请考虑以下情境——
您在处理一个数据集。您构建了一个分类模型,并立即获得了 90% 的准确率。结果看起来相当惊艳。可当您再深入一点,就会发现几乎所有数据都属于同一类。糟糕!类别失衡会让人非常挫败。
当您发现数据存在类别失衡,原以为很棒的结果其实靠不住时,难免沮丧。而更让人沮丧的是,许多不错的书籍也很少系统地讨论这个主题。
这正是由类别失衡 数据集引发的情形,以及它可能带来的令人抓狂的结果。
在本教程中,您将了解一系列可用于在失衡数据集上取得优异结果的技术。具体包括:
什么是失衡数据?
为什么失衡数据集是个严峻的问题?
准确率悖论
分类器评估的不同指标
处理失衡数据的多种方法
该主题的延伸阅读
先来看看什么是失衡数据。
来源:KDNuggets
What is Imbalanced Data?
失衡数据通常是指分类任务中,不同类别的样本数量不均衡。
例如,您有一个二分类问题,共 100 个样本,其中 80 个标记为 Class-1,剩余 20 个标记为 Class-2。
这就是一个失衡数据集的典型例子,Class-1 与 Class-2 的样本比为 4:1。
无论是 Kaggle 竞赛还是实际测试数据,类别失衡都是最常见的问题之一。
大多数真实世界的分类任务都或多或少存在类别失衡:对应某些类别标签的数据量不足。因此,必须正确选择模型的评估指标。否则,您可能会去调整/优化一个无用的参数。在以业务为先的场景中,这可能导致彻底的浪费。
有些问题类别失衡不仅常见,而且几乎必然发生。比如,涉及欺诈与非欺诈交易的数据集,欺诈交易的数量很可能远少于非欺诈交易。这就是问题的根源所在。接下来您会看到原因。
Why are Imbalanced Datasets a Serious Problem to Tackle?
尽管众多机器学习算法(包括深度与统计方法)在很多实际应用中都很成功,但从失衡数据 中学习仍未达到最先进 的水平。通常,从失衡数据学习被称为Imbalanced learning(失衡学习) 。
失衡学习的主要问题包括:
当数据集中存在代表性不足的数据时,类别分布会出现偏斜。
由于数据本身的复杂特性,要从这类数据中学习需要新的理解、方法、原则与数据变换工具。此外,这也并不保证能高效解决业务问题。最糟的情况下,可能完全无用且无任何可复用的产出。
此时您可能会问:在 GPU、TPU 如此发达的时代,为什么机器学习算法仍难以高效处理失衡数据?这是个很自然的问题,答案如下。
机器学习算法的评估方式,很大程度上决定了算法在面对失衡数据时为何表现不佳。
“当准确率指标显示您拥有出色的准确率(比如 90%)时,实际它只是在反映底层的类别分布。 ”——Machine Learning Mastery
假设您有一个二分类数据集,类别分布比为 9:1。总样本数为 1000,类别标签为 Class-1 与 Class-2。根据分布比,Class-1 有 900 个样本,Class-2 有 100 个。您使用一个标准分类器(如逻辑回归),并用分类准确率 来评估(即被正确分类的样本数占比)。现在仔细想一想。
您的逻辑回归模型其实不必复杂,就能把全部 1000 个样本都预测为 Class-1。这样得到 90% 的准确率,但这显然不足以衡量分类器的真实质量。很明显,您需要其他指标来评估系统性能。您马上就会看到。这种现象称为准确率悖论 。
Approaches for Handling Imbalanced Data:
本节先从几种非 “分类准确率”的指标开始,以便在处理失衡数据时,能够更真实地评判分类器。
首先定义四个基本概念:
真正类(TP)——正类样本被正确分类为正类
真负类(TN)——负类样本被正确分类为负类
假正类(FP)——负类样本被错误分类为正类
假负类(FN)——正类样本被错误分类为负类
下图可以说明上述术语:
来源
现在,假设您在刚才的玩具数据集上训练了另一种分类器,这次使用随机森林,得到 70% 的分类准确率。既然您已了解真正率、真负率与假正率、假负率,接下来更细致地比较此前的逻辑回归与随机森林。
假设逻辑回归的真正率、真负率与假正率、假负率如下所示:
再假设随机森林的这些指标如下:
看看两个分类器对负类的正确预测数量(真负类)。在失衡数据集上,您需要优先关注这个数值(因为数据集中 Class-1 占主导)。在此意义上,随机森林明显优于逻辑回归。
现在,您已准备好学习应对失衡数据集问题的具体方法。
(注意,上述表示方式通常称为混淆矩阵 。)
以下两项指标源自混淆矩阵,评估分类器时非常常用。
精确率(Precision) :精确率等于真正类数除以真正类与假正类之和。换言之,即正类预测数除以所有被预测为正类的总数。也称为正预测值(PPV)。
精确率可被视为分类器的“严谨度” 。精确率低通常意味着假正类多。
召回率(Recall) :召回率等于真正类数除以真正类与假负类之和。换言之,即正类预测数除以测试数据中真实正类的数量。也称为灵敏度或真正类率。
召回率可被视为分类器的“完整度” 。召回率低通常意味着假负类多。
其他可能有用的指标:
在学习处理类别失衡的方法之前,先看一个非常真实的例子:如果只选择分类准确率 作为评估指标,可能会导致糟糕的结果。(目的是确保您在训练下一个分类器时,不只看准确率。)
乳腺癌数据集 是一个标准的机器学习数据集。它包含 9 个特征,描述了 286 位曾罹患并存活的乳腺癌患者,以及其是否在 5 年内复发。让我们基于该数据集直观感受一下问题。
该数据集是一个二分类问题。在 286 位女性中,201 位未复发,剩下 85 位出现复发。
让我们用可视化的方式进一步探索该数据集。
import numpy as np
import pandas as pd
data = pd. read_csv( "breast-cancer.data" , header= None )
print ( data. head( 10 ) )
技术支持
0 1 2 3 4 5 6 7 8 \
0 no- recurrence- events 30 - 39 premeno 30 - 34 0 - 2 no 3 left left_low
1 no- recurrence- events 40 - 49 premeno 20 - 24 0 - 2 no 2 right right_up
2 no- recurrence- events 40 - 49 premeno 20 - 24 0 - 2 no 2 left left_low
3 no- recurrence- events 60 - 69 ge40 15 - 19 0 - 2 no 2 right left_up
4 no- recurrence- events 40 - 49 premeno 0 - 4 0 - 2 no 2 right right_low
5 no- recurrence- events 60 - 69 ge40 15 - 19 0 - 2 no 2 left left_low
6 no- recurrence- events 50 - 59 premeno 25 - 29 0 - 2 no 2 left left_low
7 no- recurrence- events 60 - 69 ge40 20 - 24 0 - 2 no 1 left left_low
8 no- recurrence- events 40 - 49 premeno 50 - 54 0 - 2 no 2 left left_low
9 no- recurrence- events 40 - 49 premeno 20 - 24 0 - 2 no 2 right left_up
9
0 no
1 no
2 no
3 no
4 no
5 no
6 no
7 no
8 no
9 no
技术支持
列名是数字,因为这里用的是部分预处理后的数据集。如果您感兴趣,可以参考下图:
来源
我们绘制类别分布的柱状图。
import matplotlib. pyplot as plt
classes = data[ 9 ] . values
unique, counts = np. unique( classes, return_counts= True )
plt. bar( unique, counts)
plt. title( 'Class Frequency' )
plt. xlabel( 'Class' )
plt. ylabel( 'Frequency' )
plt. show( )
技术支持
您可以清楚地看到类别失衡。yes 表示患有癌症的样本,显然,与另一类相比,这类样本的数量要少得多。
让我们定义数据集中出现的“未复发(No Recurrences)”与“复发(Recurrences)”,以便更清晰。
全为未复发 :如果一个模型只预测“未复发”,其准确率为 (201/286) × 100,即 70.28%。这称为全为未复发 。准确率看似很高,但模型很糟。如果误读了该模型,将有 85 位女性被错误告知其乳腺癌不会复发(高假负)。
全为复发 :如果一个模型只预测“复发”,其准确率为 (85/286) × 100,即 29.72%。这称为全为复发 。该模型准确率低下,会让 201 位女性误以为发生了复发,但事实并非如此(高假正)。
看到这里,您应该已经有所触动。继续往下看。
现在,您已经有充分理由认识到,仅用分类准确率来评估模型并非明智之选。
接下来学习一些方法。
Re-sampling the dataset:
处理失衡数据集的策略包括:改进分类算法,或在将数据输入算法前(本质是数据预处理步骤)对训练数据中的各类样本进行平衡。后者更为常用且适用范围更广。而且,相比改进算法,生成所需样本通常更省时。但在研究场景下,两者都值得探索。
采样的核心思想是:要么增加少数类样本,要么减少多数类样本。目的是让两类样本数量达到更合理的平衡。
主要有两类采样方法:
向少数类添加样本副本,称为过采样 (更正式地说是有放回采样);或
从多数类中删除样本,称为欠采样 。
从实现角度看,这似乎也并不复杂,是吧?稍后您会了解到一个专门用于采样的库。
Random under-sampling:
当您随机从数据集的多数类中删除样本,并将其分配给少数类(且不填补多数类因此产生的“空缺”)时,称为随机欠采样 。由于多数类中留下了“空缺”,这个过程具有随机性 。
优点 :
当训练集非常庞大时,减少训练样本数量有助于提升模型运行效率并缓解内存问题。
缺点 :
可能丢弃对数据本身有用的信息,而这些信息可能对构建基于规则的分类器(如随机森林)很重要。
随机欠采样得到的样本可能存在偏差,无法准确代表总体,从而导致分类器在未见过的数据上表现不佳。
Random over-sampling:
与随机欠采样类似,也可以进行随机过采样。但在这种情况下,不从多数类“借力”,而是通过复制少数类样本到某个倍数来增加少数类样本数量,同时不减少多数类样本数。比如,数据集有 1000 个样本,其中 980 属于多数类,20 属于少数类。现在将这 20 个少数类样本各复制 20 次进行过采样,过采样后少数类样本总数将达到 400。
优点 :
缺点 :
在考虑采用欠采样或过采样时,可参考以下因素:
当数据量很大时,考虑欠采样
当数据量不大时,考虑过采样
考虑采用随机与非随机(如分层)采样方案
尝试不同的类别比例(例如,二分类并不一定要追求 1:1,可尝试其他比例)
如果想在 Python 中实现欠采样与过采样,可以查看 scikit-learn-contrib 。
接下来学习处理失衡数据的另一种方法。
Try generating synthetic samples:
一种简单的方式是:从少数类样本中随机抽取各特征,来创建合成样本。
也有系统化的算法可用于生成合成样本。其中最常用的是 SMOTE(合成少数类过采样技术 )。它提出于 2002 年,您可以查看相应论文。下图信息图可帮助理解合成样本的直观含义:
来源
SMOTE 是一种过采样方法,它通过创建“合成”样本来替代简单的重复。对每个少数类样本,在其与任意/全部 k 个少数类近邻之间的连线上生成合成样本。根据所需的过采样量,从 k 个近邻中随机选择若干近邻。
SMOTE 的核心在于对少数类的构造。直觉很简单:您已经看到,过采样会导致过拟合,因为重复样本会让决策边界收紧。如果能生成相似 而非重复的样本,会怎样?原始 SMOTE 论文(见上文链接)表明,对于机器学习算法,这些新构造的样本并非精确副本,从而可以“软化”决策边界,帮助算法更准确地逼近假设。
不过,SMOTE 也有优劣:
优点 :
通过生成合成样本,缓解了随机过采样导致的过拟合。
不丢失信息。
实现与解释相对简单。
缺点 :
在生成合成样本时,SMOTE 未考虑近邻可能来自其他类别。这会加剧类别重叠并引入额外噪声。
对高维数据不太实用。
SMOTE 还有一些变体,如 safe-level SMOTE、border-line SMOTE、OSSLDDD-SMOTE 等。若要使用 SMOTE 及其变体,可参考前文提到的 scikit-learn-contrib 模块。若想深入了解 SMOTE,可阅读这篇 与这篇 论文。
下面进入本教程的最后一种思路。
Trying out different perspectives:
有一些专门处理失衡数据集的研究领域,发展出了各自的算法、度量与术语。
在处理失衡数据时,创造力与创新思维往往能带来新的视角。以下方法可作为起点:
代价敏感学习(Cost-Sensitive Learning) :通常,您会使用正则化 (如果想进一步了解正则化,可参阅这篇 DataCamp 文章 )来惩罚在广义线性模型(GLM) 中常出现的大系数。不同模型的应用会有所差异,这里暂以 GLM 为例。如果您能设计一种机制,让分类器在每次误分类时都受到惩罚,那么分类器就能以更细致的方式去学习假设。
以下方法值得考虑:
正确地使用 K 折交叉验证
对不同重采样的数据集进行集成
以不同的比例进行重采样
对占优类别进行聚类
Wrap up!
至此,您已经了解了什么是失衡数据,以及它在设计与开发机器学习模型时会引发的问题。您也看到了为什么必须重视失衡数据。随后,我们学习了多种有效处理失衡数据集的方法。处理失衡数据是一个活跃的研究领域,它也为您提供了开拓新研究问题的方向。
一下子涉及这么多重要概念!非常棒!
本教程就到这里。
如果您想更深入地学习失衡数据主题,以下是一些论文链接:
参考资料 :
如果您想进一步学习数据可视化,欢迎学习 DataCamp 由 Bokeh 开发者之一 Bryan Van de Ven 授课的 “Interactive Data Visualization with Bokeh” 课程。
请考虑以下情境——
您在处理一个数据集。您构建了一个分类模型,并立即获得了 90% 的准确率。结果看起来相当惊艳。可当您再深入一点,就会发现几乎所有数据都属于同一类。糟糕!类别失衡会让人非常挫败。
当您发现数据存在类别失衡,原以为很棒的结果其实靠不住时,难免沮丧。而更让人沮丧的是,许多不错的书籍也很少系统地讨论这个主题。
这正是由类别失衡数据集引发的情形,以及它可能带来的令人抓狂的结果。
在本教程中,您将了解一系列可用于在失衡数据集上取得优异结果的技术。具体包括:
先来看看什么是失衡数据。
What is Imbalanced Data?
失衡数据通常是指分类任务中,不同类别的样本数量不均衡。
例如,您有一个二分类问题,共 100 个样本,其中 80 个标记为 Class-1,剩余 20 个标记为 Class-2。
这就是一个失衡数据集的典型例子,Class-1 与 Class-2 的样本比为 4:1。
无论是 Kaggle 竞赛还是实际测试数据,类别失衡都是最常见的问题之一。
大多数真实世界的分类任务都或多或少存在类别失衡:对应某些类别标签的数据量不足。因此,必须正确选择模型的评估指标。否则,您可能会去调整/优化一个无用的参数。在以业务为先的场景中,这可能导致彻底的浪费。
有些问题类别失衡不仅常见,而且几乎必然发生。比如,涉及欺诈与非欺诈交易的数据集,欺诈交易的数量很可能远少于非欺诈交易。这就是问题的根源所在。接下来您会看到原因。
Why are Imbalanced Datasets a Serious Problem to Tackle?
尽管众多机器学习算法(包括深度与统计方法)在很多实际应用中都很成功,但从失衡数据中学习仍未达到最先进的水平。通常,从失衡数据学习被称为Imbalanced learning(失衡学习)。
失衡学习的主要问题包括:
此时您可能会问:在 GPU、TPU 如此发达的时代,为什么机器学习算法仍难以高效处理失衡数据?这是个很自然的问题,答案如下。
机器学习算法的评估方式,很大程度上决定了算法在面对失衡数据时为何表现不佳。
“当准确率指标显示您拥有出色的准确率(比如 90%)时,实际它只是在反映底层的类别分布。”——Machine Learning Mastery
假设您有一个二分类数据集,类别分布比为 9:1。总样本数为 1000,类别标签为 Class-1 与 Class-2。根据分布比,Class-1 有 900 个样本,Class-2 有 100 个。您使用一个标准分类器(如逻辑回归),并用分类准确率来评估(即被正确分类的样本数占比)。现在仔细想一想。
您的逻辑回归模型其实不必复杂,就能把全部 1000 个样本都预测为 Class-1。这样得到 90% 的准确率,但这显然不足以衡量分类器的真实质量。很明显,您需要其他指标来评估系统性能。您马上就会看到。这种现象称为准确率悖论。
Approaches for Handling Imbalanced Data:
本节先从几种非“分类准确率”的指标开始,以便在处理失衡数据时,能够更真实地评判分类器。
首先定义四个基本概念:
下图可以说明上述术语:
现在,假设您在刚才的玩具数据集上训练了另一种分类器,这次使用随机森林,得到 70% 的分类准确率。既然您已了解真正率、真负率与假正率、假负率,接下来更细致地比较此前的逻辑回归与随机森林。
假设逻辑回归的真正率、真负率与假正率、假负率如下所示:
再假设随机森林的这些指标如下:
看看两个分类器对负类的正确预测数量(真负类)。在失衡数据集上,您需要优先关注这个数值(因为数据集中 Class-1 占主导)。在此意义上,随机森林明显优于逻辑回归。
现在,您已准备好学习应对失衡数据集问题的具体方法。
(注意,上述表示方式通常称为混淆矩阵。)
以下两项指标源自混淆矩阵,评估分类器时非常常用。
精确率(Precision):精确率等于真正类数除以真正类与假正类之和。换言之,即正类预测数除以所有被预测为正类的总数。也称为正预测值(PPV)。
精确率可被视为分类器的“严谨度”。精确率低通常意味着假正类多。
召回率(Recall):召回率等于真正类数除以真正类与假负类之和。换言之,即正类预测数除以测试数据中真实正类的数量。也称为灵敏度或真正类率。
召回率可被视为分类器的“完整度”。召回率低通常意味着假负类多。
其他可能有用的指标:
在学习处理类别失衡的方法之前,先看一个非常真实的例子:如果只选择分类准确率作为评估指标,可能会导致糟糕的结果。(目的是确保您在训练下一个分类器时,不只看准确率。)
乳腺癌数据集是一个标准的机器学习数据集。它包含 9 个特征,描述了 286 位曾罹患并存活的乳腺癌患者,以及其是否在 5 年内复发。让我们基于该数据集直观感受一下问题。
该数据集是一个二分类问题。在 286 位女性中,201 位未复发,剩下 85 位出现复发。
让我们用可视化的方式进一步探索该数据集。
列名是数字,因为这里用的是部分预处理后的数据集。如果您感兴趣,可以参考下图:
来源
我们绘制类别分布的柱状图。
您可以清楚地看到类别失衡。
yes表示患有癌症的样本,显然,与另一类相比,这类样本的数量要少得多。让我们定义数据集中出现的“未复发(No Recurrences)”与“复发(Recurrences)”,以便更清晰。
全为未复发:如果一个模型只预测“未复发”,其准确率为 (201/286) × 100,即 70.28%。这称为全为未复发。准确率看似很高,但模型很糟。如果误读了该模型,将有 85 位女性被错误告知其乳腺癌不会复发(高假负)。
全为复发:如果一个模型只预测“复发”,其准确率为 (85/286) × 100,即 29.72%。这称为全为复发。该模型准确率低下,会让 201 位女性误以为发生了复发,但事实并非如此(高假正)。
看到这里,您应该已经有所触动。继续往下看。
现在,您已经有充分理由认识到,仅用分类准确率来评估模型并非明智之选。
接下来学习一些方法。
Re-sampling the dataset:
处理失衡数据集的策略包括:改进分类算法,或在将数据输入算法前(本质是数据预处理步骤)对训练数据中的各类样本进行平衡。后者更为常用且适用范围更广。而且,相比改进算法,生成所需样本通常更省时。但在研究场景下,两者都值得探索。
采样的核心思想是:要么增加少数类样本,要么减少多数类样本。目的是让两类样本数量达到更合理的平衡。
主要有两类采样方法:
从实现角度看,这似乎也并不复杂,是吧?稍后您会了解到一个专门用于采样的库。
Random under-sampling:
当您随机从数据集的多数类中删除样本,并将其分配给少数类(且不填补多数类因此产生的“空缺”)时,称为随机欠采样。由于多数类中留下了“空缺”,这个过程具有随机性。
优点:
缺点:
Random over-sampling:
与随机欠采样类似,也可以进行随机过采样。但在这种情况下,不从多数类“借力”,而是通过复制少数类样本到某个倍数来增加少数类样本数量,同时不减少多数类样本数。比如,数据集有 1000 个样本,其中 980 属于多数类,20 属于少数类。现在将这 20 个少数类样本各复制 20 次进行过采样,过采样后少数类样本总数将达到 400。
优点:
缺点:
在考虑采用欠采样或过采样时,可参考以下因素:
如果想在 Python 中实现欠采样与过采样,可以查看
scikit-learn-contrib。接下来学习处理失衡数据的另一种方法。
Try generating synthetic samples:
一种简单的方式是:从少数类样本中随机抽取各特征,来创建合成样本。
也有系统化的算法可用于生成合成样本。其中最常用的是 SMOTE(合成少数类过采样技术)。它提出于 2002 年,您可以查看相应论文。下图信息图可帮助理解合成样本的直观含义:
来源
SMOTE 是一种过采样方法,它通过创建“合成”样本来替代简单的重复。对每个少数类样本,在其与任意/全部 k 个少数类近邻之间的连线上生成合成样本。根据所需的过采样量,从 k 个近邻中随机选择若干近邻。
SMOTE 的核心在于对少数类的构造。直觉很简单:您已经看到,过采样会导致过拟合,因为重复样本会让决策边界收紧。如果能生成相似而非重复的样本,会怎样?原始 SMOTE 论文(见上文链接)表明,对于机器学习算法,这些新构造的样本并非精确副本,从而可以“软化”决策边界,帮助算法更准确地逼近假设。
不过,SMOTE 也有优劣:
优点:
缺点:
SMOTE 还有一些变体,如 safe-level SMOTE、border-line SMOTE、OSSLDDD-SMOTE 等。若要使用 SMOTE 及其变体,可参考前文提到的
scikit-learn-contrib模块。若想深入了解 SMOTE,可阅读这篇与这篇论文。下面进入本教程的最后一种思路。
Trying out different perspectives:
有一些专门处理失衡数据集的研究领域,发展出了各自的算法、度量与术语。
在处理失衡数据时,创造力与创新思维往往能带来新的视角。以下方法可作为起点:
代价敏感学习(Cost-Sensitive Learning):通常,您会使用正则化(如果想进一步了解正则化,可参阅这篇 DataCamp 文章)来惩罚在广义线性模型(GLM)中常出现的大系数。不同模型的应用会有所差异,这里暂以 GLM 为例。如果您能设计一种机制,让分类器在每次误分类时都受到惩罚,那么分类器就能以更细致的方式去学习假设。
以下方法值得考虑:
Wrap up!
至此,您已经了解了什么是失衡数据,以及它在设计与开发机器学习模型时会引发的问题。您也看到了为什么必须重视失衡数据。随后,我们学习了多种有效处理失衡数据集的方法。处理失衡数据是一个活跃的研究领域,它也为您提供了开拓新研究问题的方向。
一下子涉及这么多重要概念!非常棒!
本教程就到这里。
如果您想更深入地学习失衡数据主题,以下是一些论文链接:
参考资料:
如果您想进一步学习数据可视化,欢迎学习 DataCamp 由 Bokeh 开发者之一 Bryan Van de Ven 授课的 “Interactive Data Visualization with Bokeh” 课程。