使用 Python 进行 SMOTE 不平衡分类

使用 Python 进行 SMOTE 不平衡分类

  • 关注博主学习更多内容
  • 关注v xGZH:多目标优化与学习Lab

不平衡分类涉及针对类别严重不平衡的分类数据集开发预测模型。

使用不平衡数据集的挑战在于,大多数机器学习技术都会忽略少数类别,从而导致其性能较差,尽管通常情况下,少数类别的性能才是最重要的。

解决数据集不平衡的一种方法是对少数类别进行过采样。最简单的方法涉及在少数类中复制示例,尽管这些示例不会向模型添加任何新信息。相反,可以从现有示例中合成新示例。这是少数类别的一种数据增强,称为合成少数过采样技术,简称SMOTE 。

在本教程中,您将发现用于对不平衡分类数据集进行过采样的 SMOTE。

完成本教程后,您将了解:

  • SMOTE 如何为少数群体综合新的例子。
  • 如何在 SMOTE 转换的训练数据集上正确拟合和评估机器学习模型。
  • 如何使用 SMOTE 的扩展来沿着类决策边界生成综合示例。

教程概述

本教程分为五个部分;他们是:

  1. 合成少数过采样技术
  2. 不平衡学习库
  3. 用于平衡数据的 SMOTE
  4. SMOTE 分类
  5. 具有选择性合成样品生成功能的 SMOTE
    1. 边界-SMOTE
    2. 边界-SMOTE SVM
    3. 自适应合成采样 (ADASYN)

合成少数过采样技术

分类不平衡的一个问题是,少数类的例子太少,模型无法有效地学习决策边界。

解决这个问题的一种方法是对少数类中的示例进行过采样。这可以通过在拟合模型之前简单地复制训练数据集中少数类的示例来实现。这可以平衡类别分布,但不会向模型提供任何附加信息。

对少数类复制示例的改进是合成少数类的新示例。这是一种表格数据的数据增强,非常有效。

也许最广泛使用的合成新示例的方法称为合成少数过采样技术,简称 SMOTE。Nitesh Chawla等人描述了该技术。在他们 2002 年的论文中,该技术被命名为“ SMOTE:合成少数过采样技术”。

SMOTE 的工作原理是选择特征空间中接近的示例,在特征空间中的示例之间绘制一条线,然后在沿该线的某个点绘制新样本。

具体来说,首先从少数群体中随机选择一个例子。然后找到该示例的k个最近邻居(通常k=5)。选择随机选择的邻居,并在特征空间中两个示例之间的随机选择点处创建合成示例。

具体来说,首先从少数群体中随机选择一个例子。然后找到该示例的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 应用于不平衡的二元分类问题来培养对 SMOTE 的直觉。

首先,我们可以使用make_classification() scikit-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)

我们可以使用Counter 对象来汇总每个类中的示例数量,以确认数据集已正确创建。

# 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 的比例,在本例中,多数类中有大约 9,900 个示例,少数类中有 100 个示例。

Counter({0: 9900, 1: 100})

创建数据集的散点图,显示属于多数类(蓝色)的大量点和属于少数类(橙色)的少量点。我们可以看到两个类别之间存在一定程度的重叠。
在这里插入图片描述

不平衡二元分类问题的散点图
接下来,我们可以使用 SMOTE 对少数类进行过采样并绘制转换后的数据集。

我们可以在SMOTE 类中使用不平衡学习 Python 库提供的 SMOTE 实现。

SMOTE 类的作用类似于 scikit-learn 中的数据转换对象,因为它必须被定义和配置,适合数据集,然后应用于创建数据集的新转换版本。

例如,我们可以定义一个具有默认参数的 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 转换数据集并总结新的类分布,显示少数类中现在有 9,900 个示例的平衡分布。

Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9900})

最后,创建转换后的数据集的散点图。

它显示了少数群体类中沿着少数群体中的原始示例之间的路线创建的更多示例。
在这里插入图片描述

SMOTE转化的不平衡二元分类问题散点图
关于 SMOTE 的原始论文建议将 SMOTE 与多数类的随机欠采样相结合。

不平衡学习库通过RandomUnderSampler 类支持随机欠采样。

我们可以更新示例,首先对少数类进行过采样,使其比多数类的示例数量多 10%(例如,大约 1,000 个),然后使用随机欠采样来减少多数类中的示例数量,使其比多数类多 50%。少数群体(例如约2,000人)。

为了实现这一点,我们可以指定所需的比率作为 SMOTE 和RandomUnderSampler类的参数;例如:

over = SMOTE(sampling_strategy=0.1)
under = RandomUnderSampler(sampling_strategy=0.5)

然后我们可以将这两个转换链接在一起形成一个Pipeline。

然后可以将 Pipeline 应用于数据集,依次执行每个转换并返回最终数据集,其中应用了转换的累积,在本例中是过采样,然后是欠采样。

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,即多数类中有大约 2,000 个示例,少数类中有大约 1,000 个示例。

Counter({0: 9900, 1: 100})
Counter({0: 1980, 1: 990})

最后,创建转换后的数据集的散点图,显示过采样的少数类和欠采样的多数类。
在这里插入图片描述

SMOTE 和随机欠采样变换的不平衡数据集散点图
现在我们已经熟悉了不平衡数据集的转换,让我们看看在拟合和评估分类模型时如何使用 SMOTE。 ## SMOTE 分类 在本节中,我们将了解在 scikit-learn 中拟合和评估机器学习算法时如何使用 SMOTE 作为数据准备方法。

首先,我们使用上一节中的二元分类数据集,然后拟合并评估决策树算法。

该算法使用任何所需的超参数进行定义(我们将使用默认值),然后我们将使用重复分层k 倍交叉验证来评估模型。我们将使用 3 次重复的 10 倍交叉验证,这意味着 10 倍交叉验证应用了 3 次,在数据集上拟合和评估 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。
注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在本例中,我们可以看到报告的 ROC AUC 约为 0.76。

Mean ROC AUC: 0.761

现在,我们可以尝试相同的模型和相同的评估方法,尽管使用数据集的 SMOTE 转换版本。

在k倍交叉验证过程中过采样的正确应用是仅将该方法应用于训练数据集,然后在分层但未转换的测试集上评估模型。

这可以通过定义一个 Pipeline 来实现,该 Pipeline 首先使用 SMOTE 转换训练数据集,然后拟合模型。

...
# define pipeline
steps = [('over', SMOTE()), ('model', DecisionTreeClassifier())]
pipeline = Pipeline(steps=steps)

然后可以使用重复的 k 倍交叉验证来评估该管道。

将它们结合在一起,下面列出了在训练数据集上使用 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 分数。

注意:由于算法或评估过程的随机性或数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在这种情况下,我们可以看到性能略有改善,从 ROC AUC 约 0.76 提高到约 0.80。

Mean ROC AUC: 0.809

正如论文中提到的,相信 SMOTE 在与多数类的欠采样(例如随机欠采样)结合时表现更好。

我们可以通过简单地向管道添加RandomUnderSampler步骤来实现此目的。

与上一节一样,我们首先使用 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

您可以探索测试少数类和多数类的不同比例(例如更改抽样策略参数),看看是否可以进一步提升性能。

另一个需要探索的领域是在创建每个新的合成示例时测试 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

SMOTE 的一个流行扩展涉及选择那些被错误分类的少数类实例,例如使用 k 最近邻分类模型。

然后,我们可以仅对那些困难的实例进行过采样,仅在需要时提供更高的分辨率。

边界线上的例子和附近的例子[…]比远离边界线的例子更容易被错误分类,因此对于分类来说更重要。

— Borderline-SMOTE:不平衡数据集学习中的一种新的过采样方法,2005 年。

这些被错误分类的例子可能是不明确的,并且位于类成员可能重叠的决策边界的边缘或边界区域。因此,这种对SMOTE的修改称为Borderline-SMOTE,由Hui Han等人提出。在他们 2005 年题为“ Borderline-SMOTE:不平衡数据集学习中的一种新的过采样方法”的论文中。

作者还描述了该方法的一个版本,该方法还对那些导致少数类中的边界实例错误分类的示例对多数类进行了过采样。这称为 Borderline-SMOTE1,而仅对少数类别中的边界案例进行过采样称为 Borderline-SMOTE2。

Borderline-SMOTE2 不仅从 DANGER 中的每个示例及其 P 中的正最近邻生成合成示例,而且还从 N 中的最近负邻居生成合成示例。

— Borderline-SMOTE:不平衡数据集学习中的一种新的过采样方法,2005 年。

我们可以使用不平衡学习中的BorderlineSMOTE 类来实现 Borderline-SMOTE1 。

我们可以演示前面几节中使用的综合二元分类问题的技术。

我们期望 Borderline-SMOTE 方法只沿着两个类之间的决策边界创建合成示例,而不是盲目地为少数类生成新的合成示例。

下面列出了使用 Borderline-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 关系。

Borderline-SMOTE 用于平衡班级分布,这通过打印的班级摘要进行确认。

Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9900})

最后,创建转换后的数据集的散点图。该图清楚地显示了选择性过采样方法的效果。沿少数类决策边界的示例被有意地过采样(橙色)。

该图显示那些远离决策边界的示例没有被过采样。这包括更容易分类的示例(那些位于图左上方的橙色点)和那些由于类别重叠而极其难以分类的示例(那些位于图右下角的橙色点)。
在这里插入图片描述

具有边界 SMOTE 过采样的不平衡数据集的散点图

边界-SMOTE SVM

Hien Nguyen 等人。建议使用 Borderline-SMOTE 的替代方案,其中使用 SVM 算法而不是 KNN 来识别决策边界上错误分类的示例。

他们的方法在 2009 年题为“ Borderline Over-sampling For Imbalanced Data Classification ”的论文中进行了总结。SVM用于定位由支持向量定义的决策边界,并且少数类中靠近支持向量的示例成为生成合成示例的焦点。

…边界区域通过在原始训练集上训练标准 SVM 分类器后获得的支持向量来近似。新实例将沿着使用插值将每个少数类支持向量与其许多最近邻居连接的线随机创建

—不平衡数据分类的边界过采样,2009 年。

除了使用 SVM 之外,该技术还尝试选择少数类示例较少的区域,并尝试推断类边界。

如果多数类实例的数量少于其最近邻居的一半,则将通过外推创建新实例,以将少数类区域扩展到多数类。

—不平衡数据分类的边界过采样,2009 年。

这种变化可以通过不平衡学习库中的SVMSMOTE 类来实现。

下面的示例演示了在同一不平衡数据集上使用 Borderline SMOTE 的替代方法。

# 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 模型应用 Borderline-SMOTE 后的平衡类分布。

Counter({0: 9900, 1: 100})
Counter({0: 9900, 1: 9900})

创建数据集的散点图,显示沿决策边界与多数类的定向过采样。

我们还可以看到,与 Borderline-SMOTE 不同,更多的示例是在远离类重叠区域(例如图的左上角)合成的。

在这里插入图片描述

使用 SVM 进行边界 SMOTE 过采样的不平衡数据集的散点图

自适应合成采样 (ADASYN)

另一种方法涉及生成与少数类中示例的密度成反比的合成样本。

也就是说,在少数示例密度较低的特征空间区域中生成更多的合成示例,而在密度较高的区域中生成较少的合成示例或不生成。

这种对 SMOTE 的修改称为自适应合成采样方法 (ADASYN),由Haibo He等人提出。在他们 2008 年的论文中,该方法以“ ADASYN:用于不平衡学习的自适应合成采样方法”命名。

ADASYN 基于根据分布自适应生成少数数据样本的思想:与那些更容易学习的少数样本相比,为更难学习的少数类样本生成更多的合成数据。

— ADASYN:用于不平衡学习的自适应合成采样方法,2008 年。

使用在线 Borderline-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})

创建转换后的数据集的散点图。与 Borderline-SMOTE 一样,我们可以看到合成样本生成集中在决策边界周围,因为该区域的密度最低。

与 Borderline-SMOTE 不同,我们可以看到类重叠最多的示例最受关注。对于这些低密度示例可能属于异常值的问题,ADASYN 方法可能会过多关注特征空间的这些区域,这可能会导致模型性能较差。

在应用过采样过程之前,它可能有助于消除异常值,并且这可能是更普遍使用的有用启发式方法。
在这里插入图片描述

使用自适应合成采样 (ADASYN) 的不平衡数据集散点图

文章来源:SMOTE for Imbalanced Classification with Python

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值