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

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

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

一个常用的例子是成人收入数据集,它涉及到社交关系、教育水平等个人数据,以此来预测成人的收入水平,判断其是否拥有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%则通常被认为是无效的。

目录
相关文章
|
21天前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习】K-Means对文本聚类和半环形数据聚类实战(附源码和数据集)
【Python机器学习】K-Means对文本聚类和半环形数据聚类实战(附源码和数据集)
84 0
|
4天前
|
机器学习/深度学习 数据采集 Python
机器学习模型的评估与选择标准
【6月更文挑战第1天】机器学习模型的评估至关重要,包括准确率、召回率、F1值和均方误差等指标。准确率衡量预测正确比例,召回率关注找出所有相关样本的能力,F1值是两者的综合。泛化能力同样重要,防止过拟合和欠拟合。不同场景可能侧重不同指标,如医疗诊断更关注召回率。选择模型需综合考虑多个因素,以实现最佳性能。通过实践和探索,我们可以更好地理解和优化模型评估,推动机器学习进步。
27 2
|
13天前
|
机器学习/深度学习 小程序 计算机视觉
机器学习寻找数据集—动态网站获取
机器学习寻找数据集—动态网站获取
|
18天前
|
机器学习/深度学习 数据采集 人工智能
论文介绍:机器学习中数据集规模增长的极限分析
【5月更文挑战第17天】论文《机器学习中数据集规模增长的极限分析》探讨了数据集大小对AI模型性能的影响,预测语言数据可能在2026年前耗尽,图像数据在2030-2060年可能面临相同问题。研究显示数据积累速度无法跟上数据集增长,可能在2030-2040年间导致训练瓶颈。然而,算法创新和新数据源的发展可能缓解这一问题。[链接](https://arxiv.org/pdf/2211.04325.pdf)
39 2
|
21天前
|
机器学习/深度学习 分布式计算 并行计算
【机器学习】怎样在非常大的数据集上执行K-means算法?
【5月更文挑战第13天】【机器学习】怎样在非常大的数据集上执行K-means算法?
|
21天前
|
机器学习/深度学习 BI
机器学习模型评估指标总结
机器学习模型评估指标总结
17 2
|
21天前
|
机器学习/深度学习 数据可视化 前端开发
【Python机器学习专栏】机器学习模型评估的实用方法
【4月更文挑战第30天】本文介绍了机器学习模型评估的关键方法,包括评估指标(如准确率、精确率、召回率、F1分数、MSE、RMSE、MAE及ROC曲线)和交叉验证技术(如K折交叉验证、留一交叉验证、自助法)。混淆矩阵提供了一种可视化分类模型性能的方式,而Python的scikit-learn库则方便实现这些评估。选择适合的指标和验证方法能有效优化模型性能。
|
21天前
|
机器学习/深度学习 数据采集 SQL
【Python机器学习专栏】使用Pandas处理机器学习数据集
【4月更文挑战第30天】本文介绍了如何使用Python的Pandas库处理机器学习数据集,涵盖数据读取、概览、清洗、转换、切分和保存等步骤。通过Pandas,可以从CSV等格式加载数据,进行缺失值、异常值处理,数据类型转换,如归一化、类别编码,并实现训练集与测试集的划分。此外,还展示了如何保存处理后的数据,强调了Pandas在数据预处理中的重要性。
|
21天前
|
机器学习/深度学习 算法 Python
【Python机器学习专栏】Python中的机器学习评估与度量指标
【4月更文挑战第30天】本文介绍了Python中机器学习模型的评估方法和度量指标。主要包括留出法、交叉验证和自助法等评估方法,以及准确率、精确率、召回率、F1分数、AUC-ROC曲线、MSE、RMSE和R方值等度量指标。选择合适的评估标准对于理解模型性能和适应不同任务至关重要。
|
21天前
|
机器学习/深度学习 大数据
如何通过评估方法评估机器学习模型的性能
如何通过评估方法评估机器学习模型的性能
19 0

热门文章

最新文章