不平衡数据集分类实战:成人收入数据集分类模型训练和评估(一)

简介: 不平衡数据集分类实战:成人收入数据集分类模型训练和评估(一)

许多二分类任务并不是每个类别都有相同数量的数据,存在着数据分布不平衡的情况。

一个常用的例子是成人收入数据集,它涉及到社交关系、教育水平等个人数据,以此来预测成人的收入水平,判断其是否拥有5万美元/年的个人收入。数据集中个人收入低于5万美元的数据比高于5万美元的数据要明显多一些,存在着一定程度的分布不平衡。

针对这一数据集,可以使用很多不平衡分类的相关算法完成分类任务。

在本教程中,您将了解如何为数据分布不平衡的成人收入数据集开发分类模型并对其进行评估。

学习本教程后,您将知道:

  • 如何加载和分析数据集,并对如何进行数据预处理和模型选择有一定启发。
  • 如何使用一个稳健的测试工具系统地评估机器学习模型的效能。
  • 如何拟合最终模型并使用它预测特定情况所对应的类标签。

针对成人收入不平衡分类的具体内容如下:

教程大纲

本教程主要分为了以下五个部分:

  1. 成人收入数据集介绍
  2. 数据集分析
  3. 基础模型和性能评价
  4. 模型评价
  5. 对新输入数据进行预测

成人收入数据集介绍

在这个教程中,我们将使用一个数据分布不平衡的机器学习常用数据集,称为“成人收入”或简称“成人”数据集。

该数据集归Ronny Kohavi和Barry Becker所有,取自1994年美国人口普查局的数据,包含有教育水平等个人详细数据,用于预测个人年收入是否超过或低于50000美元。

数据集提供14个输入变量,这些变量数据的类型有标签数据、序列数据、连续数据。变量的完整列表如下:

  • 年龄。
  • 阶级。
  • 最终重量。
  • 教育程度。
  • 教育年限。
  • 婚姻状况。
  • 职业。
  • 社交。
  • 种族。
  • 性别。
  • 资本收益。
  • 资本损失。
  • 每周工作小时数。
  • 国籍。

总共有48842行数据,3620行含有缺失数据,45222行具有完整的数据,其中缺失值用?标记。

有'>50K'和'<=50K'两类标签数据,也就是说它是一个二分类任务。同时这些标签数据分布不平衡,'<=50K'类标签比重更大。

考虑到标签数据分布不平衡的情况并不严重,并且两个标签同等重要,本教程采用常见的分类准确度或分类误差来反映此数据集上的相关模型性能。

分析数据集

成人数据集是一个广泛使用的标准机器学习数据集,用于探索和演示许多一般性的或专门为不平衡分类设计的机器学习算法。

首先,下载数据集并将其保存在当前工作目录中,命名为“adult-all.csv”.

接下来让我们考察一下该数据集。文件的前几行如下:

39,State-gov,77516,Bachelors,13,Never-married,Adm-clerical,Not-in-family,White,Male,2174,0,40,United-States,<=50K
50,Self-emp-not-inc,83311,Bachelors,13,Married-civ-spouse,Exec-managerial,Husband,White,Male,0,0,13,United-States,<=50K
38,Private,215646,HS-grad,9,Divorced,Handlers-cleaners,Not-in-family,White,Male,0,0,40,United-States,<=50K
53,Private,234721,11th,7,Married-civ-spouse,Handlers-cleaners,Husband,Black,Male,0,0,40,United-States,<=50K
28,Private,338409,Bachelors,13,Married-civ-spouse,Prof-specialty,Wife,Black,Female,0,0,40,Cuba,<=50K
...

我们可以看到,输入变量包含有连续数据、标签数据以及序号数据,对于标签数据需要进行二进制或者独热编码。同时也需要注意到,目标变量是用字符串表示的,而对于二分类问题,需要用0/1进行标签编码,因此对于占比多的多数标签编码为0,而占比较少的少数标签则编码为1。缺失的数据用?表示,通常可以估算这些值,也可以直接从数据集中删除这些行。

具体的载入数据集方法可使用read_csv()这一Pandas包的内置函数,只需要指定文件名、是否读入标题行以及缺失值的对应符号(本数据为?,缺失值会被处理为NaN数据):

# define the dataset location
filename = 'adult-all.csv'
# load the csv file as a data frame
dataframe = read_csv(filename, header=None, na_values='?')

成功加载数据集后,我们需要移除缺失数据所在的行,并统计数据大小:

# drop rows with missing
dataframe = dataframe.dropna()
# summarize the shape of the dataset
print(dataframe.shape)

通过Counter函数我们可以统计数据集分布情况:

# summarize the class distribution
target = dataframe.values[:,-1]
counter = Counter(target)
for k,v in counter.items():
    per = v / len(target) * 100
    print('Class=%s, Count=%d, Percentage=%.3f%%' % (k, v, per))

上述函数集合到一起,就实现了数据加载和相关统计工作。完整代码如下:

# load and summarize the dataset
from pandas import read_csv
from collections import Counter
# define the dataset location
filename = 'adult-all.csv'
# load the csv file as a data frame
dataframe = read_csv(filename, header=None, na_values='?')
# drop rows with missing
dataframe = dataframe.dropna()
# summarize the shape of the dataset
print(dataframe.shape)
# summarize the class distribution
target = dataframe.values[:,-1]
counter = Counter(target)
for k,v in counter.items():
    per = v / len(target) * 100
    print('Class=%s, Count=%d, Percentage=%.3f%%' % (k, v, per))

运行结果如下:

(45222, 15)
Class= <=50K, Count=34014, Percentage=75.216%
Class= >50K, Count=11208, Percentage=24.784%

在上述代码中,首先我们加载了数据集,并确认了行和列的数量,即45222行,15列(14个输入变量和一个目标变量)。然后分析了数据分布情况,发现数据分布是不平衡的,大约75%的数据都是(<=50K),而只有大约25%的数据是(>50K)。

通过创建直方图,我们可以更直观地看到数据分布情况。具体做法如下:

首先,调用select_dtypes函数选取数值型数据。

...
# select columns with numerical data types
num_ix = df.select_dtypes(include=['int64', 'float64']).columns
# select a subset of the dataframe with the chosen columns
subset = df[num_ix]

然后通过matplotlib绘图包进行显示。

# create histograms of numeric input variables
from pandas import read_csv
from matplotlib import pyplot
# define the dataset location
filename = 'adult-all.csv'
# load the csv file as a data frame
df = read_csv(filename, header=None, na_values='?')
# drop rows with missing
df = df.dropna()
# select columns with numerical data types
num_ix = df.select_dtypes(include=['int64', 'float64']).columns
# select a subset of the dataframe with the chosen columns
subset = df[num_ix]
# create a histogram plot of each numeric variable
subset.hist()
pyplot.show()

运行上述代码,将为数据集中的六个输入变量分别创建一个直方图。

image.png

我们可以看到它们有着不同的分布情况,有些是高斯分布,有些是指数分布或离散分布。同样可以看出,他们的变化范围差异较大。而为了得到较好的算法效果,我们通常需要将数据分布缩放到相同的范围,因此需要进行相应的幂变换。

基础模型和性能评价

k-fold交叉验证方法能够较好估计模型的性能。在这里我们将使用k=10的重复分层k-fold交叉验证方法来评估相关模型,这意味着每个折叠将包含约45222/10=4522个数据。而分层表示每一个折叠将包含相同的混合比例(即每个折叠中指标数据都具有75%-25%的分布特征)。重复表示评估过程将被多次执行,以避免偶然结果和更好地捕获所选模型的方差,本教程中,我们将重复三次。这意味着将对单个模型进行10×3=30次拟合和评估,并记录每次运行结果的平均值和标准差。

上述方法可以通过scikit-learn包里面的RepeatedStratifiedKFold函数实现。

具体代码如下:

# evaluate a model
def evaluate_model(X, y, model):
    # define evaluation procedure
    cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
    # evaluate model
    scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
    return scores

通过evaluate_model()函数我们实现了获取加载的数据集和定义的模型,使用重复分层k-fold交叉验证对其进行评估,然后返回一个准确度列表。

而如何生成X、Y数据呢?我们可以定义一个函数来加载数据集并对目标列进行编码,然后返回所需数据。具体代码如下:

# load the dataset
def load_dataset(full_path):
    # load the dataset as a numpy array
    dataframe = read_csv(full_path, header=None, na_values='?')
    # drop rows with missing
    dataframe = dataframe.dropna()
    # split into inputs and outputs
    last_ix = len(dataframe.columns) - 1
    X, y = dataframe.drop(last_ix, axis=1), dataframe[last_ix]
    # select categorical and numerical features
    cat_ix = X.select_dtypes(include=['object', 'bool']).columns
    num_ix = X.select_dtypes(include=['int64', 'float64']).columns
    # label encode the target variable to have the classes 0 and 1
    y = LabelEncoder().fit_transform(y)
    return X.values, y, cat_ix, num_ix

通过以上步骤,我们就可以使用这个测试工具评估数据集的相关模型了。

为了更好地评估若干模型之间的差距,我们可以通过scikit库里面的DummyClassifier类建立一个基准模型。相关代码如下:

# define the reference model
model = DummyClassifier(strategy='most_frequent')
# evaluate the model
scores = evaluate_model(X, y, model)
# summarize performance
print('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

上述函数集合到一起,就实现了一个基准算法对于数据集的预测分类和评价。完整代码如下:

# test harness and baseline model evaluation for the adult dataset
from collections import Counter
from numpy import mean
from numpy import std
from numpy import hstack
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.dummy import DummyClassifier
# load the dataset
def load_dataset(full_path):
    # load the dataset as a numpy array
    dataframe = read_csv(full_path, header=None, na_values='?')
    # drop rows with missing
    dataframe = dataframe.dropna()
    # split into inputs and outputs
    last_ix = len(dataframe.columns) - 1
    X, y = dataframe.drop(last_ix, axis=1), dataframe[last_ix]
    # select categorical and numerical features
    cat_ix = X.select_dtypes(include=['object', 'bool']).columns
    num_ix = X.select_dtypes(include=['int64', 'float64']).columns
    # label encode the target variable to have the classes 0 and 1
    y = LabelEncoder().fit_transform(y)
    return X.values, y, cat_ix, num_ix
# evaluate a model
def evaluate_model(X, y, model):
    # define evaluation procedure
    cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
    # evaluate model
    scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
    return scores
# define the location of the dataset
full_path = 'adult-all.csv'
# load the dataset
X, y, cat_ix, num_ix = load_dataset(full_path)
# summarize the loaded dataset
print(X.shape, y.shape, Counter(y))
# define the reference model
model = DummyClassifier(strategy='most_frequent')
# evaluate the model
scores = evaluate_model(X, y, model)
# summarize performance
print('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

运行结果如下:

(45222, 14) (45222,) Counter({0: 34014, 1: 11208})
Mean Accuracy: 0.752 (0.000)

通过上述代码,我们首先加载数据并进行预处理。然后通过DummyClassifier()进行分类,并通过RepeatedStratifiedKFold()进行评价。可以看到,基准算法达到了约75.2%的准确度。这一结果指出了相关模型的准确度下限;任何平均准确度高于75.2%的模型都可被视为有效模型,而低于75.2%则通常被认为是无效的。

目录
打赏
0
0
0
0
529
分享
相关文章
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
197 6
基于阿里云 Milvus + DeepSeek + PAI LangStudio 的低成本高精度 RAG 实战
阿里云向量检索服务Milvus版是一款全托管向量检索引擎,并确保与开源Milvus的完全兼容性,支持无缝迁移。它在开源版本的基础上增强了可扩展性,能提供大规模AI向量数据的相似性检索服务。凭借其开箱即用的特性、灵活的扩展能力和全链路监控告警,Milvus云服务成为多样化AI应用场景的理想选择,包括多模态搜索、检索增强生成(RAG)、搜索推荐、内容风险识别等。您还可以利用开源的Attu工具进行可视化操作,进一步促进应用的快速开发和部署。
R1类模型推理能力评测手把手实战
随着DeepSeek-R1模型的广泛应用,越来越多的开发者开始尝试复现类似的模型,以提升其推理能力。
R1类模型推理能力评测手把手实战
随着DeepSeek-R1模型的广泛应用,越来越多的开发者开始尝试复现类似的模型,以提升其推理能力。
机器学习中评估模型性能的重要工具——混淆矩阵和ROC曲线。混淆矩阵通过真正例、假正例等指标展示模型预测情况
本文介绍了机器学习中评估模型性能的重要工具——混淆矩阵和ROC曲线。混淆矩阵通过真正例、假正例等指标展示模型预测情况,而ROC曲线则通过假正率和真正率评估二分类模型性能。文章还提供了Python中的具体实现示例,展示了如何计算和使用这两种工具来评估模型。
130 8
在数据驱动时代,A/B 测试成为评估机器学习项目不同方案效果的重要方法
在数据驱动时代,A/B 测试成为评估机器学习项目不同方案效果的重要方法。本文介绍 A/B 测试的基本概念、步骤及其在模型评估、算法改进、特征选择和用户体验优化中的应用,同时提供 Python 实现示例,强调其在确保项目性能和用户体验方面的关键作用。
72 6
在数据驱动时代,A/B 测试成为评估机器学习项目效果的重要手段
在数据驱动时代,A/B 测试成为评估机器学习项目效果的重要手段。本文介绍了 A/B 测试的基本概念、步骤及其在模型评估、算法改进、特征选择和用户体验优化中的应用,强调了样本量、随机性和时间因素的重要性,并展示了 Python 在 A/B 测试中的具体应用实例。
48 1
用Python实现简单机器学习模型:以鸢尾花数据集为例
用Python实现简单机器学习模型:以鸢尾花数据集为例
229 1
机器学习实战:TensorFlow在图像识别中的应用探索
【10月更文挑战第28天】随着深度学习技术的发展,图像识别取得了显著进步。TensorFlow作为Google开源的机器学习框架,凭借其强大的功能和灵活的API,在图像识别任务中广泛应用。本文通过实战案例,探讨TensorFlow在图像识别中的优势与挑战,展示如何使用TensorFlow构建和训练卷积神经网络(CNN),并评估模型的性能。尽管面临学习曲线和资源消耗等挑战,TensorFlow仍展现出广阔的应用前景。
111 5

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等