Machine Learning Mastery 不平衡数据教程(七)
用于不平衡分类的随机过采样和欠采样
最后更新于 2021 年 1 月 5 日
不平衡数据集是指在类分布中存在严重偏差的数据集,例如少数类与多数类的比例为 1:100 或 1:1000。
训练数据集中的这种偏差会影响许多机器学习算法,导致一些算法完全忽略少数类。这是一个问题,因为预测最重要的通常是少数群体。
解决类不平衡问题的一种方法是对训练数据集进行随机重采样。随机对不平衡数据集进行重采样的两种主要方法是从多数类中删除示例,称为欠采样,以及从少数类中复制示例,称为过采样。
在本教程中,您将发现用于不平衡分类的随机过采样和欠采样
完成本教程后,您将知道:
- 随机重采样为不平衡数据集的类分布重新平衡提供了一种简单的技术。
- 随机过采样会复制训练数据集中少数类的示例,并可能导致某些模型的过拟合。
- 随机欠采样会从多数类中删除示例,并可能导致丢失对模型来说非常宝贵的信息。
用我的新书Python 不平衡分类启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
- 2021 年 1 月更新:更新了 API 文档的链接。
不平衡分类的随机过采样和欠采样 图片由 RichardBH 提供,保留部分权利。
教程概述
本教程分为五个部分;它们是:
- 随机重采样不平衡数据集
- 不平衡学习库
- 随机过采样不平衡数据集
- 随机欠采样不平衡数据集
- 结合随机过采样和欠采样
随机重采样不平衡数据集
重采样包括创建训练数据集的新变换版本,其中所选示例具有不同的类分布。
这是一种简单有效的解决不平衡分类问题的策略。
应用重采样策略来获得更平衡的数据分布是解决不平衡问题的有效方法
——不平衡分布下的预测建模综述,2015 年。
最简单的策略是为转换后的数据集随机选择示例,称为随机重采样。
不平衡分类的随机重采样主要有两种方法;它们是过采样和欠采样。
- 随机过采样:随机复制小众类的例子。
- 随机欠采样:随机删除多数类中的例子。
随机过采样包括从少数类中随机选择示例,进行替换,并将它们添加到训练数据集中。随机欠采样包括从多数类中随机选择示例,并将其从训练数据集中删除。
在随机欠采样中,大多数类实例被随机丢弃,直到达到更平衡的分布。
—第 45 页,不平衡学习:基础、算法和应用,2013
这两种方法都可以重复,直到在训练数据集中达到期望的类分布,例如类之间的相等分割。
它们被称为“原始重采样”方法,因为它们对数据不做任何假设,也不使用试探法。这使得它们实现简单,执行快速,这对于非常大和复杂的数据集来说是理想的。
这两种技术都可以用于两类(二元)分类问题和具有一个或多个多数或少数类的多类分类问题。
重要的是,对类分布的更改仅应用于训练数据集。目的是影响模型的拟合。重采样不会应用于用于评估模型表现的测试或保持数据集。
一般来说,这些简单的方法可能是有效的,尽管这取决于所涉及的数据集和模型的细节。
让我们仔细看看每种方法以及如何在实践中使用它们。
不平衡学习库
在这些例子中,我们将使用不平衡学习 Python 库提供的实现,可以通过 pip 安装如下:
sudo pip install imbalanced-learn
您可以通过打印已安装库的版本来确认安装成功:
# check version number
import imblearn
print(imblearn.__version__)
运行该示例将打印已安装库的版本号;例如:
0.5.0
随机过采样不平衡数据集
随机过采样包括随机复制少数民族的例子,并将其添加到训练数据集中。
训练数据集中的示例是随机选择的,并进行替换。这意味着可以多次选择来自少数民族类的例子,并将其添加到新的更加平衡的训练数据集;它们是从原始训练数据集中选择的,添加到新的训练数据集中,然后返回或替换原始数据集中的*,允许再次选择它们。*
*这种技术对于那些受偏斜分布影响的机器学习算法是有效的,其中给定类的多个重复示例会影响模型的拟合。这可能包括迭代学习系数的算法,比如使用随机梯度下降的人工神经网络。它还会影响寻求数据良好分割的模型,如支持向量机和决策树。
调整目标类分布可能会很有用。在某些情况下,为严重不平衡的数据集寻求平衡分布可能会导致受影响的算法对少数类进行过度填充,从而导致泛化错误增加。这种效果在训练数据集上表现较好,但在保持数据集或测试数据集上表现较差。
……随机过采样可能会增加过拟合的可能性,因为它会精确复制少数类示例。例如,通过这种方式,符号分类器可以构建表面上准确但实际上覆盖了一个复制示例的规则。
—第 83 页,从不平衡数据集中学习,2018。
因此,为了深入了解该方法的影响,最好在过采样后监控训练数据集和测试数据集的表现,并将结果与原始数据集上的相同算法进行比较。
当拟合模型时,尤其是考虑到模型在训练数据集中一次又一次地看到相同的例子,少数类的例子数量的增加,尤其是如果类偏斜严重,也会导致计算成本的显著增加。
……在随机过采样中,少数类示例的随机副本被添加到数据中。这可能会增加过拟合的可能性,特别是对于较高的过采样率。此外,它可能会降低分类器的表现并增加计算量。
——不平衡分布下的预测建模综述,2015 年。
可以使用随机过采样类实现随机过采样。
可以定义该类,并采用 sampling_strategy 参数,该参数可以设置为“少数民族,以自动平衡少数民族类和多数民族类。
例如:
...
# define oversampling strategy
oversample = RandomOverSampler(sampling_strategy='minority')
这意味着,如果多数类有 1,000 个例子,少数类有 100 个,这个策略将对少数类进行过采样,使其有 1,000 个例子。
可以指定一个浮点值来指示转换数据集中少数类多数示例的比率。例如:
...
# define oversampling strategy
oversample = RandomOverSampler(sampling_strategy=0.5)
对于二进制分类问题,这将确保少数类被过采样为多数类的一半数量的例子。这意味着,如果多数类有 1,000 个示例,少数类有 100 个示例,则转换后的数据集将有 500 个少数类示例。
该类类似于 Sklearn 转换对象,因为它适合数据集,然后用于生成新的或转换的数据集。与 Sklearn 转换不同,它将改变数据集中的示例数量,而不仅仅是值(如缩放器)或特征数量(如投影)。
例如,可以通过调用 fit_sample() 函数一步拟合应用:
...
# fit and apply the transform
X_over, y_over = oversample.fit_resample(X, y)
我们可以在一个简单的综合二分类问题上演示这一点,该问题具有 1:100 的类别不平衡。
...
# define dataset
X, y = make_classification(n_samples=10000, weights=[0.99], flip_y=0)
下面列出了定义数据集和执行随机过采样以平衡类分布的完整示例。
# example of random oversampling to balance the class distribution
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import RandomOverSampler
# define dataset
X, y = make_classification(n_samples=10000, weights=[0.99], flip_y=0)
# summarize class distribution
print(Counter(y))
# define oversampling strategy
oversample = RandomOverSampler(sampling_strategy='minority')
# fit and apply the transform
X_over, y_over = oversample.fit_resample(X, y)
# summarize class distribution
print(Counter(y_over))
运行该示例首先创建数据集,然后总结类分布。我们可以看到,多数派有近 100 个 10K 的例子,少数派有 100 个。
然后定义随机过采样变换来平衡少数类,然后拟合并应用于数据集。报告了转换数据集的类分布,显示现在少数类的示例数与多数类相同。
Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9900})
该变换可用作管道的一部分,以确保它仅作为 k 倍交叉验证中每个分割的一部分应用于训练数据集。
不能使用传统的 Sklearn 管道;相反,可以使用来自不平衡学习库的管道。例如:
...
# pipeline
steps = [('over', RandomOverSampler()), ('model', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
下面的示例提供了一个完整的示例,用于在 1:100 类分布的不平衡数据集上评估决策树。
使用三次重复的重复 10 倍交叉验证对模型进行评估,并在每次重复中对训练数据集分别执行过采样,确保不会出现交叉验证前执行过采样时可能出现的数据泄漏。
# example of evaluating a decision tree with random oversampling
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.tree import DecisionTreeClassifier
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import RandomOverSampler
# define dataset
X, y = make_classification(n_samples=10000, weights=[0.99], flip_y=0)
# define pipeline
steps = [('over', RandomOverSampler()), ('model', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(pipeline, X, y, scoring='f1_micro', cv=cv, n_jobs=-1)
score = mean(scores)
print('F1 Score: %.3f' % score)
运行该示例使用过采样在不平衡数据集上评估决策树模型。
所选模型和重采样配置是任意的,旨在提供一个模板,您可以使用该模板来测试数据集和学习算法的欠采样,而不是最佳地求解合成数据集。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
使用默认的过采样策略,平衡少数类和多数类。报告每次折叠和每次重复的 F1 平均得分。
F1 Score: 0.990
现在我们已经熟悉了过采样,让我们来看看欠采样。
随机欠采样不平衡数据集
随机欠采样包括从多数类中随机选择要从训练数据集中删除的示例。
这具有减少训练数据集的转换版本中多数类中的示例数量的效果。这个过程可以重复进行,直到达到期望的类别分布,例如每个类别的示例数量相等。
这种方法可能更适合那些存在类不平衡的数据集,尽管少数类中有足够数量的例子,这样一个有用的模型可以被拟合。
欠采样的一个限制是,多数类中可能有用、重要或对拟合稳健决策边界至关重要的示例被删除。假设示例是随机删除的,那么就没有办法从多数类中检测或保留“好的”或更多信息丰富的示例。
……在随机欠采样(可能)中,大量数据被丢弃。[……]这可能很成问题,因为这种数据的丢失会使少数和多数实例之间的决策边界更难学习,从而导致分类表现的损失。
—第 45 页,不平衡学习:基础、算法和应用,2013
随机欠采样技术可以使用随机欠采样不平衡学习类来实现。
该类可以像上一节中的randomoversacompler类一样使用,除了策略影响多数类而不是少数类。例如,将 sampling_strategy 参数设置为“多数”将对由具有最大数量示例的类确定的多数类进行欠采样。
...
# define undersample strategy
undersample = RandomUnderSampler(sampling_strategy='majority')
例如,多数类中有 1,000 个示例,少数类中有 100 个示例的数据集将被欠采样,这样两个类在转换后的训练数据集中都会有 100 个示例。
我们还可以将 sampling_strategy 参数设置为一个浮点值,该值是相对于少数类的百分比,具体来说就是少数类中的示例数除以多数类中的示例数。例如,如果我们将不平衡数据集中的采样策略设置为 0.5,多数类中有 1000 个示例,少数类中有 100 个示例,那么转换后的数据集中多数类将有 200 个示例(或者 100/200 = 0.5)。
...
# define undersample strategy
undersample = RandomUnderSampler(sampling_strategy=0.5)
这可能是为了确保生成的数据集足够大以适合合理的模型,并且不会丢弃太多来自多数类的有用信息。
在随机欠采样中,可以通过随机选择 90 个多数类实例来创建平衡的类分布。生成的数据集将由 20 个实例组成:10 个(随机剩余的)多数类实例和(原始的)10 个少数类实例。
—第 45 页,不平衡学习:基础、算法和应用,2013
然后,通过调用 fit_resample() 函数并将未转换的数据集作为参数传递,可以一步完成转换并将其应用于数据集。
...
# fit and apply the transform
X_over, y_over = undersample.fit_resample(X, y)
我们可以在具有 1:100 类别不平衡的数据集上演示这一点。
下面列出了完整的示例。
# example of random undersampling to balance the class distribution
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.under_sampling import RandomUnderSampler
# define dataset
X, y = make_classification(n_samples=10000, weights=[0.99], flip_y=0)
# summarize class distribution
print(Counter(y))
# define undersample strategy
undersample = RandomUnderSampler(sampling_strategy='majority')
# fit and apply the transform
X_over, y_over = undersample.fit_resample(X, y)
# summarize class distribution
print(Counter(y_over))
运行该示例首先创建数据集,并报告不平衡的类分布。
对数据集进行拟合和应用变换,并报告新的类分布。我们可以看到,多数类被欠采样,与少数类有相同数量的例子。
必须使用判断和经验结果来判断只有 200 个示例的训练数据集是否足以训练模型。
Counter({0: 9900, 1: 100})
Counter({0: 100, 1: 100})
这种欠采样变换也可以用在流水线中,就像上一节中的过采样变换一样。
这允许仅使用评估方案(如 k-fold 交叉验证)将转换应用于训练数据集,从而避免模型评估中的任何数据泄漏。
...
# define pipeline
steps = [('under', RandomUnderSampler()), ('model', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
我们可以定义一个在不平衡类别数据集上拟合决策树的示例,在重复的 10 倍交叉验证的每个分割上对训练数据集应用欠采样变换。
下面列出了完整的示例。
# example of evaluating a decision tree with random undersampling
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.tree import DecisionTreeClassifier
from imblearn.pipeline import Pipeline
from imblearn.under_sampling import RandomUnderSampler
# define dataset
X, y = make_classification(n_samples=10000, weights=[0.99], flip_y=0)
# define pipeline
steps = [('under', RandomUnderSampler()), ('model', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(pipeline, X, y, scoring='f1_micro', cv=cv, n_jobs=-1)
score = mean(scores)
print('F1 Score: %.3f' % score)
运行该示例在欠采样的不平衡数据集上评估决策树模型。
所选模型和重采样配置是任意的,旨在提供一个模板,您可以使用该模板来测试数据集和学习算法的欠采样,而不是最佳地求解合成数据集。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
使用默认的欠采样策略,平衡多数类和少数类。报告每次折叠和每次重复的 F1 平均得分。
F1 Score: 0.889
结合随机过采样和欠采样
结合随机过采样和欠采样可以获得有趣的结果。
例如,可以对少数类应用适度的过采样,以改善对这些示例的偏差,同时也可以对多数类应用适度的欠采样,以减少对该类的偏差。
与单独执行一种或另一种技术相比,这可以提高整体表现。
例如,如果我们有一个类分布为 1:100 的数据集,我们可能首先应用过采样,通过复制少数类中的示例将比率提高到 1:10,然后应用欠采样,通过删除多数类中的示例将比率进一步提高到 1:2。
这可以通过使用不平衡学习来实现,方法是将采样策略设置为 0.1 (10%),然后使用随机欠采样器,将采样策略设置为 0.5 (50%)。例如:
...
# define oversampling strategy
over = RandomOverSampler(sampling_strategy=0.1)
# fit and apply the transform
X, y = over.fit_resample(X, y)
# define undersampling strategy
under = RandomUnderSampler(sampling_strategy=0.5)
# fit and apply the transform
X, y = under.fit_resample(X, y)
我们可以在 1:100 类分布的合成数据集上演示这一点。完整的示例如下所示:
# example of combining random oversampling and undersampling for imbalanced data
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
# define dataset
X, y = make_classification(n_samples=10000, weights=[0.99], flip_y=0)
# summarize class distribution
print(Counter(y))
# define oversampling strategy
over = RandomOverSampler(sampling_strategy=0.1)
# fit and apply the transform
X, y = over.fit_resample(X, y)
# summarize class distribution
print(Counter(y))
# define undersampling strategy
under = RandomUnderSampler(sampling_strategy=0.5)
# fit and apply the transform
X, y = under.fit_resample(X, y)
# summarize class distribution
print(Counter(y))
运行该示例首先创建合成数据集并总结类分布,显示大约 1:100 的类分布。
然后应用过采样,将分布从大约 1:100 增加到大约 1:10。最后,应用欠采样,进一步将类别分布从 1:10 改善到大约 1:2
Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 990})
Counter({0: 1980, 1: 990})
当使用 k-fold 交叉验证评估一个模型时,我们可能还想应用同样的混合方法。
这可以通过使用具有一系列转换的管道并以正在评估的模型结束来实现;例如:
...
# define pipeline
over = RandomOverSampler(sampling_strategy=0.1)
under = RandomUnderSampler(sampling_strategy=0.5)
steps = [('o', over), ('u', under), ('m', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
我们可以用同一个合成数据集上的决策树模型来演示这一点。
下面列出了完整的示例。
# example of evaluating a model with random oversampling and undersampling
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.tree import DecisionTreeClassifier
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
# define dataset
X, y = make_classification(n_samples=10000, weights=[0.99], flip_y=0)
# define pipeline
over = RandomOverSampler(sampling_strategy=0.1)
under = RandomUnderSampler(sampling_strategy=0.5)
steps = [('o', over), ('u', under), ('m', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(pipeline, X, y, scoring='f1_micro', cv=cv, n_jobs=-1)
score = mean(scores)
print('F1 Score: %.3f' % score)
运行该示例使用重复的 K 折交叉验证来评估决策树模型,其中对训练数据集进行变换,首先使用过采样,然后对执行的每个分割和重复进行欠采样。报告每次折叠和每次重复的 F1 平均得分。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
所选模型和重采样配置是任意的,旨在提供一个模板,您可以使用该模板来测试数据集和学习算法的欠采样,而不是最佳地求解合成数据集。
F1 Score: 0.985
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
书
- 第五章数据级预处理方法,从不平衡数据集中学习,2018。
- 第三章不平衡数据集:从采样到分类器,不平衡学习:基础、算法和应用,2013。
报纸
- 平衡机器学习训练数据的几种方法的行为研究,2004。
- 不平衡分布下的预测建模综述,2015。
应用程序接口
- 不平衡-学习文档。
- 不平衡学习,GitHub 。
- imblearn.over_sampling。randomoversacompler API。
- imb learn . pipeline . pipeline API。
- imblearn.under_sampling。随机欠采样应用编程接口。
文章
摘要
在本教程中,您发现了用于不平衡分类的随机过采样和欠采样
具体来说,您了解到:
- 随机重采样为不平衡数据集的类分布重新平衡提供了一种简单的技术。
- 随机过采样会复制训练数据集中少数类的示例,并可能导致某些模型的过拟合。
- 随机欠采样会从多数类中删除示例,并可能导致丢失对模型来说非常宝贵的信息。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。*
不平衡分类的最佳资源
最后更新于 2021 年 1 月 5 日
分类是一个预测建模问题,涉及到预测给定示例的类标签。
通常假设训练数据集中的示例分布在所有类中是均匀的。实际上,情况很少如此。
那些分类预测模型中的例子在类标签上的分布不相等(例如,是偏斜的),被称为“不平衡分类”
*通常,轻微的不平衡不是问题,可以使用标准的机器学习技术。在不平衡严重的情况下,如 1:100、1:1000 或少数与多数的比例较高,则需要专门的技术。
类别严重不平衡的分类问题需要专门技术的原因是,大多数用于分类的机器学习模型都是围绕类别分布相等的假设设计和测试的。因此,它们经常失败或导致误导性结果。
在本教程中,您将发现可以用来开始不平衡分类的最佳资源。
完成本教程后,您将知道:
- 不平衡分类的最佳机器学习书籍。
- 介绍阶级不平衡话题的最佳调查论文。
- 您可以用来为不平衡数据集开发解决方案的最佳 Python 库。
用我的新书Python 不平衡分类启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
- 2021 年 1 月更新:更新了 API 文档的链接。
不平衡分类最佳资源 图片由拉德克·库恰尔斯基提供,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- 不平衡分类书籍
- 不平衡分类综述
- 不平衡分类的 Python 库
不平衡分类书籍
用机器学习解决不平衡分类预测建模问题是一个相对较新的研究领域。
然而,考虑到不平衡类别数据集的普遍性,关于这个主题有几本书和几个章节。
在本节中,我们将仔细阅读以下关于机器学习不平衡分类的书籍:
- 不平衡学习:基础、算法和应用,2013。
- 从不平衡数据集中学习,2018。
我还将包括以下这本书,其中有一章专门讨论这个主题:
- 应用预测建模,2013。
我发现还有另外两本书是相关的,但可能更切实际,我就不详细介绍了;他们是:
- 生态与生物研究不平衡数据的统计方法,2019。
- 用模糊和粗糙集方法处理机器学习中不平衡和弱标记的数据,2018。
让我们仔细看看这些书。
不平衡学习:基础、算法和应用
这本书是由两个学者编辑的论文集,这两个学者写了很多关于这个主题的文章:和马云钱。
该书于 2013 年出版。
- 不平衡学习:基础、算法和应用,2013。
不平衡学习——基础、算法和应用
这本书旨在让研究生或学者跟上不平衡学习的领域。这是比不平衡分类更一般的领域,因为它包括训练数据集可能不平衡的其他问题类型,例如回归和聚类。
具体来说,我们将不平衡学习定义为具有严重数据分布偏差的数据表示和信息提取的学习过程,以开发有效的决策边界来支持决策过程。学习过程可以包括监督学习、非监督学习、半监督学习或两者或全部的组合。不平衡学习的任务也可以应用于回归、分类或聚类任务。
—第 1-2 页,不平衡学习:基础、算法和应用,2013。
它为从业者提供了一个很好的起点来获得该领域和技术的概述。
这本书的目录如下。
- 1.介绍
- 2.不平衡学习的基础
- 3.不平衡数据集:从采样到分类器
- 4.班级不平衡学习的集成方法
- 5.支持向量机的类不平衡学习方法
- 6.班级失衡与主动学习
- 7.类分布不均衡的非平稳流数据学习
- 8.不平衡学习的评估指标
从不平衡数据集中学习
这本书也是关于不平衡数据集的机器学习主题的论文集,尽管感觉比之前的书“不平衡学习”更有凝聚力。”
该书由一系列学者阿尔韦托·费尔南德斯、萨尔瓦多·加西亚、米克尔·加拉、罗纳尔多·普拉蒂、巴托兹·科劳兹克和弗朗西斯科·埃雷拉撰写或编辑,于 2018 年出版。
- 从不平衡数据集中学习,2018。
从不平衡数据集中学习
与前一本书类似,这本书旨在让研究生和工程师了解不平衡数据集的机器学习领域。
这本书的目标读者是旨在应用不平衡学习技术来解决不同类型的现实世界问题的开发人员和工程师,以及需要全面回顾从不平衡数据中学习的技术、方法和工具的研究人员和学生。
—第八页,从不平衡数据集中学习,2018。
这本书看起来比以前的书更系统(例如,从头到尾完成一个项目)和实用,以前的书看起来更学术(pet 方法或子领域)。如果你有预算,我建议两者一起买。
这本书的目录如下。
- 1.KDD 与数据科学导论
- 2.不平衡分类的基础
- 3.绩效指标
- 4.对成本敏感的学习
- 5.数据级预处理方法
- 6.算法级方法
- 7.集成学习
- 8.多类不平衡分类
- 9.不平衡学习的降维
- 10.数据内在特征
- 11.从不平衡数据流中学习
- 12.非经典不平衡分类问题
- 13.大数据的不平衡分类
- 14.不平衡分类软件和库
应用预测建模
这是我最喜欢的应用机器学习手册之一,由 Max Kuhn 和 Kjell Johnson 编写,重点是 r
这本书出版于 2013 年,但总的建议可能是永恒的。
- 应用预测建模,2013。
应用预测建模
虽然整本书读起来很棒,但这本书有一章专门讨论不平衡分类的问题。
- 第十六章:严重阶级失衡的补救措施
本章的方法是对“房车保单所有权”数据集的案例研究。作者通过这个问题展示了一套不同的实用技术来处理严重的阶级不平衡。
本章是阅读如何使用现代方法处理现实世界不平衡数据集的实际演示的必读。
本章各节如下:
- 16.1 案例研究:预测房车保单所有权
- 16.2 阶级不平衡的影响
- 16.3 模型调整
- 16.4 替代截止值
- 16.5 调整先验概率
- 16.6 不相等的案例权重
- 16.7 取样方法
- 16.8 成本敏感型培训
- 16.9 计算
不平衡分类综述
关于不平衡分类的机器学习方法以及相关的问题和技术有成千上万的出版物。
在本节中,我们将看一些最好的调查论文,而不是列举该领域最好的论文。
综述性论文是对该领域和该领域技术的地位以及它们之间的相互关系进行广泛概述的论文。它们旨在帮助刚进入该领域的人,如研究生和工程师,快速掌握最新知识。
作为一个实践者,阅读一篇调查论文可能比浏览关于这个主题的书籍更有效率。
有许多优秀的调查论文可供选择;我推荐的收藏夹如下:
- 从不平衡的数据中学习:开放的挑战和未来的方向,巴托兹·科劳兹克,2016。
- 不平衡分布下的预测建模综述,保拉·布兰科,路易斯·托戈和丽塔·里贝罗,2015。
- 不平衡数据的分类:综述,孙,黄安祥,穆罕默德·卡迈勒,2009。
- 从不平衡数据中学习,何海波和爱德华多·加西亚,2009。
我也推荐学习论文,用一套标准的机器学习数据集来演示一种或多种标准技术的论文。在这种情况下,这些技术被设计来解决不平衡的类分布,并且标准数据集具有偏斜的类分布。
这些论文很快就找出了哪些方法有效(或者流行)以及哪些数据集可用作基准。
这类好论文的一些例子包括:
- 对不平衡数据分类的洞察:关于使用数据内在特征的经验结果和当前趋势,2013。
- 平衡机器学习训练数据的几种方法的行为研究,2004。
不平衡分类的 Python 库
Python 已经迅速成为应用机器学习的首选编程语言。
科学工具包-学习库
Python 中机器学习的 go-to 库是 Sklearn ,它提供数据准备、机器学习算法和模型评估方案等技术。
Sklearn 是一个 Python 模块,集成了各种最先进的机器学习算法,用于中等规模的有监督和无监督问题。这个包侧重于使用通用高级语言将机器学习带给非专家。
——Sklearn:Python 中的机器学习,2011。
尽管 Sklearn 库不是围绕不平衡分类问题设计的,但它确实提供了一些处理不平衡数据集的工具,例如:
- 支持一系列指标,例如 ROC AUC 和准确率/召回率、F1、Brier 评分等。
- 支持类别加权,例如决策树、SVM 等。
不平衡学习库
一个与 Sklearn 相关的致力于不平衡分类问题的项目叫做不平衡学习。
它结合 Sklearn 库提供了可用于不平衡分类的技术,允许库之间共享学习算法和模型评估技术。
不平衡学习是一个开源的 python 工具箱,旨在提供广泛的方法来应对机器学习和模式识别中经常遇到的不平衡数据集问题。
——不平衡学习:一个应对机器学习中不平衡数据集魔咒的 Python 工具箱,2016。
该库侧重于提供过采样和欠采样技术,以便在拟合给定的机器学习模型之前,使训练数据集中的类分布更加均匀。
有关不平衡学习的更多信息,请参见:
摘要
在本教程中,您发现了可以用来开始不平衡分类的最佳资源。
具体来说,您了解到:
- 不平衡分类的最佳机器学习书籍。
- 介绍阶级不平衡话题的最佳调查论文。
- 您可以用来为不平衡数据集开发解决方案的最佳 Python 库。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。*
不平衡分类的 ROC 曲线和精确率召回率曲线
最后更新于 2020 年 9 月 16 日
大多数不平衡分类问题涉及两类:一类是包含大多数例子的否定情况,另一类是包含少数例子的肯定情况。
有助于解释二进制(两类)分类预测模型的两个诊断工具是 ROC 曲线和准确率-召回曲线。
在解释概率预测时,可以根据曲线创建曲线图,并用于了解不同阈值的表现权衡。每个图还可以用曲线分数下的区域进行总结,该区域可用于直接比较分类模型。
在本教程中,您将发现用于不平衡分类的 ROC 曲线和准确率-召回曲线。
完成本教程后,您将知道:
- ROC 曲线和准确率-召回曲线为二分类模型提供了诊断工具。
- ROC AUC 和准确率-召回 AUC 提供总结曲线的分数,可用于比较分类器。
- ROC 曲线和 ROC AUC 对于少数类样本很少的严重不平衡分类问题是乐观的。
用我的新书Python 不平衡分类启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
不平衡分类的 ROC 曲线和准确率-召回曲线 图片由尼古拉斯·阿·托内利提供,保留部分权利。
教程概述
本教程分为四个部分;它们是:
- 混淆矩阵述评
- ROC 曲线和 ROC 曲线面积比
- 准确率-召回曲线和 AUC
- 具有严重不平衡的 ROC 曲线和准确率-召回曲线
混淆矩阵述评
在我们深入研究 ROC 曲线和 PR 曲线之前,回顾一下混淆矩阵是很重要的。
对于不平衡分类问题,多数类通常称为阴性结果(如“无变化”或“阴性检测结果”),少数类通常称为阳性结果(如“变化”或“阳性检测结果”)。
混淆矩阵不仅能更深入地了解预测模型的表现,还能更深入地了解哪些类被正确预测,哪些被错误预测,以及出现了什么类型的错误。
最简单的混淆矩阵是针对两类分类问题,有负(0 类)和正(1 类)类。
在这种类型的混淆矩阵中,表中的每个单元格都有一个具体且易于理解的名称,总结如下:
| Positive Prediction | Negative Prediction
Positive Class | True Positive (TP) | False Negative (FN)
Negative Class | False Positive (FP) | True Negative (TN)
组成 ROC 曲线和准确率-召回曲线的度量标准是根据混淆矩阵中的单元格来定义的。
现在我们已经复习了混淆矩阵,让我们仔细看看 ROC 曲线度量。
ROC 曲线和 ROC 曲线面积比
ROC 曲线(或接收器工作特性曲线)是总结正类上二分类模型表现的图。
x 轴表示假阳性率,y 轴表示真阳性率。
- ROC 曲线:假阳性率(x)与真阳性率(y)的关系图。
真阳性率是一个分数,计算方法是真阳性预测的总数除以真阳性和假阴性的总和(例如阳性类别中的所有例子)。真正的阳性率被称为敏感度或召回率。
- 真阳性 =真阳性/(真阳性+假阴性)
假阳性率的计算方法是假阳性预测的总数除以假阳性和真阴性的总和(例如阴性类别中的所有例子)。
- 假阳性 =假阳性/(假阳性+真阴性)
我们可以将该图视为正类(y 轴)的正确预测分数与负类(x 轴)的误差分数之比。
理想情况下,我们希望正确的正类预测的分数为 1(图的顶部),不正确的负类预测的分数为 0(图的左侧)。这强调了实现完美技能的最佳分类器是图的左上角(坐标 0,1)。
- 完美技能:剧情左上角的一个点。
阈值应用于正类和负类之间的概率分界点,默认情况下,对于任何分类器,该分界点将被设置为 0.5,在每个结果(0 和 1)的中间。
真正平均和假正平均之间存在权衡,因此改变分类阈值将改变预测的平衡,以假正平均为代价提高真正平均,或者相反。
通过评估不同阈值的真阳性和假阳性,可以构建从左下方延伸到右上方并向左上方弯曲的曲线。这条曲线被称为 ROC 曲线。
在阳性和阴性类别之间没有辨别能力的分类器将在假阳性率 0 和真阳性率 0(坐标(0,0)或预测所有阴性类别)到假阳性率 1 和真阳性率 1(坐标(1,1)或预测所有阳性类别)之间形成对角线。这条线以下的点代表的模型比没有技能更糟糕。
该曲线提供了一种方便的诊断工具,用于研究具有不同阈值的一个分类器以及对真阳性和假阳性的影响。人们可能会选择一个阈值来偏向分类模型的预测行为。
它是一种流行的诊断工具,用于平衡和不平衡二进制预测问题的分类器,因为它不偏向多数或少数类。
ROC 分析不偏向于以牺牲多数类为代价在少数类上表现良好的模型——这种特性在处理不平衡数据时非常有吸引力。
—第 27 页,不平衡学习:基础、算法和应用,2013。
我们可以使用 roc_curve() Sklearn 函数在 Python 中绘制模型的 ROC 曲线。
该函数获取测试集中的真实结果(0,1)和 1 类的预测概率。该函数返回每个阈值的假阳性率、每个阈值的真阳性率和阈值。
...
# calculate roc curve
fpr, tpr, thresholds = roc_curve(testy, pos_probs)
大多数 Sklearn 模型可以通过调用 predict_proba() 函数来预测概率。
这将为测试集中的每个样本返回每个类别的概率,例如,在二进制分类问题中,两个类别中的每个类别有两个数字。正类的概率可以作为概率数组中的第二列来检索。
...
# predict probabilities
yhat = model.predict_proba(testX)
# retrieve just the probabilities for the positive class
pos_probs = yhat[:, 1]
我们可以在合成数据集上演示这一点,并绘制无技能分类器和逻辑回归模型的 ROC 曲线。
make _ classing()函数可以用来创建综合分类问题。在这种情况下,我们将为二进制分类问题创建 1000 个示例(每个类大约 500 个示例)。然后,我们将数据集分割成一个训练集,并测试大小相等的集合,以便拟合和评估模型。
...
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
逻辑回归模型是一个很好的演示模型,因为预测的概率经过了很好的校准,而其他机器学习模型不是围绕概率模型开发的,在这种情况下,它们的概率可能需要首先校准(例如 SVM)。
...
# fit a model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
下面列出了完整的示例。
# example of a roc curve for a predictive model
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve
from matplotlib import pyplot
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# fit a model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
# predict probabilities
yhat = model.predict_proba(testX)
# retrieve just the probabilities for the positive class
pos_probs = yhat[:, 1]
# plot no skill roc curve
pyplot.plot([0, 1], [0, 1], linestyle='--', label='No Skill')
# calculate roc curve for model
fpr, tpr, _ = roc_curve(testy, pos_probs)
# plot model roc curve
pyplot.plot(fpr, tpr, marker='.', label='Logistic')
# axis labels
pyplot.xlabel('False Positive Rate')
pyplot.ylabel('True Positive Rate')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
运行该示例会创建合成数据集,拆分为训练集和测试集,然后在训练数据集上拟合逻辑回归模型,并使用它对测试集进行预测。
显示了逻辑回归模型的 ROC 曲线(橙色带点)。对角线形式的无技能分类器(蓝色带破折号)。
逻辑回归模型和无技能分类器的 ROC 曲线
现在我们已经看到了 ROC 曲线,让我们仔细看看曲线评分下的 ROC 区域。
曲线下面积评分
虽然 ROC 曲线是一个有用的诊断工具,但根据曲线比较两个或多个分类器可能很有挑战性。
相反,可以计算曲线下的面积,以给出分类器模型在所有阈值下的单一分数。这被称为曲线下的 ROC 面积或 ROCAUC,有时也称为 ROC AUC。
对于一个完美的分类器,分数是一个介于 0.0 和 1.0 之间的值。
AUCROC 可以解释为分类器给出的分数将随机选择的正实例排名高于随机选择的负实例的概率。
—第 54 页,从不平衡数据集中学习,2018。
这个单一的分数可以用来直接比较二分类器模型。因此,这个分数可能是最常用于比较不平衡问题的分类模型。
最常见的度量包括接收器操作特性(ROC)分析和 ROC 曲线下的面积(AUC)。
—第 27 页,不平衡学习:基础、算法和应用,2013。
可以在 Sklearn 中使用 roc_auc_score()函数计算 ROC 的 AUC。
像 roc_curve() 函数一样,AUC 函数同时采用测试集中的真实结果(0,1)和正类的预测概率。
...
# calculate roc auc
roc_auc = roc_auc_score(testy, pos_probs)
我们可以用一个逻辑回归模型来演示同一个合成数据集。
下面列出了完整的示例。
# example of a roc auc for a predictive model
from sklearn.datasets import make_classification
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# no skill model, stratified random class predictions
model = DummyClassifier(strategy='stratified')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
pos_probs = yhat[:, 1]
# calculate roc auc
roc_auc = roc_auc_score(testy, pos_probs)
print('No Skill ROC AUC %.3f' % roc_auc)
# skilled model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
pos_probs = yhat[:, 1]
# calculate roc auc
roc_auc = roc_auc_score(testy, pos_probs)
print('Logistic ROC AUC %.3f' % roc_auc)
运行该示例会创建和拆分合成数据集,拟合模型,并使用拟合模型预测测试数据集上的概率。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
在这种情况下,我们可以看到逻辑回归模型在合成数据集上的 ROC AUC 约为 0.903,这比得分约为 0.5 的无技能分类器好得多。
No Skill ROC AUC 0.509
Logistic ROC AUC 0.903
虽然使用广泛,但 ROC AUC 也不是没有问题。
对于严重倾斜的不平衡分类和少数民族的例子,ROC AUC 可能会产生误导。这是因为少量正确或不正确的预测会导致 ROC 曲线或 ROC AUC 评分的巨大变化。
尽管 ROC 图被广泛用于在存在类不平衡的情况下评估分类器,但它有一个缺点:在类稀有性下,即当类不平衡的问题与少数实例的低样本量的存在相关联时,因为估计可能是不可靠的。
—第 55 页,从不平衡数据集中学习,2018。
一种常见的替代方法是准确率-召回曲线和曲线下面积。
准确率-召回曲线和 AUC
准确率是一个度量标准,它量化了正确的积极预测的数量。
它的计算方法是真阳性数除以真阳性和假阳性总数。
- 准确率 =真阳性/(真阳性+假阳性)
结果是一个介于 0.0(无准确率)和 1.0(完全或完美准确率)之间的值。
回忆是一个度量标准,它量化了从所有可能做出的积极预测中做出的正确积极预测的数量。
它的计算方法是真阳性数除以真阳性和假阴性总数(例如,它是真阳性率)。
- 回忆 =真阳性/(真阳性+假阴性)
结果是 0.0(无召回)到 1.0(完全或完美召回)之间的值。
精确度和召回率都集中在积极类(少数类)上,而与真正的消极类(多数类)无关。
……精确度和召回率使得评估少数民族分类器的表现成为可能。
—第 27 页,不平衡学习:基础、算法和应用,2013。
准确率-召回曲线(或 PR 曲线)是不同概率阈值的准确率(y 轴)和召回率(x 轴)的曲线图。
- PR 曲线:召回率(x)对准确率(y)的曲线图。
具有完美技巧的模型被描绘为坐标为(1,1)的点。一个巧妙的模型由一条向(1,1)坐标弯曲的曲线表示。无技能分类器将是图上的一条水平线,其准确率与数据集中的正例数成正比。对于平衡数据集,这将是 0.5。
PR 曲线对少数类的关注使其成为不平衡二分类模型的有效诊断工具。
准确率-召回曲线(PR 曲线)推荐用于高度倾斜的区域,在这些区域 ROC 曲线可能会提供过于乐观的表现视图。
——不平衡分布下的预测建模综述,2015 年。
可以在 Sklearn 中使用 precision_recall_curve()函数计算准确率-召回率曲线,该函数获取少数类的类标签和预测概率,并返回准确率、召回率和阈值。
...
# calculate precision-recall curve
precision, recall, _ = precision_recall_curve(testy, pos_probs)
我们可以在预测模型的合成数据集上演示这一点。
下面列出了完整的示例。
# example of a precision-recall curve for a predictive model
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_recall_curve
from matplotlib import pyplot
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# fit a model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
# predict probabilities
yhat = model.predict_proba(testX)
# retrieve just the probabilities for the positive class
pos_probs = yhat[:, 1]
# calculate the no skill line as the proportion of the positive class
no_skill = len(y[y==1]) / len(y)
# plot the no skill precision-recall curve
pyplot.plot([0, 1], [no_skill, no_skill], linestyle='--', label='No Skill')
# calculate model precision-recall curve
precision, recall, _ = precision_recall_curve(testy, pos_probs)
# plot the model precision-recall curve
pyplot.plot(recall, precision, marker='.', label='Logistic')
# axis labels
pyplot.xlabel('Recall')
pyplot.ylabel('Precision')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
运行该示例会创建合成数据集,拆分为训练集和测试集,然后在训练数据集上拟合逻辑回归模型,并使用它对测试集进行预测。
显示了逻辑回归模型的准确率-召回曲线(橙色,带点)。随机或基线分类器显示为水平线(蓝色带破折号)。
逻辑回归模型和无技能分类器的准确率-召回曲线
现在我们已经看到了准确率-召回曲线,让我们仔细看看曲线得分下的 ROC 区域。
精确-召回曲线下面积分数
准确率-召回 AUC 就像 ROC AUC 一样,它将具有一系列阈值的曲线总结为一个分数。
然后,该分数可以用作二分类问题上不同模型之间的比较点,其中分数 1.0 代表具有完美技能的模型。
准确率-召回 AUC 分数可以使用 Sklearn 中的 auc()函数计算,以准确率和召回值为参数。
...
# calculate the precision-recall auc
auc_score = auc(recall, precision)
同样,我们可以演示在合成数据集上计算逻辑回归的准确率-召回率 AUC。
下面列出了完整的示例。
# example of a precision-recall auc for a predictive model
from sklearn.datasets import make_classification
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import auc
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# no skill model, stratified random class predictions
model = DummyClassifier(strategy='stratified')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
pos_probs = yhat[:, 1]
# calculate the precision-recall auc
precision, recall, _ = precision_recall_curve(testy, pos_probs)
auc_score = auc(recall, precision)
print('No Skill PR AUC: %.3f' % auc_score)
# fit a model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
pos_probs = yhat[:, 1]
# calculate the precision-recall auc
precision, recall, _ = precision_recall_curve(testy, pos_probs)
auc_score = auc(recall, precision)
print('Logistic PR AUC: %.3f' % auc_score)
运行该示例会创建和拆分合成数据集,拟合模型,并使用拟合模型预测测试数据集上的概率。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
在这种情况下,我们可以看到逻辑回归模型在合成数据集上的准确率-召回率 AUC 约为 0.898,这比在这种情况下得分为 0.632 的无技能分类器好得多。
No Skill PR AUC: 0.632
Logistic PR AUC: 0.898
具有严重不平衡的 ROC 曲线和准确率-召回曲线
在这一节中,我们将探讨使用 ROC 曲线和准确率-召回曲线处理具有严重类别不平衡的二分类问题的情况。
首先,我们可以使用 make_classification() 函数为一个分类问题创建 1000 个例子,少数与多数类的比例大约为 1:100。这可以通过设置“权重参数并指定从每个类生成的实例的权重来实现。
我们将对 1000 个示例使用 99%和 1%的权重,这意味着 0 类大约有 990 个,1 类大约有 10 个。
...
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], random_state=1)
然后,我们可以将数据集拆分为训练集和测试集,并通过在调用 train_test_split() 函数时设置“分层”参数并将其设置为目标变量数组来确保两者具有相同的一般类比率。
...
# split into train/test sets with same class ratio
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2, stratify=y)
将这些联系在一起,下面列出了准备不平衡数据集的完整示例。
# create an imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], random_state=1)
# split into train/test sets with same class ratio
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2, stratify=y)
# summarize dataset
print('Dataset: Class0=%d, Class1=%d' % (len(y[y==0]), len(y[y==1])))
print('Train: Class0=%d, Class1=%d' % (len(trainy[trainy==0]), len(trainy[trainy==1])))
print('Test: Class0=%d, Class1=%d' % (len(testy[testy==0]), len(testy[testy==1])))
运行该示例首先总结整个数据集的类比率,然后是每个训练集和测试集的比率,确认数据集的分割保持相同的比率。
Dataset: Class0=985, Class1=15
Train: Class0=492, Class1=8
Test: Class0=493, Class1=7
接下来,我们可以在数据集上开发一个逻辑回归模型,并使用 ROC 曲线和 ROC AUC 评分来评估模型的表现,并将结果与无技能分类器进行比较,就像我们在上一节中所做的那样。
下面列出了完整的示例。
# roc curve and roc auc on an imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.dummy import DummyClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score
from matplotlib import pyplot
# plot no skill and model roc curves
def plot_roc_curve(test_y, naive_probs, model_probs):
# plot naive skill roc curve
fpr, tpr, _ = roc_curve(test_y, naive_probs)
pyplot.plot(fpr, tpr, linestyle='--', label='No Skill')
# plot model roc curve
fpr, tpr, _ = roc_curve(test_y, model_probs)
pyplot.plot(fpr, tpr, marker='.', label='Logistic')
# axis labels
pyplot.xlabel('False Positive Rate')
pyplot.ylabel('True Positive Rate')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], random_state=1)
# split into train/test sets with same class ratio
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2, stratify=y)
# no skill model, stratified random class predictions
model = DummyClassifier(strategy='stratified')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
naive_probs = yhat[:, 1]
# calculate roc auc
roc_auc = roc_auc_score(testy, naive_probs)
print('No Skill ROC AUC %.3f' % roc_auc)
# skilled model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
model_probs = yhat[:, 1]
# calculate roc auc
roc_auc = roc_auc_score(testy, model_probs)
print('Logistic ROC AUC %.3f' % roc_auc)
# plot roc curves
plot_roc_curve(testy, naive_probs, model_probs)
运行该示例会像以前一样创建不平衡的二进制类别数据集。
然后在训练数据集上拟合逻辑回归模型,并在测试数据集上进行评估。一个无技能分类器被评估在旁边作为参考。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
报告了两个分类器的 ROC AUC 分数,显示无技能分类器达到了预期的大约 0.5 的最低分数。逻辑回归模型的结果表明它有一些技巧,得分约为 0.869。
No Skill ROC AUC 0.490
Logistic ROC AUC 0.869
还为模型和无技能分类器创建了 ROC 曲线,与对角线无技能分类器相比,该曲线显示的不是出色的表现,而是绝对熟练的表现。
不平衡类别数据集上逻辑回归的 ROC 曲线绘制
接下来,我们可以对相同的模型拟合进行分析,并使用准确率-召回曲线和 AUC 评分对相同的数据进行评估。
下面列出了完整的示例。
# pr curve and pr auc on an imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import auc
from matplotlib import pyplot
# plot no skill and model precision-recall curves
def plot_pr_curve(test_y, model_probs):
# calculate the no skill line as the proportion of the positive class
no_skill = len(test_y[test_y==1]) / len(test_y)
# plot the no skill precision-recall curve
pyplot.plot([0, 1], [no_skill, no_skill], linestyle='--', label='No Skill')
# plot model precision-recall curve
precision, recall, _ = precision_recall_curve(testy, model_probs)
pyplot.plot(recall, precision, marker='.', label='Logistic')
# axis labels
pyplot.xlabel('Recall')
pyplot.ylabel('Precision')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], random_state=1)
# split into train/test sets with same class ratio
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2, stratify=y)
# no skill model, stratified random class predictions
model = DummyClassifier(strategy='stratified')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
naive_probs = yhat[:, 1]
# calculate the precision-recall auc
precision, recall, _ = precision_recall_curve(testy, naive_probs)
auc_score = auc(recall, precision)
print('No Skill PR AUC: %.3f' % auc_score)
# fit a model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
yhat = model.predict_proba(testX)
model_probs = yhat[:, 1]
# calculate the precision-recall auc
precision, recall, _ = precision_recall_curve(testy, model_probs)
auc_score = auc(recall, precision)
print('Logistic PR AUC: %.3f' % auc_score)
# plot precision-recall curves
plot_pr_curve(testy, model_probs)
像以前一样,运行该示例会创建不平衡的二进制类别数据集。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
在这种情况下,我们可以看到逻辑回归模型的公关 AUC 约为 0.228,无技能模型的公关 AUC 约为 0.007。
No Skill PR AUC: 0.007
Logistic PR AUC: 0.228
还创建了准确率-召回曲线的图。
我们可以像预期的那样看到无技能分类器的水平线,在这种情况下,逻辑回归曲线的之字形线接近无技能线。
不平衡类别数据集上逻辑回归准确率-召回率曲线的绘制
为了解释为什么 ROC 曲线和 PR 曲线讲述了一个不同的故事,回想一下 PR 曲线关注的是少数族裔,而 ROC 曲线涵盖了这两个阶层。
如果我们使用阈值 0.5,并使用逻辑回归模型对测试集中的所有示例进行预测,我们会看到它在所有情况下都预测 0 类或多数类。这可以通过使用拟合模型来预测清晰的类标签来确认,这将使用默认阈值 0.5。然后可以总结预测的类标签的分布。
...
# predict class labels
yhat = model.predict(testX)
# summarize the distribution of class labels
print(Counter(yhat))
然后,我们可以创建正类的预测概率直方图,以确认预测概率的质量低于 0.5,因此被映射到类 0。
...
# create a histogram of the predicted probabilities
pyplot.hist(pos_probs, bins=100)
pyplot.show()
将这些联系在一起,完整的示例如下所示。
# summarize the distribution of predicted probabilities
from collections import Counter
from matplotlib import pyplot
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.99, 0.01], random_state=1)
# split into train/test sets with same class ratio
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2, stratify=y)
# fit a model
model = LogisticRegression(solver='lbfgs')
model.fit(trainX, trainy)
# predict probabilities
yhat = model.predict_proba(testX)
# retrieve just the probabilities for the positive class
pos_probs = yhat[:, 1]
# predict class labels
yhat = model.predict(testX)
# summarize the distribution of class labels
print(Counter(yhat))
# create a histogram of the predicted probabilities
pyplot.hist(pos_probs, bins=100)
pyplot.show()
运行该示例首先总结了预测类标签的分布。正如我们所料,测试集中的所有示例都预测了多数类(类 0)。
Counter({0: 500})
还创建了类别 1 的预测概率直方图,显示质心(大多数预测概率)小于 0.5,实际上通常接近于零。
不平衡分类 1 类的逻辑回归预测概率直方图
这意味着,除非仔细选择概率阈值,否则模型预测中任何巧妙的细微差别都将丢失。选择用于将预测概率解释为清晰类别标签的阈值是一个重要的主题
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
教程
报纸
- 不平衡分布下的预测建模综述,2015。
书
- 不平衡学习:基础、算法和应用,2013。
- 从不平衡数据集中学习,2018。
应用程序接口
- sklearn . datasets . make _ classification API。
- 硬化. metrics.roc_curve API 。
- 硬化. metrics.roc_auc_score API
- 准确率 _ 召回 _ 曲线 API 。
- 硬化.公制.无 API 。
文章
摘要
在本教程中,您发现了用于不平衡分类的 ROC 曲线和准确率-召回曲线。
具体来说,您了解到:
- ROC 曲线和准确率-召回曲线为二分类模型提供了诊断工具。
- ROC AUC 和准确率-召回 AUC 提供总结曲线的分数,可用于比较分类器。
- ROC 曲线和 ROC AUC 对于少数类样本很少的严重不平衡分类问题是乐观的。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
Python 中用于不平衡分类的 SMOTE
最后更新于 2021 年 3 月 17 日
不平衡分类涉及在具有严重类别不平衡的类别数据集上开发预测模型。
使用不平衡数据集的挑战在于,大多数机器学习技术会忽略少数类,从而导致少数类的表现不佳,尽管少数类的表现通常是最重要的。
解决不平衡数据集的一种方法是对少数类进行过采样。最简单的方法是在少数类中复制例子,尽管这些例子没有给模型添加任何新的信息。相反,可以从现有的例子中合成新的例子。这是一种针对少数民族的数据扩充,被称为合成少数民族过采样技术,简称为 SMOTE 。
在本教程中,您将发现针对过采样不平衡类别数据集的 SMOTE。
完成本教程后,您将知道:
- SMOTE 如何为少数民族阶层综合新的例子。
- 如何在 SMOTE 变换的训练数据集上正确拟合和评估机器学习模型。
- 如何使用 SMOTE 的扩展生成沿着类决策边界的合成例子。
用我的新书Python 不平衡分类启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
- 2021 年 1 月更新:更新了 API 文档的链接。
使用 Python 对不平衡分类进行过采样 图片由 Victor U 提供,保留部分权利。
教程概述
本教程分为五个部分;它们是:
- 合成少数过采样技术
- 不平衡学习库
- 用于平衡数据的 SMOTE
- 分类标准
- 选择性合成样品生成
- 边界线-SMOTE
- 边界线-SVM
- 自适应合成采样
合成少数过采样技术
不平衡分类的一个问题是,少数类的例子太少,模型无法有效地学习决策边界。
解决这个问题的一个方法是对少数民族的例子进行过采样。这可以通过在拟合模型之前简单地复制训练数据集中少数类的例子来实现。这可以平衡类分布,但不会向模型提供任何附加信息。
复制少数民族的例子的一个改进是综合少数民族的新例子。这是一种针对表格数据的数据扩充,非常有效。
也许最广泛使用的合成新例子的方法叫做合成少数过采样技术,简称 SMOTE。该技术由尼泰什·查瓦拉等人在他们 2002 年的论文中描述,该论文以标题为“ SMOTE:合成少数民族过采样技术的技术命名
SMOTE 的工作方式是选择特征空间中靠近的示例,在特征空间中的示例之间绘制一条线,并在沿着该线的某个点绘制一个新样本。
具体来说,首先从少数民族中随机选择一个例子。然后找到该示例中最近邻居的 k (通常 k=5 )。选择随机选择的邻居,并在特征空间中两个示例之间的随机选择点创建合成示例。
… SMOTE 首先随机选择一个少数民族类实例 a,并找到它的 k 个最近的少数民族类邻居。然后,通过随机选择 k 个最近邻居 b 中的一个,并连接 a 和 b 以在特征空间中形成线段,来创建合成实例。合成实例被生成为两个选定实例 a 和 b 的凸组合。
—第 47 页,不平衡学习:基础、算法和应用,2013。
这个过程可以用来为少数民族创造尽可能多的合成例子。如本文所述,它建议首先使用随机欠采样来修剪多数类中的示例数量,然后使用 SMOTE 对少数类进行过采样来平衡类分布。
SMOTE 和欠采样的组合比普通欠采样表现更好。
——SMOTE:合成少数民族过采样技术,2011 年。
该方法是有效的,因为来自少数类的新的合成示例被创建为似是而非的,也就是说,在特征空间上与来自少数类的现有示例相对接近。
我们的合成过采样方法可以使分类器构建包含附近少数类点的更大的决策区域。
——SMOTE:合成少数民族过采样技术,2011 年。
这种方法的一个普遍缺点是,创建合成示例时没有考虑多数类,如果类之间有很强的重叠,可能会导致示例不明确。
现在我们已经熟悉了这种技术,让我们来看一个不平衡分类问题的工作示例。
不平衡学习库
在这些例子中,我们将使用不平衡学习 Python 库提供的实现,可以通过 pip 安装如下:
sudo pip install imbalanced-learn
您可以通过打印已安装库的版本来确认安装成功:
# check version number
import imblearn
print(imblearn.__version__)
运行该示例将打印已安装库的版本号;例如:
0.5.0
用于平衡数据的 SMOTE
在本节中,我们将通过将 SMOTE 应用于不平衡二进制分类问题来发展它的直觉。
首先,我们可以使用make _ classification()sci kit-learn 函数创建一个包含 10,000 个示例和 1:100 类分布的合成二进制类别数据集。
...
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
我们可以使用计数器对象来总结每个类中的示例数量,以确认数据集创建正确。
...
# summarize class distribution
counter = Counter(y)
print(counter)
最后,我们可以创建数据集的散点图,并为每个类的示例涂上不同的颜色,以清楚地看到类不平衡的空间性质。
...
# scatter plot of examples by class label
for label, _ in counter.items():
row_ix = where(y == label)[0]
pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()
将所有这些联系在一起,下面列出了生成和绘制合成二分类问题的完整示例。
# Generate and plot a synthetic imbalanced classification dataset
from collections import Counter
from sklearn.datasets import make_classification
from matplotlib import pyplot
from numpy import where
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# summarize class distribution
counter = Counter(y)
print(counter)
# scatter plot of examples by class label
for label, _ in counter.items():
row_ix = where(y == label)[0]
pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()
运行示例首先总结了类分布,确认了 1:100 的比例,在本例中,多数类中有大约 9900 个示例,少数类中有 100 个示例。
Counter({0: 9900, 1: 100})
创建数据集的散点图,显示属于多数类的大量点(蓝色)和分散在少数类的少量点(橙色)。我们可以看到这两个类别之间有一定程度的重叠。
不平衡二分类问题的散点图
接下来,我们可以使用 SMOTE 对少数类进行过采样,并绘制转换后的数据集。
我们可以在 SMOTE 类中使用不平衡学习 Python 库提供的 SMOTE 实现。
SMOTE 类的作用类似于 Sklearn 中的数据转换对象,因为它必须被定义和配置,适合数据集,然后应用于创建数据集的新转换版本。
例如,我们可以用默认参数定义一个 SMOTE 实例,该实例将平衡少数类,然后一步适应并应用它来创建数据集的转换版本。
...
# transform the dataset
oversample = SMOTE()
X, y = oversample.fit_resample(X, y)
转换后,我们可以总结新转换数据集的类分布,现在可以通过在少数类中创建许多新的合成示例来平衡这种分布。
...
# summarize the new class distribution
counter = Counter(y)
print(counter)
还可以创建转换后数据集的散点图,我们预计在少数民族类的原始示例之间的线上会看到更多少数民族类的示例。
将这些联系在一起,下面列出了将 SMOTE 应用于合成数据集,然后汇总并绘制转换结果的完整示例。
# Oversample and plot imbalanced dataset with SMOTE
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
from matplotlib import pyplot
from numpy import where
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# summarize class distribution
counter = Counter(y)
print(counter)
# transform the dataset
oversample = SMOTE()
X, y = oversample.fit_resample(X, y)
# summarize the new class distribution
counter = Counter(y)
print(counter)
# scatter plot of examples by class label
for label, _ in counter.items():
row_ix = where(y == label)[0]
pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()
运行该示例首先创建数据集并总结类分布,显示 1:100 的比率。
然后使用 SMOTE 对数据集进行转换,并总结出新的类分布,现在显示了一个平衡的分布,少数类中有 9900 个示例。
Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9900})
最后,创建转换数据集的散点图。
它显示了少数民族类中更多的例子,这些例子是在少数民族类中的原始例子之间创建的。
非平衡二分类问题的 SMOTE 变换散点图
关于 SMOTE 的原始论文建议将 SMOTE 与多数类的随机欠采样相结合。
不平衡学习库通过随机欠采样类支持随机欠采样。
我们可以更新示例,首先对少数类进行过采样,使其具有多数类示例数量的 10%(例如,大约 1,000 个),然后使用随机欠采样来减少多数类中的示例数量,使其比少数类多 50%(例如,大约 2,000 个)。
为了实现这一点,我们可以指定期望的比率作为 SMOTE 和随机欠采样类的参数;例如:
...
over = SMOTE(sampling_strategy=0.1)
under = RandomUnderSampler(sampling_strategy=0.5)
然后,我们可以将这两个变换链接在一起,形成一个管道。
然后,可以将管道应用于数据集,依次执行每个变换,并返回一个最终数据集,该数据集带有应用于该数据集的变换的累积,在这种情况下,先过采样,然后欠采样。
...
steps = [('o', over), ('u', under)]
pipeline = Pipeline(steps=steps)
然后,管道可以像单个转换一样适合并应用于我们的数据集:
...
# transform the dataset
X, y = pipeline.fit_resample(X, y)
然后,我们可以总结并绘制结果数据集。
我们希望对少数类进行一些 SMOTE 过采样,尽管没有以前数据集平衡时那么多。我们还预计,通过随机欠采样,多数类中的例子会更少。
将这些结合在一起,完整的示例如下所示。
# Oversample with SMOTE and random undersample for imbalanced dataset
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline
from matplotlib import pyplot
from numpy import where
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# summarize class distribution
counter = Counter(y)
print(counter)
# define pipeline
over = SMOTE(sampling_strategy=0.1)
under = RandomUnderSampler(sampling_strategy=0.5)
steps = [('o', over), ('u', under)]
pipeline = Pipeline(steps=steps)
# transform the dataset
X, y = pipeline.fit_resample(X, y)
# summarize the new class distribution
counter = Counter(y)
print(counter)
# scatter plot of examples by class label
for label, _ in counter.items():
row_ix = where(y == label)[0]
pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()
运行该示例首先创建数据集并总结类分布。
接下来,对数据集进行变换,首先对少数类进行过采样,然后对多数类进行欠采样。经过这一系列转换后的最终类分布与我们的预期相符,在多数类中有 1:2 的比例,即大约 2000 个示例,在少数类中有大约 1000 个示例。
Counter({0: 9900, 1: 100})
Counter({0: 1980, 1: 990})
最后,创建转换数据集的散点图,显示过采样的少数类和欠采样的多数类。
基于 SMOTE 和随机欠采样变换的不平衡数据集散点图
现在我们已经熟悉了不平衡数据集的转换,让我们看看在拟合和评估分类模型时使用 SMOTE。
分类标准
在本节中,我们将了解在 Sklearn 中拟合和评估机器学习算法时,如何使用 SMOTE 作为数据准备方法。
首先,我们使用上一节中的二进制类别数据集,然后拟合和评估决策树算法。
算法用任何需要的超参数定义(我们将使用默认值),然后我们将使用重复分层 k 倍交叉验证来评估模型。我们将使用 10 倍交叉验证的三次重复,这意味着 10 倍交叉验证被应用三次,以拟合和评估数据集上的 30 个模型。
数据集是分层的,这意味着交叉验证拆分的每个折叠都将具有与原始数据集相同的类分布,在本例中,比率为 1:100。我们将使用曲线下 ROC 面积(AUC)度量来评估模型。对于严重不平衡的数据集来说,这可能是乐观的,但对于表现更好的模型来说,这仍然会显示出相对的变化。
...
# define model
model = DecisionTreeClassifier()
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
一旦适合,我们可以计算和报告跨越折叠和重复的分数的平均值。
...
print('Mean ROC AUC: %.3f' % mean(scores))
我们不会期望适合原始不平衡数据集的决策树表现得很好。
将这些联系在一起,完整的示例如下所示。
# decision tree evaluated on imbalanced dataset
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.tree import DecisionTreeClassifier
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# define model
model = DecisionTreeClassifier()
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
print('Mean ROC AUC: %.3f' % mean(scores))
运行示例评估模型并报告平均 ROC AUC。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
在这种情况下,我们可以看到报告了大约 0.76 的 ROC AUC。
Mean ROC AUC: 0.761
现在,我们可以尝试相同的模型和相同的评估方法,尽管使用的是数据集的 SMOTE 转换版本。
在 k 倍交叉验证期间,过采样的正确应用是仅将该方法应用于训练数据集,然后在分层但未转换的测试集上评估模型。
这可以通过定义一个管道来实现,该管道首先用 SMOTE 转换训练数据集,然后拟合模型。
...
# define pipeline
steps = [('over', SMOTE()), ('model', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
然后可以使用重复的 k-fold 交叉验证来评估该管道。
将这些联系在一起,下面列出了在训练数据集上使用 SMOTE 过采样评估决策树的完整示例。
# decision tree evaluated on imbalanced dataset with SMOTE oversampling
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.tree import DecisionTreeClassifier
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# define pipeline
steps = [('over', SMOTE()), ('model', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(pipeline, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
print('Mean ROC AUC: %.3f' % mean(scores))
运行该示例评估模型,并报告多次折叠和重复的平均 ROC AUC 得分。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
在这种情况下,我们可以看到从大约 0.76 到大约 0.80 的 ROC AUC 在表现上的适度改善。
Mean ROC AUC: 0.809
正如论文中提到的,当与多数类的欠采样(如随机欠采样)结合使用时,SMOTE 的表现会更好。
我们可以通过简单地向管道添加一个随机欠采样步骤来实现这一点。
与上一节一样,我们将首先使用 SMOTE 对少数类进行过采样,使其达到约 1:10 的比例,然后对多数类进行欠采样,使其达到约 1:2 的比例。
...
# define pipeline
model = DecisionTreeClassifier()
over = SMOTE(sampling_strategy=0.1)
under = RandomUnderSampler(sampling_strategy=0.5)
steps = [('over', over), ('under', under), ('model', model)]
pipeline = Pipeline(steps=steps)
将这些联系在一起,完整的示例如下所示。
# decision tree on imbalanced dataset with SMOTE oversampling and random undersampling
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.tree import DecisionTreeClassifier
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# define pipeline
model = DecisionTreeClassifier()
over = SMOTE(sampling_strategy=0.1)
under = RandomUnderSampler(sampling_strategy=0.5)
steps = [('over', over), ('under', under), ('model', model)]
pipeline = Pipeline(steps=steps)
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(pipeline, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
print('Mean ROC AUC: %.3f' % mean(scores))
运行该示例使用训练数据集上的 SMOTE 过采样和随机欠采样管道来评估模型。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
在这种情况下,我们可以看到报告的 ROC AUC 显示额外的提升至约 0.83。
Mean ROC AUC: 0.834
您可以尝试测试少数族裔和多数族裔的不同比率(例如,更改 sampling_strategy 参数),看看是否有可能进一步提升表现。
另一个需要探索的领域是,在创建每个新的合成示例时,测试在 SMOTE 过程中选择的 k 近邻的不同值。默认值为 k=5 ,尽管较大或较小的值会影响创建的示例类型,进而可能影响模型的表现。
例如,我们可以网格搜索 k 的一系列值,例如从 1 到 7 的值,并为每个值评估管道。
...
# values to evaluate
k_values = [1, 2, 3, 4, 5, 6, 7]
for k in k_values:
# define pipeline
...
下面列出了完整的示例。
# grid search k value for SMOTE oversampling for imbalanced classification
from numpy import mean
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.tree import DecisionTreeClassifier
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# values to evaluate
k_values = [1, 2, 3, 4, 5, 6, 7]
for k in k_values:
# define pipeline
model = DecisionTreeClassifier()
over = SMOTE(sampling_strategy=0.1, k_neighbors=k)
under = RandomUnderSampler(sampling_strategy=0.5)
steps = [('over', over), ('under', under), ('model', model)]
pipeline = Pipeline(steps=steps)
# evaluate pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(pipeline, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
score = mean(scores)
print('> k=%d, Mean ROC AUC: %.3f' % (k, score))
运行该示例将对过程中使用的 KNN 使用不同的 k 值执行 SMOTE 过采样,然后随机欠采样,并在生成的训练数据集上拟合决策树。
报告了每种配置的平均 ROC AUC。
注:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
在这种情况下,结果表明 k=3 可能是好的,ROC AUC 约为 0.84, k=7 也可能是好的,ROC AUC 约为 0.85。
这突出显示了所执行的过采样和欠采样的数量(sampling_strategy 参数)以及从中选择合作伙伴来创建合成示例的示例数量( k_neighbors )可能是为数据集选择和调整的重要参数。
> k=1, Mean ROC AUC: 0.827
> k=2, Mean ROC AUC: 0.823
> k=3, Mean ROC AUC: 0.834
> k=4, Mean ROC AUC: 0.840
> k=5, Mean ROC AUC: 0.839
> k=6, Mean ROC AUC: 0.839
> k=7, Mean ROC AUC: 0.853
现在我们已经熟悉了如何在拟合和评估分类模型时使用 SMOTE,让我们看看 SMOTE 过程的一些扩展。
选择性合成样品生成
我们可以选择使用 SMOTE 过采样的少数民族样本。
在这一节中,我们将回顾 SMOTE 的一些扩展,这些扩展对来自少数类的例子更具选择性,为生成新的合成例子提供了基础。
边界线-SMOTE
SMOTE 的一个流行扩展包括选择那些被错误分类的少数类的实例,例如使用 k-最近邻分类模型。
然后,我们可以对这些困难的情况进行过采样,只在可能需要的地方提供更高的分辨率。
边界线上的例子和附近的例子比远离边界线的例子更容易被错误分类,因此对分类更重要。
——边界线-SMOTE:不平衡数据集学习中的一种新的过采样方法,2005。
这些被错误分类的例子可能是模糊的,并且在决策边界的边缘或边界的区域中,其中类成员可能重叠。因此,这种对 SMOTE 的修改被称为边界-SMOTE,是由韩晖等人在 2005 年发表的题为“边界-SMOTE:不平衡数据集学习中的一种新的过采样方法”的论文中提出的
作者还描述了该方法的一个版本,该版本还针对那些导致少数类中的临界实例的错误分类的示例对多数类进行了过采样。这被称为临界 SMOTE1,而对少数类中的临界情况的过采样被称为临界 SMOTE2。
边界线-smoth 2 不仅从 DANGER 中的每个示例及其在 P 中的正最近邻生成合成示例,还从其在 n 中的负最近邻生成合成示例
——边界线-SMOTE:不平衡数据集学习中的一种新的过采样方法,2005。
我们可以使用不平衡学习中的边界移动类来实现边界移动 1。
我们可以演示前面章节中使用的合成二分类问题的技巧。
我们不希望盲目地为少数类生成新的合成示例,而是希望边界-SMOTE 方法只沿着两个类之间的决策边界创建合成示例。
下面列出了使用边界扫描对二进制类别数据集进行过采样的完整示例。
# borderline-SMOTE for imbalanced dataset
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import BorderlineSMOTE
from matplotlib import pyplot
from numpy import where
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# summarize class distribution
counter = Counter(y)
print(counter)
# transform the dataset
oversample = BorderlineSMOTE()
X, y = oversample.fit_resample(X, y)
# summarize the new class distribution
counter = Counter(y)
print(counter)
# scatter plot of examples by class label
for label, _ in counter.items():
row_ix = where(y == label)[0]
pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()
运行该示例首先创建数据集并总结初始类分布,显示 1:100 的关系。
边界-SMOTE 应用于平衡班级分布,并通过打印的班级总结进行确认。
Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9900})
最后,创建转换数据集的散点图。该图清楚地显示了选择性过采样方法的效果。少数类决策边界上的示例被集中过采样(橙色)。
该图显示,远离决策边界的示例没有过采样。这包括更容易分类的例子(图左上方的橙色点)和考虑到强烈的类重叠而极难分类的例子(图右下方的橙色点)。
基于边界过采样的不平衡数据集散点图
边界线-SVM
Hien Nguyen 等人建议使用边界线-SMOTE 的替代方案,其中使用 SVM 算法而不是 KNN 算法来识别决策边界上的错误分类示例。
他们的方法总结在 2009 年的论文《不平衡数据分类的临界过采样》中 SVM 用于定位由支持向量和少数类中的示例定义的决策边界,该决策边界接近支持向量并成为生成合成示例的焦点。
……边界区域通过在原始训练集上训练标准 SVMs 分类器后获得的支持向量来近似。新的实例将沿着连接每一个少数类支持向量和它的一些最近邻居的线使用插值随机创建
——不平衡数据分类的临界过采样,2009。
除了使用 SVM,这种技术还试图选择少数民族较少的地区,并试图向阶级边界外推。
如果多数类实例的数量少于其最近邻居的一半,将使用外推法创建新实例,以将少数类区域向多数类扩展。
——不平衡数据分类的临界过采样,2009。
这种变化可以通过不平衡学习库中的 SVMSMOTE 类来实现。
下面的示例演示了在相同的不平衡数据集上使用边界线分割的替代方法。
# borderline-SMOTE with SVM for imbalanced dataset
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import SVMSMOTE
from matplotlib import pyplot
from numpy import where
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# summarize class distribution
counter = Counter(y)
print(counter)
# transform the dataset
oversample = SVMSMOTE()
X, y = oversample.fit_resample(X, y)
# summarize the new class distribution
counter = Counter(y)
print(counter)
# scatter plot of examples by class label
for label, _ in counter.items():
row_ix = where(y == label)[0]
pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()
运行该示例首先总结了原始的类分布,然后在使用 SVM 模型应用了边界线-SMOTE 之后总结了平衡的类分布。
Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9900})
创建数据集的散点图,显示沿决策边界和多数类的定向过采样。
我们还可以看到,与边界线-SMOTE 不同,更多的示例是在远离类重叠区域的地方合成的,例如在图的左上角。
利用 SVM 边界 SMOTE 过采样的不平衡数据集散点图
自适应合成采样
另一种方法是生成与少数民族样本密度成反比的合成样本。
也就是说,在少数示例密度低的特征空间区域中生成更多的合成示例,而在密度高的区域中生成更少的合成示例或不生成合成示例。
对 SMOTE 的这种修改被称为自适应综合采样方法,或 ADASN,并在何海波等人 2008 年的论文中被提出,该论文以名为“T2 ADASN:用于不平衡学习的自适应综合采样方法”的方法命名
ADASYN 基于根据少数类数据样本的分布自适应生成少数类数据样本的思想:与那些更容易学习的少数类样本相比,为更难学习的少数类样本生成更多的合成数据。
——ADASYN:不平衡学习的自适应综合采样方法,2008。
使用在线边界-SMOTE,不会创建区分模型。相反,少数类中的示例根据其密度进行加权,然后密度最低的那些示例是 SMOTE 合成示例生成过程的焦点。
ADASYN 算法的关键思想是使用密度分布作为标准,自动决定需要为每个少数数据示例生成的合成样本的数量。
——ADASYN:不平衡学习的自适应综合采样方法,2008。
我们可以使用不平衡学习库中的 ADASYN 类来实现这个过程。
下面的示例演示了在不平衡二进制类别数据集上进行过采样的替代方法。
# Oversample and plot imbalanced dataset with ADASYN
from collections import Counter
from sklearn.datasets import make_classification
from imblearn.over_sampling import ADASYN
from matplotlib import pyplot
from numpy import where
# define dataset
X, y = make_classification(n_samples=10000, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.99], flip_y=0, random_state=1)
# summarize class distribution
counter = Counter(y)
print(counter)
# transform the dataset
oversample = ADASYN()
X, y = oversample.fit_resample(X, y)
# summarize the new class distribution
counter = Counter(y)
print(counter)
# scatter plot of examples by class label
for label, _ in counter.items():
row_ix = where(y == label)[0]
pyplot.scatter(X[row_ix, 0], X[row_ix, 1], label=str(label))
pyplot.legend()
pyplot.show()
运行该示例首先创建数据集并总结初始类分布,然后在执行过采样后更新类分布。
Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9899})
创建转换数据集的散点图。像边界线-SMOTE 一样,我们可以看到合成样本生成集中在决策边界周围,因为该区域具有最低密度。
与边界线-SMOTE 不同,我们可以看到类重叠最多的示例具有最多的焦点。对于这些低密度示例可能是异常值的问题,ADASYN 方法可能会将过多的注意力放在特征空间的这些区域,这可能会导致更差的模型表现。
在应用过采样程序之前,去除异常值可能会有所帮助,这可能是一种更普遍使用的有益启发。
基于自适应合成采样的不平衡数据集散点图
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
书
- 从不平衡数据集中学习,2018。
- 不平衡学习:基础、算法和应用,2013。
报纸
- SMOTE:合成少数过采样技术,2002。
- 边界线-SMOTE:一种新的不平衡数据集学习的过采样方法,2005。
- 不平衡数据分类的临界过采样,2009。
- ADASYN:不平衡学习的自适应综合采样方法,2008。
应用程序接口
- imblearn.over_sampling。SMOTE API 。
- imblearn.over_sampling。SMOTENC API 。
- imblearn.over_sampling。边境移动应用编程接口。
- imblearn.over_sampling。SVMSMOTE API 。
- imblearn.over_sampling。ADASYN API 。
文章
摘要
在本教程中,您发现了用于过采样不平衡类别数据集的 SMOTE。
具体来说,您了解到:
- SMOTE 如何为少数民族阶层综合新的例子。
- 如何在 SMOTE 变换的训练数据集上正确拟合和评估机器学习模型。
- 如何使用 SMOTE 的扩展生成沿着类决策边界的合成例子。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。
不平衡分类的标准机器学习数据集
最后更新于 2021 年 1 月 5 日
不平衡分类问题是涉及预测类别标签的问题,其中类别标签在训练数据集中的分布是偏斜的。
许多真实世界的分类问题具有不平衡的类分布,因此机器学习从业者熟悉处理这些类型的问题是很重要的。
在本教程中,您将发现一套用于不平衡分类的标准机器学习数据集。
完成本教程后,您将知道:
- 两类不平衡的标准机器学习数据集。
- 具有倾斜类分布的多类分类标准数据集。
- 用于机器学习竞赛的流行不平衡类别数据集。
用我的新书Python 不平衡分类启动你的项目,包括分步教程和所有示例的 Python 源代码文件。
我们开始吧。
- 2021 年 1 月更新:更新了 API 文档的链接。
不平衡分类的标准机器学习数据集 图片由格雷姆·邱嘉德提供,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- 二元类别数据集
- 多类类别数据集
- 竞争和其他数据集
二元类别数据集
二分类预测建模问题是具有两类的问题。
典型地,不平衡二进制分类问题描述正常状态(类别 0)和异常状态(类别 1),例如欺诈、诊断或故障。
在本节中,我们将仔细研究三个具有类不平衡的标准二进制分类机器学习数据集。这些数据集足够小,可以放在内存中,并且已经被很好地研究过,为许多研究论文的调查提供了基础。
这些数据集的名称如下:
- 皮马印第安人糖尿病
- 哈贝曼乳腺癌(哈贝曼)
- 德国信贷(德语)
将加载每个数据集,并总结类不平衡的性质。
皮马印第安人糖尿病
每份记录都描述了女性的医疗细节,预测是未来五年内糖尿病的发作。
- 更多详情:皮马-印第安人-糖尿病。名称
- 数据集:pima-印度人-糖尿病. csv
下面提供了数据集前五行的示例。
6,148,72,35,0,33.6,0.627,50,1
1,85,66,29,0,26.6,0.351,31,0
8,183,64,0,0,23.3,0.672,32,1
1,89,66,23,94,28.1,0.167,21,0
0,137,40,35,168,43.1,2.288,33,1
...
下面的示例加载并总结了数据集的类细分。
# Summarize the Pima Indians Diabetes dataset
from numpy import unique
from pandas import read_csv
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv'
dataframe = read_csv(url, header=None)
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 768
N Inputs: 8
N Classes: 2
Classes: [0\. 1.]
Class Breakdown:
- Class 0.0: 500 (65.10417%)
- Class 1.0: 268 (34.89583%)
哈贝曼乳腺癌(哈贝曼)
每一份记录都描述了一个病人的医疗细节,预测是病人五年后是否存活。
- 更多详情:哈贝曼名称
- 数据集: haberman.csv
- 附加信息
下面提供了数据集前五行的示例。
30,64,1,1
30,62,3,1
30,65,0,1
31,59,2,1
31,65,4,1
...
下面的示例加载并总结了数据集的类细分。
# Summarize the Haberman Breast Cancer dataset
from numpy import unique
from pandas import read_csv
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv'
dataframe = read_csv(url, header=None)
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 306
N Inputs: 3
N Classes: 2
Classes: [1 2]
Class Breakdown:
- Class 1: 225 (73.52941%)
- Class 2: 81 (26.47059%)
德国信贷(德语)
每条记录都描述了一个人的财务细节,预测的是这个人是否是一个好的信用风险者。
下面提供了数据集前五行的示例。
A11,6,A34,A43,1169,A65,A75,4,A93,A101,4,A121,67,A143,A152,2,A173,1,A192,A201,1
A12,48,A32,A43,5951,A61,A73,2,A92,A101,2,A121,22,A143,A152,1,A173,1,A191,A201,2
A14,12,A34,A46,2096,A61,A74,2,A93,A101,3,A121,49,A143,A152,1,A172,2,A191,A201,1
A11,42,A32,A42,7882,A61,A74,2,A93,A103,4,A122,45,A143,A153,1,A173,2,A191,A201,1
A11,24,A33,A40,4870,A61,A73,3,A93,A101,4,A124,53,A143,A153,2,A173,2,A191,A201,2
...
下面的示例加载并总结了数据集的类细分。
# Summarize the German Credit dataset
from numpy import unique
from pandas import read_csv
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/german.csv'
dataframe = read_csv(url, header=None)
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 1000
N Inputs: 20
N Classes: 2
Classes: [1 2]
Class Breakdown:
- Class 1: 700 (70.00000%)
- Class 2: 300 (30.00000%)
多类类别数据集
多类分类预测建模问题是具有两个以上类的问题。
典型地,不平衡的多类分类问题描述了多个不同的事件,其中一些比另一些更常见。
在本节中,我们将仔细研究三个具有类不平衡的标准多类分类机器学习数据集。这些数据集足够小,可以放在内存中,并且已经被很好地研究过,为许多研究论文的调查提供了基础。
这些数据集的名称如下:
- 玻璃标识(玻璃)
- 大肠杆菌
- 甲状腺(甲状腺)
注:将所有多数类归入一类,留下最小的少数类,将不平衡多类分类问题转化为不平衡二类分类问题,在研究论文中比较常见。
将加载每个数据集,并总结类不平衡的性质。
玻璃标识(玻璃)
每条记录描述了玻璃的化学成分,预测涉及玻璃的类型。
- 更多详细信息:glass . name
- 数据集: glass.csv
- 附加信息
下面提供了数据集前五行的示例。
1.52101,13.64,4.49,1.10,71.78,0.06,8.75,0.00,0.00,1
1.51761,13.89,3.60,1.36,72.73,0.48,7.83,0.00,0.00,1
1.51618,13.53,3.55,1.54,72.99,0.39,7.78,0.00,0.00,1
1.51766,13.21,3.69,1.29,72.61,0.57,8.22,0.00,0.00,1
1.51742,13.27,3.62,1.24,73.08,0.55,8.07,0.00,0.00,1
...
第一列表示行标识符,可以删除。
下面的示例加载并总结了数据集的类细分。
# Summarize the Glass Identification dataset
from numpy import unique
from pandas import read_csv
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/glass.csv'
dataframe = read_csv(url, header=None)
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 214
N Inputs: 9
N Classes: 6
Classes: [1\. 2\. 3\. 5\. 6\. 7.]
Class Breakdown:
- Class 1.0: 70 (32.71028%)
- Class 2.0: 76 (35.51402%)
- Class 3.0: 17 (7.94393%)
- Class 5.0: 13 (6.07477%)
- Class 6.0: 9 (4.20561%)
- Class 7.0: 29 (13.55140%)
大肠杆菌
每条记录描述了不同测试的结果,预测涉及蛋白质定位位点的名称。
下面提供了数据集前五行的示例。
0.49,0.29,0.48,0.50,0.56,0.24,0.35,cp
0.07,0.40,0.48,0.50,0.54,0.35,0.44,cp
0.56,0.40,0.48,0.50,0.49,0.37,0.46,cp
0.59,0.49,0.48,0.50,0.52,0.45,0.36,cp
0.23,0.32,0.48,0.50,0.55,0.25,0.35,cp
...
第一列表示行标识符或名称,可以删除。
下面的示例加载并总结了数据集的类细分。
# Summarize the Ecoli dataset
from numpy import unique
from pandas import read_csv
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/ecoli.csv'
dataframe = read_csv(url, header=None)
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 336
N Inputs: 7
N Classes: 8
Classes: ['cp' 'im' 'imL' 'imS' 'imU' 'om' 'omL' 'pp']
Class Breakdown:
- Class cp: 143 (42.55952%)
- Class im: 77 (22.91667%)
- Class imL: 2 (0.59524%)
- Class imS: 2 (0.59524%)
- Class imU: 35 (10.41667%)
- Class om: 20 (5.95238%)
- Class omL: 5 (1.48810%)
- Class pp: 52 (15.47619%)
甲状腺(甲状腺)
每份记录都描述了不同甲状腺测试的结果,预测包括甲状腺的医学诊断。
下面提供了数据集前五行的示例。
107,10.1,2.2,0.9,2.7,1
113,9.9,3.1,2.0,5.9,1
127,12.9,2.4,1.4,0.6,1
109,5.3,1.6,1.4,1.5,1
105,7.3,1.5,1.5,-0.1,1
...
下面的示例加载并总结了数据集的类细分。
# Summarize the Thyroid Gland dataset
from numpy import unique
from pandas import read_csv
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/new-thyroid.csv'
dataframe = read_csv(url, header=None)
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 215
N Inputs: 5
N Classes: 3
Classes: [1\. 2\. 3.]
Class Breakdown:
- Class 1.0: 150 (69.76744%)
- Class 2.0: 35 (16.27907%)
- Class 3.0: 30 (13.95349%)
竞争和其他数据集
本节列出了研究论文中使用的其他数据集,这些数据集使用较少、较大或用作机器学习竞赛基础的数据集。
这些数据集的名称如下:
- 信用卡欺诈(信用)
- 波尔图塞古罗汽车保险索赔(波尔图塞古罗)
将加载每个数据集,并总结类不平衡的性质。
信用卡欺诈(信用)
每条记录都描述了一个信用卡翻译,它被归类为欺诈。
这些数据大约是 144 兆字节的未压缩数据或 66 兆字节的压缩数据。
下载数据集并将其解压缩到当前工作目录中。
下面提供了数据集前五行的示例。
"Time","V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17","V18","V19","V20","V21","V22","V23","V24","V25","V26","V27","V28","Amount","Class"
0,-1.3598071336738,-0.0727811733098497,2.53634673796914,1.37815522427443,-0.338320769942518,0.462387777762292,0.239598554061257,0.0986979012610507,0.363786969611213,0.0907941719789316,-0.551599533260813,-0.617800855762348,-0.991389847235408,-0.311169353699879,1.46817697209427,-0.470400525259478,0.207971241929242,0.0257905801985591,0.403992960255733,0.251412098239705,-0.018306777944153,0.277837575558899,-0.110473910188767,0.0669280749146731,0.128539358273528,-0.189114843888824,0.133558376740387,-0.0210530534538215,149.62,"0"
0,1.19185711131486,0.26615071205963,0.16648011335321,0.448154078460911,0.0600176492822243,-0.0823608088155687,-0.0788029833323113,0.0851016549148104,-0.255425128109186,-0.166974414004614,1.61272666105479,1.06523531137287,0.48909501589608,-0.143772296441519,0.635558093258208,0.463917041022171,-0.114804663102346,-0.183361270123994,-0.145783041325259,-0.0690831352230203,-0.225775248033138,-0.638671952771851,0.101288021253234,-0.339846475529127,0.167170404418143,0.125894532368176,-0.00898309914322813,0.0147241691924927,2.69,"0"
1,-1.35835406159823,-1.34016307473609,1.77320934263119,0.379779593034328,-0.503198133318193,1.80049938079263,0.791460956450422,0.247675786588991,-1.51465432260583,0.207642865216696,0.624501459424895,0.066083685268831,0.717292731410831,-0.165945922763554,2.34586494901581,-2.89008319444231,1.10996937869599,-0.121359313195888,-2.26185709530414,0.524979725224404,0.247998153469754,0.771679401917229,0.909412262347719,-0.689280956490685,-0.327641833735251,-0.139096571514147,-0.0553527940384261,-0.0597518405929204,378.66,"0"
1,-0.966271711572087,-0.185226008082898,1.79299333957872,-0.863291275036453,-0.0103088796030823,1.24720316752486,0.23760893977178,0.377435874652262,-1.38702406270197,-0.0549519224713749,-0.226487263835401,0.178228225877303,0.507756869957169,-0.28792374549456,-0.631418117709045,-1.0596472454325,-0.684092786345479,1.96577500349538,-1.2326219700892,-0.208037781160366,-0.108300452035545,0.00527359678253453,-0.190320518742841,-1.17557533186321,0.647376034602038,-0.221928844458407,0.0627228487293033,0.0614576285006353,123.5,"0"
...
下面的示例加载并总结了数据集的类细分。
# Summarize the Credit Card Fraud dataset
from numpy import unique
from pandas import read_csv
# load the dataset
dataframe = read_csv('creditcard.csv')
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 284807
N Inputs: 30
N Classes: 2
Classes: [0\. 1.]
Class Breakdown:
- Class 0.0: 284315 (99.82725%)
- Class 1.0: 492 (0.17275%)
波尔图塞古罗汽车保险索赔(波尔图塞古罗)
每条记录描述了人们的汽车保险细节,预测涉及到这个人是否会提出保险索赔。
这个数据大约压缩了 42 兆字节。
下载数据集并将其解压缩到当前工作目录中。
下面提供了数据集前五行的示例。
id,target,ps_ind_01,ps_ind_02_cat,ps_ind_03,ps_ind_04_cat,ps_ind_05_cat,ps_ind_06_bin,ps_ind_07_bin,ps_ind_08_bin,ps_ind_09_bin,ps_ind_10_bin,ps_ind_11_bin,ps_ind_12_bin,ps_ind_13_bin,ps_ind_14,ps_ind_15,ps_ind_16_bin,ps_ind_17_bin,ps_ind_18_bin,ps_reg_01,ps_reg_02,ps_reg_03,ps_car_01_cat,ps_car_02_cat,ps_car_03_cat,ps_car_04_cat,ps_car_05_cat,ps_car_06_cat,ps_car_07_cat,ps_car_08_cat,ps_car_09_cat,ps_car_10_cat,ps_car_11_cat,ps_car_11,ps_car_12,ps_car_13,ps_car_14,ps_car_15,ps_calc_01,ps_calc_02,ps_calc_03,ps_calc_04,ps_calc_05,ps_calc_06,ps_calc_07,ps_calc_08,ps_calc_09,ps_calc_10,ps_calc_11,ps_calc_12,ps_calc_13,ps_calc_14,ps_calc_15_bin,ps_calc_16_bin,ps_calc_17_bin,ps_calc_18_bin,ps_calc_19_bin,ps_calc_20_bin
7,0,2,2,5,1,0,0,1,0,0,0,0,0,0,0,11,0,1,0,0.7,0.2,0.7180703307999999,10,1,-1,0,1,4,1,0,0,1,12,2,0.4,0.8836789178,0.3708099244,3.6055512755000003,0.6,0.5,0.2,3,1,10,1,10,1,5,9,1,5,8,0,1,1,0,0,1
9,0,1,1,7,0,0,0,0,1,0,0,0,0,0,0,3,0,0,1,0.8,0.4,0.7660776723,11,1,-1,0,-1,11,1,1,2,1,19,3,0.316227766,0.6188165191,0.3887158345,2.4494897428,0.3,0.1,0.3,2,1,9,5,8,1,7,3,1,1,9,0,1,1,0,1,0
13,0,5,4,9,1,0,0,0,1,0,0,0,0,0,0,12,1,0,0,0.0,0.0,-1.0,7,1,-1,0,-1,14,1,1,2,1,60,1,0.316227766,0.6415857163,0.34727510710000004,3.3166247904,0.5,0.7,0.1,2,2,9,1,8,2,7,4,2,7,7,0,1,1,0,1,0
16,0,0,1,2,0,0,1,0,0,0,0,0,0,0,0,8,1,0,0,0.9,0.2,0.5809475019,7,1,0,0,1,11,1,1,3,1,104,1,0.3741657387,0.5429487899000001,0.2949576241,2.0,0.6,0.9,0.1,2,4,7,1,8,4,2,2,2,4,9,0,0,0,0,0,0
...
下面的示例加载并总结了数据集的类细分。
# Summarize the Porto Seguro’s Safe Driver Prediction dataset
from numpy import unique
from pandas import read_csv
# load the dataset
dataframe = read_csv('train.csv')
# get the values
values = dataframe.values
X, y = values[:, :-1], values[:, -1]
# gather details
n_rows = X.shape[0]
n_cols = X.shape[1]
classes = unique(y)
n_classes = len(classes)
# summarize
print('N Examples: %d' % n_rows)
print('N Inputs: %d' % n_cols)
print('N Classes: %d' % n_classes)
print('Classes: %s' % classes)
print('Class Breakdown:')
# class breakdown
breakdown = ''
for c in classes:
total = len(y[y == c])
ratio = (total / float(len(y))) * 100
print(' - Class %s: %d (%.5f%%)' % (str(c), total, ratio))
运行该示例提供了以下输出。
N Examples: 595212
N Inputs: 58
N Classes: 2
Classes: [0\. 1.]
Class Breakdown:
- Class 0.0: 503955 (84.66815%)
- Class 1.0: 91257 (15.33185%)
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
报纸
- 平衡机器学习训练数据的几种方法的行为研究,2004。
- 班级不平衡问题的集合研究综述:基于装袋、提升和混合的方法,2011。
文章
摘要
在本教程中,您发现了一套用于不平衡分类的标准机器学习数据集。
具体来说,您了解到:
- 两类不平衡的标准机器学习数据集。
- 具有倾斜类分布的多类分类标准数据集。
- 用于机器学习竞赛的流行不平衡类别数据集。
你有什么问题吗? 在下面的评论中提问,我会尽力回答。