使用 Python 进行不平衡分类的 SMOTE

不平衡分类是指在具有严重类别不平衡的分类数据集上开发预测模型。

处理不平衡数据集的挑战在于,大多数机器学习技术会忽略少数类别,进而导致在少数类别上的性能不佳,尽管通常最重要的是少数类别上的性能。

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

在本教程中,您将了解用于不平衡分类数据集过采样的 SMOTE。

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

  • SMOTE 如何为少数类别合成新样本。
  • 如何正确拟合和评估在 SMOTE 转换的训练数据集上的机器学习模型。
  • 如何使用 SMOTE 的扩展,在类别决策边界生成合成样本。

通过我的新书《使用 Python 进行不平衡分类启动您的项目,其中包括分步教程和所有示例的 Python 源代码文件。

让我们开始吧。

  • 2021 年 1 月更新:更新了 API 文档链接。
SMOTE Oversampling for Imbalanced Classification with Python

使用 Python 进行不平衡分类的 SMOTE 过采样
照片由Victor U 提供,保留部分权利。

教程概述

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

  1. 合成少数过采样技术
  2. Imbalanced-Learn 库
  3. 用于平衡数据的 SMOTE
  4. 用于分类的 SMOTE
  5. 具有选择性合成样本生成的 SMOTE
    1. 边界 SMOTE
    2. 边界 SMOTE 支持向量机
    3. 自适应合成采样 (ADASYN)

合成少数过采样技术

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

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

对复制少数类别样本的改进是从少数类别中合成新样本。这是一种表格数据的数据增强,可以非常有效。

也许最广泛使用的合成新样本的方法是合成少数过采样技术,简称 SMOTE。该技术由 Nitesh Chawla 等人在其 2002 年发表的题为“SMOTE:合成少数过采样技术”的论文中描述。

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

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

... SMOTE 首先随机选择一个少数类实例 a,并找到其 k 个最近的少数类邻居。然后通过随机选择 k 个最近邻居 b 中的一个,并将 a 和 b 连接起来在特征空间中形成一个线段来创建合成实例。合成实例是两个选定实例 a 和 b 的凸组合生成的。

— 第 47 页,《不平衡学习:基础、算法和应用》,2013 年。

此过程可用于为少数类别创建所需数量的合成样本。如论文中所述,它建议首先使用随机欠采样来减少多数类别中的样本数量,然后使用 SMOTE 对少数类别进行过采样以平衡类别分布。

SMOTE 和欠采样的组合比单纯的欠采样表现更好。

— 《SMOTE:合成少数过采样技术》,2011 年。

这种方法是有效的,因为从少数类别创建的新合成样本是合理的,也就是说,它们在特征空间中与少数类别中的现有样本相对接近。

我们的合成过采样方法旨在使分类器构建更大的决策区域,其中包含附近的少数类点。

— 《SMOTE:合成少数过采样技术》,2011 年。

该方法的一个普遍缺点是,合成样本的创建没有考虑多数类别,如果类别之间存在强烈重叠,可能会导致模糊样本。

现在我们熟悉了这项技术,让我们来看一个不平衡分类问题的实际示例。

Imbalanced-Learn 库

在这些示例中,我们将使用 imbalanced-learn Python 库提供的实现,该库可以通过 pip 安装,如下所示:

您可以通过打印已安装库的版本来确认安装成功。

运行示例将打印已安装库的版本号;例如

想要开始学习不平衡分类吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

用于平衡数据的 SMOTE

在本节中,我们将通过将其应用于不平衡的二元分类问题来培养对 SMOTE 的直觉。

首先,我们可以使用 make_classification() scikit-learn 函数创建一个包含 10,000 个样本和 1:100 类分布的合成二元分类数据集。

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

最后,我们可以创建一个数据集的散点图,并为每个类别的样本着色不同的颜色,以清楚地看到类不平衡的空间性质。

综上所述,生成和绘制合成二元分类问题的完整示例如下。

运行示例首先总结了类别分布,确认了 1:100 的比例,在本例中,多数类别大约有 9,900 个样本,少数类别有 100 个样本。

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

Scatter Plot of Imbalanced Binary Classification Problem

不平衡二元分类问题的散点图

接下来,我们可以使用 SMOTE 对少数类别进行过采样,并绘制转换后的数据集。

我们可以使用 imbalanced-learn Python 库中 SMOTE 类提供的 SMOTE 实现。

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

例如,我们可以定义一个具有默认参数的 SMOTE 实例,该实例将平衡少数类别,然后一步拟合并应用它来创建数据集的转换版本。

一旦转换,我们可以总结新转换数据集的类别分布,通过在少数类别中创建许多新的合成样本,预期现在会变得平衡。

还可以创建转换后数据集的散点图,我们期望在少数类别中原始样本之间的线上看到更多的少数类别样本。

综上所述,将 SMOTE 应用于合成数据集,然后总结并绘制转换结果的完整示例如下。

运行示例首先创建数据集并总结类别分布,显示 1:100 的比例。

然后使用 SMOTE 对数据集进行转换,并总结新的类别分布,显示现在是平衡分布,少数类别中有 9,900 个样本。

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

它显示在少数类别中的原始样本之间的线上创建了更多的少数类别样本。

Scatter Plot of Imbalanced Binary Classification Problem Transformed by SMOTE

经 SMOTE 转换的不平衡二元分类问题的散点图

SMOTE 的原始论文建议将 SMOTE 与多数类别的随机欠采样相结合。

imbalanced-learn 库通过 RandomUnderSampler 类支持随机欠采样。

我们可以更新示例,首先对少数类别进行过采样,使其样本数量达到多数类别的 10%(例如约 1,000 个),然后使用随机欠采样将多数类别中的样本数量减少到少数类别的 50% 以上(例如约 2,000 个)。

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

然后我们可以将这两个转换串联成一个 Pipeline

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

然后,管道可以像单个转换一样拟合和应用于我们的数据集

然后我们可以总结并绘制生成的数据集。

我们预计少数类别会进行一些 SMOTE 过采样,尽管不如之前数据集平衡时那么多。我们还预计通过随机欠采样,多数类别中的样本会更少。

将所有这些结合起来,完整的示例如下所示。

运行示例首先创建数据集并总结类别分布。

接下来,数据集被转换,首先是对少数类别进行过采样,然后是对多数类别进行欠采样。这一系列转换之后的最终类别分布符合我们的预期,比例为 1:2,即多数类别约有 2,000 个样本,少数类别约有 1,000 个样本。

最后,创建了转换后数据集的散点图,显示了过采样的少数类别和欠采样的多数类别。

Scatter Plot of Imbalanced Dataset Transformed by SMOTE and Random Undersampling

通过 SMOTE 和随机欠采样转换的不平衡数据集的散点图

现在我们熟悉了如何转换不平衡数据集,让我们看看在使用 SMOTE 拟合和评估分类模型时。

用于分类的 SMOTE

在本节中,我们将探讨如何在 scikit-learn 中拟合和评估机器学习算法时,将 SMOTE 作为数据准备方法。

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

算法定义了所有必需的超参数(我们将使用默认值),然后我们将使用重复分层 k 折交叉验证来评估模型。我们将使用 3 次重复的 10 折交叉验证,这意味着 10 折交叉验证应用 3 次,在数据集上拟合和评估 30 个模型。

数据集是分层的,这意味着交叉验证分割的每个折叠将具有与原始数据集相同的类别分布,在本例中为 1:100 的比例。我们将使用 ROC 曲线下面积 (AUC) 指标来评估模型。这对于严重不平衡的数据集可能过于乐观,但仍会显示性能更好的模型的相对变化。

一旦拟合,我们可以计算并报告跨折叠和重复的得分平均值。

我们不期望在原始不平衡数据集上拟合的决策树表现非常好。

将这些结合起来,完整的示例列在下面。

运行示例会评估模型并报告平均 ROC AUC。

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

在这种情况下,我们可以看到报告的 ROC AUC 约为 0.76。

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

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

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

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

综上所述,在训练数据集上使用 SMOTE 过采样评估决策树的完整示例如下。

运行示例会评估模型并报告跨多个折叠和重复的平均 ROC AUC 分数。

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

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

如论文所述,据信 SMOTE 与多数类别的欠采样(例如随机欠采样)结合使用时表现更好。

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

与上一节中一样,我们将首先使用 SMOTE 对少数类别进行过采样,使其达到约 1:10 的比例,然后对多数类别进行欠采样,使其达到约 1:2 的比例。

将这些结合起来,完整的示例列在下面。

运行示例会使用 SMOTE 过采样和训练数据集上的随机欠采样的管道来评估模型。

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

在这种情况下,我们可以看到报告的 ROC AUC 再次提升到约 0.83。

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

另一个可以探索的领域是测试 SMOTE 过程中选择的 k 最近邻的不同值,当创建每个新的合成样本时。默认值为 k=5,但更大或更小的值会影响创建的样本类型,进而可能会影响模型的性能。

例如,我们可以网格搜索一系列 k 值,例如 1 到 7,并评估每个值的管道。

完整的示例如下所示。

运行示例将使用 KNN 中不同的 k 值进行 SMOTE 过采样,然后进行随机欠采样,并在生成的训练数据集上拟合决策树。

报告了每种配置的平均 ROC AUC。

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

在这种情况下,结果表明 k=3 可能不错,ROC AUC 约为 0.84,而 k=7 也可能不错,ROC AUC 约为 0.85。

这突出表明,执行过采样和欠采样的数量(sampling_strategy 参数)以及从其中选择伙伴以创建合成样本的样本数量(k_neighbors)可能是您数据集中要选择和调整的重要参数。

现在我们熟悉了如何在拟合和评估分类模型时使用 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 年。

我们可以使用 imbalanced-learn 中的 BorderlineSMOTE 类实现 Borderline-SMOTE1。

我们可以在前几节中使用的合成二元分类问题上演示该技术。

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

使用 Borderline-SMOTE 对二元分类数据集进行过采样的完整示例如下。

运行示例首先创建数据集并总结初始类别分布,显示 1:100 的关系。

应用 Borderline-SMOTE 以平衡类别分布,并通过打印的类别摘要进行确认。

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

该图显示,那些远离决策边界的样本未被过采样。这包括易于分类的样本(图中左上方那些橙色点)和由于强类别重叠而极难分类的样本(图中右下方那些橙色点)。

Scatter Plot of Imbalanced Dataset With Borderline-SMOTE Oversampling

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

边界 SMOTE 支持向量机

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

他们的研究总结在 2009 年的论文“不平衡数据分类的边界过采样”中。SVM 用于定位由支持向量定义的决策边界,少数类别中靠近支持向量的样本成为生成合成样本的焦点。

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

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

除了使用 SVM,该技术还尝试选择少数类样本较少的区域,并试图向类边界外推。

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

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

这种变体可以通过 imbalanced-learn 库中的 SVMSMOTE 类实现。

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

运行示例首先总结原始类别分布,然后是应用带 SVM 模型的 Borderline-SMOTE 后的平衡类别分布。

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

我们还可以看到,与 Borderline-SMOTE 不同,更多的样本是远离类别重叠区域合成的,例如朝向图的左上方。

Scatter Plot of Imbalanced Dataset With Borderline-SMOTE Oversampling With SVM

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

自适应合成采样 (ADASYN)

另一种方法是生成与少数类别中样本密度成反比的合成样本。

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

这种对 SMOTE 的修改被称为自适应合成采样方法,或 ADASYN,由 Haibo He 等人在其 2008 年发表的题为“ADASYN:不平衡学习的自适应合成采样方法”的论文中提出。

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

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

使用在线 Borderline-SMOTE,不会创建判别模型。相反,少数类别中的样本根据其密度加权,然后密度最低的样本成为 SMOTE 合成样本生成过程的焦点。

ADASYN 算法的核心思想是使用密度分布作为标准,自动决定为每个少数数据样本生成多少合成样本。

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

我们可以使用 imbalanced-learn 库中的 ADASYN 类实现此过程。

以下示例演示了在不平衡二元分类数据集上进行过采样的这种替代方法。

运行示例首先创建数据集并总结初始类别分布,然后总结执行过采样后的更新类别分布。

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

与 Borderline-SMOTE 不同,我们可以看到类别重叠最多的样本得到了最多的关注。在这些低密度样本可能是异常值的问题上,ADASYN 方法可能会过分关注这些特征空间区域,这可能导致模型性能更差。

在应用过采样过程之前删除异常值可能会有所帮助,这可能是一个更普遍有用的启发式方法。

Scatter Plot of Imbalanced Dataset With Adaptive Synthetic Sampling (ADASYN)

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

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

书籍

论文

API

文章

总结

在本教程中,您学习了用于不平衡分类数据集过采样的 SMOTE。

具体来说,你学到了:

  • SMOTE 如何为少数类别合成新样本。
  • 如何正确拟合和评估在 SMOTE 转换的训练数据集上的机器学习模型。
  • 如何使用 SMOTE 的扩展,在类别决策边界生成合成样本。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

掌控不平衡分类!

Imbalanced Classification with Python

在几分钟内开发不平衡学习模型

...只需几行python代码

在我的新电子书中探索如何实现
使用 Python 处理不平衡分类问题

它提供了关于以下内容的自学教程端到端项目
性能指标欠采样方法SMOTE阈值移动概率校准成本敏感算法
以及更多...

将不平衡分类方法引入您的机器学习项目

查看内容

使用 Python 进行不平衡分类的 SMOTE 的 321 条回复

  1. Markus 2020 年 1 月 17 日,晚上 10:52 #

    print(‘平均 ROC AUC:%.3f’ % scores 的平均值)

    在计算 ROC AUC 时,示例使用的是 mean 函数而不是 roc_auc_score,为什么?

    谢谢

    • Jason Brownlee 2020 年 1 月 18 日,上午 8:48 #

      ROC AUC 分数是通过 scikit-learn 中的交叉验证过程自动计算的。

      • Ram pratapa 2020 年 4 月 1 日,下午 6:13 #

        嗨,Jason,
        有没有办法将 smote 用于多标签问题。

        • Jason Brownlee 2020 年 4 月 2 日,上午 5:44 #

          是的,您必须向 smote 配置指定哪些是正/负类以及要对它们进行多少过采样。

          • Emily 2022 年 1 月 28 日,下午 5:33 #

            您好!我的数据集中有 4 个类别(无 (2552)、感染 (2555)、缺血 (227)、两者皆有 (621))。我如何将此技术应用于我的数据集?

          • James Carmichael 2022 年 1 月 31 日,上午 11:07 #

            你好艾米丽……希望以下内容能提供更多清晰信息

            https://machinelearning.org.cn/multi-class-imbalanced-classification/

  2. Camara Mamadou 2020 年 1 月 21 日,凌晨 12:52 #

    嗨,Jason,

    感谢分享机器学习知识。

    在通过 SMOTE 过采样获得分类器的最佳结果后,如何获得保留数据测试的预测?

    此致!

    Mamadou。

    • Jason Brownlee 2020 年 1 月 21 日,上午 7:15 #

      像往常一样调用 model.predict()。

      请记住,SMOTE 仅在模型拟合时应用于训练集。

      • Akil 2020 年 2 月 20 日,晚上 11:47 #

        嗨,Jason,

        如您所说,SMOTE 仅应用于训练,这不会影响测试集的准确性吗?

        • Jason Brownlee 2020 年 2 月 21 日,上午 8:23 #

          是的,模型将更好地了解边界并在测试集上表现更好——至少在某些数据集上是这样。

          • Akshay 2020 年 10 月 16 日,上午 5:17 #

            只是一个澄清问题:根据 Akil 上面提到的,以及下面的代码,我试图理解如果模型在管道中定义,SMOTE 是否没有应用于验证数据(在 CV 期间),以及如果我使用 oversampke.fit_resample(X, y),它是否甚至应用于验证数据。我想确保它按预期工作。

            我发现当我在使用和不使用管道的情况下运行 SMOTE 时,准确性差异很大。

            # 定义流水线
            步骤 = [(‘over’, SMOTE()), (‘model’, DecisionTreeClassifier())]
            管道 = Pipeline(steps=steps)
            # 评估流水线
            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(‘平均 ROC AUC:%.3f’ % scores 的平均值)

          • Jason Brownlee 2020 年 10 月 16 日,上午 5:58 #

            SMOTE 仅应用于训练集,即使在管道中使用,即使通过交叉验证进行评估也是如此。

          • Akshay 2020 年 10 月 17 日,凌晨 12:27 #

            有道理!正如我们的评论者所说,即使在我的案例中,训练和验证的准确度指标也很接近,但测试集却下降了 7-8%。如何提高测试集的性能(抱歉再问一遍)?

            附言
            为了再次明确,在我的案例中——3 类问题
            我将 X_train 定义为用于拟合和评估模型技能的数据。在幕后发生的是 5 折交叉验证,这意味着 X_train 再次以 80:20 的比例拆分五次,其中 20% 的数据集未应用 SMOTE。这是我的理解。

          • Keith Bourne 2022 年 7 月 29 日,下午 3:47 #

            您在不同的地方多次说过类似“SMOTE 仅应用于训练集,即使在管道中使用,即使通过交叉验证进行评估也是如此。”

            但是你的代码
            步骤 = [(‘over’, SMOTE()), (‘model’, DecisionTreeClassifier())]
            管道 = Pipeline(steps=steps)
            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)

            据我所见,以及我看到其他人评论的,X 和 y 被输入到管道中并按原样进行交叉验证。在此示例中,在应用管道之前没有分解训练和测试。并且您的 X 和 y 通过过采样数据进行交叉验证——所以每个折叠都将过采样数据用于训练和测试。因此,即使您说您应该只将其应用于训练数据,您的模型正在使用应用于所有数据的 SMOTE 进行优化,这将夸大您的度量结果。这当然是人们所指出的在他们的结果中发生的情况,并且他们的测试结果显着降低。我的理解是,您将需要切割到每个折叠中,并且只将 SMOTE 应用于折叠内的训练数据,我在这里没有看到这样做。

            此外,您使用 ROC AUC 作为不平衡分类的优化指标。这不是理想的,最好使用专注于正类别的指标,例如精确召回曲线 AUC,或 average_precision。

          • James Carmichael 2022 年 7 月 30 日,上午 10:06 #

            感谢您的反馈 Keith!您的建议在实践中表现如何?

  3. Rafael Eder 2020 年 1 月 21 日,下午 3:17 #

    你好!
    SMOTE 也适用于不平衡图像数据集吗?

    此致;

    • Jason Brownlee 2020 年 1 月 22 日,上午 6:17 #

      不,它是为表格数据设计的。

      您可能能够以相同的方式使用图像增强。

      • Rafael Eder 2020 年 1 月 22 日,上午 10:07 #

        您的书籍和博客对我帮助很大!非常感谢!

      • zaidi 2021 年 7 月 8 日,下午 4:23 #

        你好,我为我的不平衡图像数据集使用了图像增强,但某些类的结果仍然很低,这会影响我的模型性能。另外,您必须知道我将它用于所有数据,我的意思是,我没有指定图像较少的类,我将它应用于所有数据。你能帮我解决这个问题吗?非常感谢

  4. brian 2020 年 1 月 31 日,凌晨 12:28 #

    你好 Jason,感谢你又一个精彩的教程系列。我在运行

    X, y = pipeline.fit_resample(X, y)

    在我自己的 X 和 y 不平衡数据上时遇到了一个错误。错误是

    “ValueError: The specified ratio required to remove samples from the minority class while trying to generate new samples. Please increase the ratio.”

    来自 imblearn/utils 中 _validation.py” 的第 362 行,在 _sampling_strategy_float 中。

    您或其他人能解释一下这个错误吗?

    谢谢。

    • brian 2020 年 1 月 31 日,凌晨 1:50 #

      后续,我似乎没有理解 SMOTE 和欠采样是如何运作的。

      我的输入数据大小是

      {0: 23558, 1: 8466}

      所以少数类:多数类示例的比例略低于 1:3

      现在我明白我之前 SMOTE() 和 RandomUnderSampler() 的“sampling_strategy”比例设置不正确。

      继续前进!

      • Jason Brownlee 2020 年 1 月 31 日,上午 7:57 #

        很高兴听到,干得好!

      • Volkan Yurtseven 2020 年 7 月 22 日,上午 7:32 #


        与 gridsearchcv 结合使用时,Smote 是对整个训练集进行过采样还是忽略验证集?

        • Jason Brownlee 2020 年 7 月 22 日,上午 7:38 #

          您可以将其作为管道的一部分使用,以确保 SMOTE 仅应用于训练数据集,而不是 val 或测试。

          • Kevin 2020 年 11 月 28 日,下午 6:17 #

            嗨,Jason,

            好博客!SMOTE 的变体深入探讨得很好。我想知道

            为什么您首先使用 SMOTE 进行过采样,然后才在您的管道中对多数类别进行欠采样?反过来会不会更有效?

          • Jason Brownlee 2020 年 11 月 29 日,上午 8:09 #

            谢谢!

            这是一种对我来说效果很好的方法。也许您可以在自己的数据集上尝试反向操作并比较结果。

          • April 2021 年 1 月 26 日,下午 3:59 #

            嗨,Jason,

            我几天来一直在仔细阅读您关于不平衡分类的非常有帮助的文章。感谢您为机器学习社区提供了如此宝贵的知识!

            我有一个关于仅将 SMOTE 应用于训练集所产生的后果的问题。如果我们将 SMOTE 仅应用于训练集而不应用于验证集或测试集,那么这三个集合将不会分层。例如,如果训练集转换为类别 1 和类别 2 的 50:50 分布,验证集和测试集仍然保持其原始分布 10:90,假设如此。这根本不是一个问题,因为我们只关心构建最高性能的模型,该模型将仅基于训练集?如果我们仅将 SMOTE 应用于训练集,模型是否也会假设实际数据也假设类别 1 和类别 2 之间存在 50:50 的分布?

            提前感谢您的帮助!

          • Jason Brownlee 2021 年 1 月 27 日,上午 6:03 #

            感谢您的支持!

            不,您应该在重采样之前对数据进行分层分割。然后使用一种(非准确率)指标,有效评估自然数据(验证集和测试集)的能力。

            这至关重要。改变测试集和验证集的性质将使测试工具无效。

    • Jason Brownlee 2020 年 1 月 31 日,上午 7:55 #

      确认您在 y 中同时拥有两个类别的样本。

    • Jeong miae 2020 年 3 月 21 日,上午 10:56 #

      感谢您的教程。
      我想问几个问题。

      1. 我可以将这种采样技术应用于图像数据吗?

      2. 在使用这些技术制作平衡数据后,我可以使用深度学习算法(例如 CNN)而不是机器学习算法吗?

  5. Valdemar 2020年2月11日上午2:06 #

    你好 Jason,

    在你的机器学习备忘录中,你建议如果数据不够就创造更多数据。你能推荐一些适合这样做的方法或库吗?

    Imblearn似乎是平衡数据的好方法。如果想增加整个数据集的大小以获得更多样本并可能改善模型,该怎么办?

  6. Frank 2020年2月28日下午11:41 #

    感谢这篇精彩的教程,一如既往地超级详细且有帮助。

    我正在处理葡萄酒质量数据集(白葡萄酒),并决定在输出特征平衡如下的情况下使用SMOTE。

    {6: 2198, 5: 1457, 7: 880, 8: 175, 4: 163, 3: 20, 9: 5}

    您认为在这种多类别问题中是否可以使用SMOTE?

    我设法使用了一个回归模型(KNN),我认为它很好地完成了任务,但很想听听您对如何处理上述多类别问题中类似类别不平衡的看法?

    • Jason Brownlee 2020年2月29日上午7:13 #

      是的,SMOTE 可以用于多类别问题,但您必须指定正类别和负类别。

  7. Thomas 2020年3月1日上午6:33 #

    谢谢分享,Jason。
    在imblearn.pipeline中,predict方法说它应用了转换和采样,然后是估计器的最终预测。

    因此,在交叉验证分数中,采样会应用于每个验证集,这不是一个问题吗?

    谢谢

    • Jason Brownlee 2020年3月2日上午6:07 #

      抱歉,我不明白你的问题。你能重述或详细说明一下吗?

      • Matthew 2021年12月5日上午12:57 #

        我认为您对边界SMOTE1和SMOTE2的描述不正确?据我所知,SMOTE1在主要正样本和一些正NN之间生成合成样本,SMOTE2也在主要正样本和一些负NN之间生成合成样本(其中合成样本更接近主要正样本)。因此,不会生成负样本。

        如果我错了,请原谅,我喜欢您的内容。

        • Adrian Tam
          Adrian Tam 2021年12月8日上午7:29 #

          该描述引自ICIC2005论文。

  8. Yong 2020年3月1日下午6:19 #

    您提到:“与上一节一样,我们首先使用SMOTE将少数类过采样到约1:10的比例,然后对多数类进行欠采样以达到约1:2的比例。”
    为什么?这种操作背后的想法是什么,以及为什么这种操作可以提高性能。

    • Jason Brownlee 2020年3月2日上午6:16 #

      这种方法可能很有效。重要的是在您的数据集上尝试一系列方法,看看哪种方法效果最好。

  9. Vijay M 2020年3月2日下午8:37 #

    杰森先生,
    我们可以将以上代码用于图像吗?

  10. Ernest Montañà 2020年3月18日上午3:40 #

    你好 Jason,感谢你的教程。

    使用以下代码行时

    # 定义流水线
    steps = [(‘over’, SMOTE()), (‘model’, RandomForestClassifier(n_estimators=100, criterion=’gini’, max_depth=None, random_state=1))]
    管道 = Pipeline(steps=steps)
    # 评估流水线
    cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=2, random_state=1)
    acc = cross_val_score(pipeline, X_new, Y, scoring=’accuracy’, cv=cv, n_jobs=-1)

    我假设SMOTE是在每次交叉验证分割时执行的,因此没有数据泄漏,我的理解对吗?谢谢。

    • Jason Brownlee 2020年3月18日上午6:13 #

      没错。这就是我们使用管道的原因。

      • AP 2021年2月19日上午1:59 #

        你好 Jason,
        感谢您的帖子。我有一些问题。我的数据集中包含 NaN 值,但由于记录数量较少,我不允许删除它们。如果在数据分割或交叉验证之前用均值或中位数填充值,则会出现信息泄漏。为了解决这个问题,我需要使用包含 SMOT 和模型的管道,并且需要应用交叉验证。现在,我的问题是,如果我有一个巨大的数据集,并且我想应用特征工程(PCA 或 RFE)并希望逐步探索所有步骤,该怎么办?如果我在管道中定义每个步骤,我如何探索哪个方法存在真正的问题?此外,我需要在大型数据集上进行试错方法时需要更多的计算能力。您对此有什么建议?

        我的第二个问题是,我不理解您最初定义的 SMOT。
        “SMOTE 首先随机选择一个少数类实例 a,并找到其 k 个最近的少数类邻居。然后通过随机选择 k 个最近邻居 b 中的一个,并将 a 和 b 连接起来在特征空间中形成一条线段来创建合成实例。合成实例是作为两个选定实例 a 和 b 的凸组合生成的。”
        我无法想象您想说什么。因此,我也不理解边界 SMOT。您能重新措辞并尽可能用一个小例子解释一下吗?

        先谢谢您了。

        • Jason Brownlee 2021年2月19日上午6:04 #

          您必须在训练集上拟合插补器,并在交叉验证中将其应用于训练集和测试集,管道会有所帮助。

          您也可以手动逐步进行 k 折交叉验证并手动实现管道——这可能对您来说更好,因为您可以跟踪所做的更改以及可能发生的任何问题。

          SMOTE 的工作原理是在特征空间中相近的示例之间画线,并选择线上一个随机点作为新实例。

          希望这能有所帮助。

  11. David 2020年3月29日上午1:35 #

    你好!一个快速问题,SMOTE 应该在数据准备(例如标准化)之前还是之后应用?或者它无关紧要?

    谢谢!

    • Jason Brownlee 2020年3月29日上午6:01 #

      可能在之后。

      它正在执行 knn,所以数据应该先进行缩放。

  12. San 2020年4月2日上午6:13 #

    当数据集中的类别只有少数实例时,如何使用SMOTE或任何其他与SMOTE相关的技术,例如ADASYN、Borderline SMOTE?

    我的数据集中有些类别只有一个实例,有些有两个实例。使用这些SMOTE技术时,我收到错误“Expected n_neighbors <= n_samples, but n_samples = 2, n_neighbors = 6”。

    有什么办法可以克服这个错误吗?使用RandomOversampling代码工作正常……但它似乎没有给出良好的性能。由于这个错误,我无法使用所有基于SMOTE的过采样技术。

    • Jason Brownlee 2020年4月2日上午6:41 #

      我认为使用一个或几个实例的类别来建模问题是不合适的。

      也许收集更多数据?
      也许删除代表性不足的类别?
      也许重新定义问题?

  13. Garv 2020年4月8日下午9:59 #

    你好,我调整了smote参数(k,采样策略),并以roc_auc作为训练数据的评分,但是我的模型如何在交叉验证评分的同时在测试数据上进行评估(理想情况下不应该在测试数据上应用smote)
    你能帮我如何在测试数据上应用最佳模型吗(需要代码)
    #使用决策树
    Xtrain1=Xtrain.copy()
    ytrain1=ytrain.copy()
    k_val=[i for i in range(2,9)]
    p_proportion=[i for i in np.arange(0.2,0.5,0.1)]
    k_n=[]
    proportion=[]
    score_m=[]
    score_var=[]
    modell=[]
    for k in k_val
    for p in p_proportion
    oversample=SMOTE(sampling_strategy=p,k_neighbors=k,random_state=1)
    Xtrain1,ytrain1=oversample.fit_resample(Xtrain,ytrain)
    model=DecisionTreeClassifier()
    cv=RepeatedStratifiedKFold(n_splits=10,n_repeats=3,random_state=1)
    scores=cross_val_score(model,X1,y1,scoring=’roc_auc’,cv=cv,n_jobs=-1)
    k_n.append(k)
    proportion.append(p)
    score_m.append(np.mean(scores))
    score_var.append(np.var(scores))
    modell.append(‘DecisionTreeClassifier’)
    scorer=pd.DataFrame({‘model’:modell,’k’:k_n,’proportion’:proportion,’scores’:score_m,’score_var’:score_var})
    print(scorer)
    models.append(model)
    models_score.append(scorer[scorer[‘scores’]==max(scorer[‘scores’])].values[0])
    models_var.append(scorer[scorer[‘score_var’]==min(scorer[‘score_var’])].values[0])

  14. Kabilan 2020年4月10日上午7:02 #

    嗨,Jason,
    我们可以使用哪种方法来过采样时间序列数据?

    • Jason Brownlee 2020年4月10日上午8:38 #

      好问题,我希望将来能涵盖这个主题。

      • John White 2020年4月10日下午7:11 #

        你好 Jason,

        你目前有什么关于如何过采样时间序列数据的想法吗?我想在此期间做一些研究/实验。谢谢!

        • Jason Brownlee 2020年4月11日上午6:14 #

          不,一般来说,我宁愿在做足功课后才提出建议。

      • Kabilan 2020年4月10日下午11:40 #

        非常感谢!

        • Jason Brownlee 2020年4月11日上午6:21 #

          不客气。

          • s 2021年9月16日上午12:44 #

            您有机会写关于时间序列数据过采样这个主题的文章吗?

          • Adrian Tam
            Adrian Tam 2021年9月16日上午1:16 #

            感谢您的建议。我们会考虑的。

      • Cel 2022年5月25日上午3:50 #

        你好 Jason,
        我又来读您的文章了,一如既往。您有没有写过关于时间序列数据过采样/欠采样的文章?

        我一直在尝试寻找处理时间序列数据过采样/欠采样的方法,但至今未能找到合适的解决方法……

  15. Vamshi 2020年4月11日上午7:56 #

    你好 Jason Brownie,

    感谢您详细描述了如何使用 SMOTE 及其替代方法处理不平衡数据集。我知道 SMOTE 仅适用于多类别数据集,但我很想知道您是否有关于将 SMOTE 用于多标签数据集的想法?或者您是否有除 SMOTE 之外的其他方法或想法来处理不平衡的多标签数据集。

    • Jason Brownlee 2020年4月11日上午7:58 #

      很好的问题!

      我对多标签数据的方法不熟悉,或许可以查阅相关文献?

      • Vamshi 2020年4月11日上午8:10 #

        我正在处理一个数据集,作为我硕士论文的一部分,它高度不平衡。所以我尝试直接使用 OnevsRestClassifier(没有任何过采样),分类器自然给出了最差的结果(预测了出现次数最多的目标值)。所以我尝试使用随机森林分类器,一次处理一个目标列,并使用随机采样器类进行过采样,过采样后给出了不错的结果。我不确定我是否能以这种方式进行。

  16. Vamshi 2020年4月11日上午8:21 #

    我还找到了这个解决方案。
    https://github.com/scikit-learn-contrib/imbalanced-learn/issues/340

  17. Jooje 2020年4月16日上午4:23 #

    您好!感谢这篇精彩的教程。SMOTE 可以与用于文本表示的高维嵌入一起使用吗?如果可以,在应用 SMOTE 之前需要进行哪些预处理/降维?

    • Jason Brownlee 2020年4月16日上午6:06 #

      不确定,也许可以尝试一下看看是否有意义。

  18. rahul malik 2020年4月23日上午8:49 #

    你好 Jason,我有 3 个输入文本列,其中 2 个是类别型的,1 个是非结构化文本。您能帮我如何进行采样吗?输出列是类别型的并且不平衡。

    • Jason Brownlee 2020年4月23日下午1:34 #

      也许可以使用标签或独热编码处理分类输入,并使用词袋模型处理文本数据。

      您可以在博客上看到许多示例,尝试搜索一下。

      • rahul malik 2020年4月23日下午10:53 #

        我使用了 Pipeline 和 columntransformer 来传递多个列作为 X,但对于采样我没有找到任何示例。对于单列,我可以使用 SMOTE,但如何传递多个列作为 X?

        • Jason Brownlee 2020年4月24日上午5:43 #

          您可能需要进行实验,也许是不同的 smote 实例,也许是手动运行管道,等等。

  19. Iraj 2020年4月30日上午8:28 #

    你好,
    SMOTE 需要每个类别 6 个示例。
    我有一个数据集,其中有 30 个类别 0,和 1 个类别 1。
    请提供任何解决方案。
    谢谢你

  20. John Sammut 2020年5月2日上午9:25 #

    你好 Jason,

    非常感谢这篇文章。我发现它非常有趣。

    如何在有3个类别的管道中应用相同的过采样比例(1:10)和欠采样比例(1:2)?

    多类别采样策略不能设置为浮点数。您会推荐什么?

    谢谢你。
    约翰

    • Jason Brownlee 2020年5月3日上午6:05 #

      谢谢。

      第一步是将类别分组为正和负,然后应用采样。

  21. Srisha 2020年5月4日下午12:35 #

    您能详细说明如何利用 SMOTE 中的 `sampling_strategy` 参数吗?

  22. Mohamad 2020年5月7日下午11:04 #

    嗨,Jason,
    非常感谢您的这篇文章,它一如既往地非常有帮助。

    我有一个疑问
    现在我的数据高度不平衡(99.5%:0.05%)。我的分类问题有超过 40,000 个样本和多个特征(36 个)。我使用 SMOTE 进行过采样以获得平衡数据,但分类器对过采样数据产生高度偏向。我猜这是由于“sampling_strategy”的原因。所以我尝试了 {0.25, 0.5, 0.75,1} 作为“sampling_strategy”。它要么高度偏向于丰富的类别,要么高度偏向于稀有的类别。

    您认为问题可能出在哪里?

  23. john sen 2020年5月11日上午3:45 #

    请告诉我如何先应用 SMOTE 再应用一种分类学习算法在同一数据集上以获得更好的结果

    • Jason Brownlee 2020年5月11日上午6:08 #

      您可以将 SMOTE 应用于训练集,然后直接应用单类别分类器。

      我不认为结合这两种方法会有益处。

      • john sen 2020年5月12日上午3:54 #

        先生,那么我应该尝试什么才能通过使用 smote 和另一个算法来获得最佳结果,从而形成一种处理不平衡数据的混合方法呢?

        • Jason Brownlee 2020年5月12日上午6:50 #

          使用试错法来发现最适合您数据集的方法。

  24. Arnaud 2020年5月11日上午3:47 #

    嗨,Jason,
    首先,感谢您的资料,它非常有价值!

    我有一个监督分类问题,需要预测不平衡的类别(事件 = 1/100 非事件)。

    我有一种直觉,使用重采样方法(如 SMOTE 或下采样/上采样/ROSE)与朴素贝叶斯模型会影响先验概率,从而导致在测试集上应用时性能下降。

    这正确吗?
    谢谢。

  25. Teixeira 2020年5月12日上午1:31 #

    嗨,博士。

    SMOTE 可以应用于将用于馈送 LSTM 的数据吗?(因为顺序很重要,它可能会干扰数据,对吗?)

    提前感谢!

    • Jason Brownlee 2020年5月12日上午6:46 #

      不,它只适用于表格数据。

      • Teixeira 2020年5月13日上午2:04 #

        首先,感谢您的回复。抱歉,我想我不明白。也许我错了,但SMOTE可以应用于表格数据,在转换为滑动窗口之前。即使在这种情况下也不建议应用SMOTE吗?

        谢谢!

        • Jason Brownlee 2020年5月13日上午6:39 #

          也许吧,但我怀疑时间序列感知的数据生成方法会表现得更好。

          • Zina 2020年9月24日上午12:51 #

            谢谢,Jason。您能指出一个时间序列感知数据生成方法的示例吗?

          • Jason Brownlee 2020年9月24日上午6:16 #

            抱歉,目前没有。或许可以在 scholar.google.com 上搜索一下。

          • said okieh 2021年12月27日上午4:50 #

            你好先生,我们如何处理LSTM的不平衡数据集?我有一个CSV文件,我们可以使用SMOTE技术还是数据生成?您能给我一个链接,说明如何使用过采样吗,因为我有3D数组LSTM输入,非常感谢。

          • James Carmichael 2021年12月27日上午10:47 #

            嗨,Said…请参阅以下内容:

            https://machinelearning.org.cn/random-oversampling-and-undersampling-for-imbalanced-classification/

  26. John D 2020年5月14日上午10:04 #

    Jason,

    我有一个高度不平衡的二元(是/否)分类数据集。该数据集目前约有 0.008% 的“是”。

    我需要使用 SMOTE 平衡数据集。

    我遇到了两种处理不平衡的方法。在我对变量运行 MinMaxScaler 之后,执行以下步骤:

    from imblearn.pipeline import Pipeline
    oversample = SMOTE(sampling_strategy = 0.1, random_state=42)
    undersample = RandomUnderSampler(sampling_strategy=0.5, random_state=42)
    steps = [(‘o’, oversample), (‘u’, undersample)]
    管道 = Pipeline(steps=steps)
    x_scaled_s, y_s = pipeline.fit_resample(X_scaled, y)
    这导致数据集大小从 240 万行减少到 732000 行,不平衡度从 0.008% 提高到 33.33%

    而这种方法

    sm = SMOTE(random_state=42)
    X_sm , y_sm = sm.fit_sample(X_scaled, y)
    这会将行数从 240 万行增加到 480 万行,不平衡度现在是 50%。

    完成这些步骤后,我需要将数据拆分为训练测试数据集……

    这里正确的方法是什么?

    在选择这些方法之前我需要考虑哪些因素?

    我应该在未采样数据上运行 X_test,y_test 吗?这意味着我先拆分数据,然后只在训练数据上进行上采样/下采样。

    再次感谢。

    • Jason Brownlee 2020年5月14日下午1:27 #

      不,采样仅应用于训练数据集,而不应用于测试集。例如:先分割,然后采样。

  27. Shivam 2020年5月16日下午4:50 #

    你好 Jason,很棒的文章。我在使用 SMOTE-NC 处理分类数据时遇到一个问题。我只有一个用于分类的特征。

    from imblearn.over_sampling import SMOTE
    from imblearn.over_sampling import SMOTENC

    sm = SMOTENC(random_state=27,categorical_features=[0,])

    X_new = np.array(X_train.values.tolist())
    Y_new = np.array(y_train.values.tolist())

    print(X_new.shape) # (10500,)
    print(Y_new.shape) # (10500,)

    X_new = np.reshape(X_new, (-1, 1)) # SMOTE 需要 2D 数组,因此改变 X_new 的形状

    print(X_new.shape) # (10500, 1)

    sm.fit_sample(X_new, Y_new)

    但是我收到错误

    ValueError: Found array with 0 feature(s) (shape=(10500, 0)) while a minimum of 1 is required.

    您能建议一下如果只有一个特征,如何处理 SMOTE 吗?

    • Jason Brownlee 2020年5月17日上午6:31 #

      有意思,我想知道是不是 smote-nc 的 bug?

      也许尝试复制列,看看是否有区别?

  28. sukhpal 2020年5月26日下午7:23 #

    先生,SMOTE 如何应用于 CSV 文件数据?

  29. John D 2020年5月27日上午8:19 #

    欠采样多数类别和过采样少数类别的标准是什么?
    或者
    仅过采样少数类别的标准是什么?

    • Jason Brownlee 2020年5月27日下午1:25 #

      我不是那样处理的。我认为这具有误导性且难以处理。

      相反,我建议进行实验,如果它能带来更好的性能,就使用它。

  30. SUKHPAL 2020年5月28日下午3:51 #

    先生,请提供关于数值数据测试时增强的教程

    • Jason Brownlee 2020年5月29日上午6:20 #

      没问题,我写了一篇,安排在下周发布。

  31. sukhpal 2020年5月30日下午7:01 #

    先生,我们是先应用特征选择技术还是先进行数据增强?

  32. Suyash 2020年6月25日下午10:32 #

    我们为什么要对整个数据集“X, y = oversample.fit_resample(X, y)”实施 SMOTE?我们应该只对训练集进行过采样。我说的对吗?应该怎么做才能只对训练集进行过采样,并且我们还想使用分层方法?

    • Jason Brownlee 2020年6月26日上午5:35 #

      没错,我们在教程后面评估模型时会这样做。

      在第一个示例中,我让您熟悉 API 和该方法的效果。

      • suyash 2020年6月27日下午11:38 #

        您能给我推荐一下那个教程吗,我们在其中只对训练数据应用 smote 并评估模型?我还想知道 RepeatedStratifiedKfold 是否只在训练数据集上工作。

      • suyash 2020年6月28日上午12:10 #

        cross_val_score 只对训练集数据进行过采样,而不对训练数据进行过采样。我说的对吗?

        • Jason Brownlee 2020年6月28日上午5:52 #

          当使用管道时,转换只应用于训练数据集,这是正确的。

          • suyash 2020年6月29日下午3:44 #

            非常感谢。

          • Jason Brownlee 2020年6月30日上午6:11 #

            不客气。

  33. Jose Q 2020年6月28日上午7:29 #

    嗨,Jason!
    感谢您发表如此精彩的帖子!

    我正在处理一个不平衡数据集 (500:1)。我想获得最佳召回性能,并且我尝试了多种分类算法、超参数以及过采样/欠采样技术。我将尝试 SMOTE !!
    从上一个问题中,我了解到使用 CV 和管道时,您只对训练集进行了过采样,对吗?

    我还有另一个问题。我的不平衡数据集包含大约 500 万条记录,来自 11 个月。它不是时间序列。我使用前十个月的数据进行训练,使用第十一个月的数据进行测试,以便更容易向用户解释,但我感觉这不正确,我猜我应该使用整个数据集中的随机测试分割。这正确吗?

  34. Jose Q 2020年7月1日上午3:09 #

    嗨,Jason,
    我遵循了您的建议
    https://machinelearning.org.cn/framework-for-imbalanced-classification-projects/

    我尝试使用 SMOTE 进行过采样,但我的电脑无法处理。
    然后我阅读了您的帖子后,尝试使用决策树和 XGB 处理不平衡数据集
    https://machinelearning.org.cn/cost-sensitive-decision-trees-for-imbalanced-classification/
    https://machinelearning.org.cn/xgboost-for-imbalanced-classification/
    但我仍然得到较低的召回值。

    我正在进行随机欠采样,因此我得到了 1:1 的类别关系,我的电脑可以管理。然后我正在进行 XGB/决策树,改变 max_depth 并改变权重以赋予正类别更高的重要性。我的假设是,只要我使用多折和多次迭代的 CV,我就不会过拟合模型。这正确吗?
    谢谢

    • Jason Brownlee 2020年7月1日上午5:55 #

      祝贺你的进步!

      也许吧。假设可能导致糟糕的结果,测试你所能想到的一切。

  35. xplorer4us 2020年7月8日下午5:32 #

    你好 Jason,对 SMOTE 的解释非常出色,易于理解,并且附带大量示例!

    我尝试下载关于不平衡分类的免费迷你课程,但我没有收到 PDF 文件。

    请问您能帮我解决这个问题吗?提前感谢!

  36. Landry 2020年7月13日下午8:01 #

    你好 Jason,感谢你的教程,它一如既往地有用,

    我有一个疑问,我直觉上觉得 SMOTE 在高维数据集(即我们的数据集中有许多特征)上的表现不佳。这是真的吗?

    • Jason Brownlee 2020年7月14日上午6:18 #

      嗯,那也会是我的直觉,但总是要进行测试。直觉在高维度下或者在机器学习中通常会失效。测试一切。

  37. Volkan Yurtseven 2020年7月22日上午7:34 #


    与 gridsearchcv 结合使用时,Smote 是对整个训练集进行过采样还是忽略验证集?

    • Jason Brownlee 2020年7月22日上午7:38 #

      您可以将其作为管道的一部分使用,以确保 SMOTE 仅应用于训练数据集,而不是 val 或测试。

      • Volkan Yurtseven 2020年7月23日上午6:52 #

        嗨,杰森,
        你是说如果在imblearn自己的Pipeline类中使用它就足够了?不需要任何参数吗?

        pipe = Pipeline(steps=[(‘coltrans’, coltrans),
        (‘scl’,StandardScaler()),
        (‘smote’, SMOTE(random_state=42))
        ]
        )

        X_smote,y_smote=pipe.fit_resample(X_train,y_train)

  38. Diego 2020年7月23日下午12:39 #

    嗨,Jason,

    感谢分享。它对我的工作真的很有帮助 🙂

    假设您使用训练数据集训练了一个管道,它有 3 个步骤:MinMaxScaler、SMOTE 和 LogisticRegression。

    您可以使用相同的管道预处理测试数据吗?
    还是应该为测试数据使用一个没有 SMOTE 的不同管道?

    pipeline.predict(X_test) 如何知道它不应该执行 SMOTE?

    谢谢。

  39. SAM V 2020年7月29日下午3:52 #

    你好 Jason,SMOTE 采样是在数据清洗、预处理或特征工程之前/之后进行的吗?我只是想知道我们应该何时进行 SMOTE 采样以及为什么?

    • Jason Brownlee 2020年7月30日上午6:16 #

      这取决于您正在进行的数据准备工作。

      可能在之后。

  40. Gaël 2020年8月6日下午7:26 #

    你好,很棒的文章!我认为在“SMOTE for Balancing Data”部分有一个错字:“属于少数类别的大量点(蓝色)”——> 应该改为多数类别,我猜。

  41. Luna 2020年8月6日下午7:30 #

    嗨,Jason,

    TypeError: 所有中间步骤都应该是转换器并实现 fit 和 transform,或者是一个字符串 ‘passthrough’ ‘SMOTE(k_neighbors=5, n_jobs=None, random_state=None, sampling_strategy=’auto’)’ (type ) 没有实现。

    运行 GridSearchCV 时我遇到这个错误。哪里出错了?

    • Jason Brownlee 2020年8月7日上午6:24 #

      也许确认您的管道内容以预测模型结束。

  42. george 2020年8月12日下午1:30 #

    嗨,Jason,

    如果我的所有预测变量都是二元的,我还可以使用 SMOTE 吗?SMOTE 似乎只适用于数值预测变量?除了随机欠采样或过采样之外还有其他方法吗?谢谢。

  43. Franco 2020年8月19日上午7:18 #

    杰出的帖子,Jason!

    我想知道,如果我们使用引导(当然是带替换的)将少数类别从 100 上采样到 9,900,我们是否会得到与 SMOTE 相似的结果……我把它列入我的待办事项清单。

    • Jason Brownlee 2020年8月19日下午1:34 #

      谢谢!

      可能不会,因为我们正在使用 SMOTE 生成全新的样本。不过,运行实验并比较结果吧!

  44. Franco 2020年8月19日下午3:52 #

    有意思……我会的。谢谢 Jason!

  45. SaHaR 2020年8月22日上午12:35 #

    嗨,Jason

    感谢您精彩的文章。一如既往地信息丰富。最近我读了一篇关于多类别和不平衡数据集分类的文章。他们对训练集和测试集都使用了 SMOTE,我认为这不是正确的方法,测试数据集不应该被操作。请告诉我我的理解是否错误,您能推荐一些关于使用 SMOTE 的缺点和挑战的参考资料吗?

    谢谢你

    • Jason Brownlee 2020年8月22日上午6:17 #

      谢谢!

      同意,在测试集上使用 SMOTE 是无效的。

  46. Vivek 2020年8月28日上午4:04 #

    嗨 Jason

    问题1:我们是在进行训练/测试分割之后才对训练集应用SMOTE吗?

    我猜,如果先进行SMOTE再分割,可能会导致数据泄漏,因为相同的实例可能会同时出现在测试集和训练集中。

    问题2:我明白为什么SMOTE比随机过采样少数类别更好。但是,如果类别不平衡比例为1:100,为什么不直接对多数类别进行随机欠采样呢?我不确定SMOTE在这里有什么帮助!

    谢谢
    维韦克

    • Jason Brownlee 2020年8月28日上午6:55 #

      是的。仅限于训练集。

      尝试多种方法,找出最适合您数据集的方法。

  47. Shehab 2020年8月29日上午7:13 #

    嗨,Jason,

    如果您的数据集不平衡,但与生产中的实际类别分布相符,该怎么办?假设类别 A 有 1000 行,类别 B 有 400 行,类别 C 有 60 行。这种不平衡的数据集会带来哪些负面影响?假设我使用像朴素贝叶斯这样的分类器,由于先验概率很重要,如果我对类别 C 进行过采样,我就会弄乱先验概率,并偏离生产中的实际概率。我应该尝试获取更多数据或在我拥有的数据上进行数据增强,同时保持这种不平衡分布,还是通过对少数类别进行过采样来改变分布?

    谢谢

  48. Daniel 2020 年 9 月 10 日下午 7:34 #

    你好,

    感谢您的工作,它真的很有用。我有一个关于 SMOTE 和主动学习结合的问题。

    我正在尝试使用主动学习技术生成数据集。我从一个未标记的数据池中选择要标记的新点,使用每次迭代中的不确定性。我的问题是类别分布不平衡(1000:1),我当前的算法无法在“是”类别中找到足够的点。您认为我可以使用 SMOTE 生成“是”类别的新点吗?
    我正在考虑使用 borderline-SMOTE 来生成新点,然后对其进行标记。我怎么能确定新点不会集中在一个小区域内?

    我不确定我是否很好地解释了这个问题。我需要以智能的方式使用标注器找到可行区域,因为标注成本很高。您能给我一些建议吗?

    谢谢。

    Daniel

  49. Bilal 2020 年 9 月 26 日下午 9:44 #

    我对整个数据集执行 SMOTE,然后对数据集进行归一化。之后,我应用了 cross_val_score。在 cross_val_score 中,SMOTE 只会对训练集进行重采样,这是正确的吗?代码如下:

    oversample = SMOTE()
    X, Y = oversample.fit_resample(X, Y)

    normalized = StandardScaler()
    normalized_X = normalized.fit_transform(X)
    clf_entropy = DecisionTreeClassifier(random_state = 42)
    y_pred = cross_val_predict(clf_entropy, normalized_X, Y, cv=15)

    • Jason Brownlee 2020 年 9 月 27 日上午 6:53 #

      不。如果您使用管道,它将按您所述工作。

  50. Vidya 2020 年 10 月 6 日下午 1:01 #

    嗨,Jason。

    感谢您的帖子。关于上面的 SMOTE + 欠采样示例,我有两个问题。
    “under = RandomUnderSampler(sampling_strategy=0.5)” 。为什么我们要将多数类别欠采样为 1:2 的比例,而不是让两个类别具有相等的表示?
    2. 如果我的不平衡数据中少数类别占 50%,我是否需要使用 PR 曲线 AUC 或 f1 作为度量,而不是 ROC AUC?
    “scores = cross_val_score(pipeline, X, y, scoring=’roc_auc’, cv=cv, n_jobs=-1)”

    谢谢!!

  51. Vidya 2020 年 10 月 7 日下午 12:51 #

    谢谢杰森。现在正在应用。

  52. Vidya 2020 年 10 月 7 日下午 1:34 #

    杰森,我正在尝试对不平衡数据应用各种平衡方法。但是,对于平衡训练数据集如何使算法在不平衡测试数据上学习并表现良好,我仍然感到不解。这是否取决于特征的质量?意思是,如果我看到在各种平衡训练数据集的方法之后,模型在测试数据上泛化不好,我需要重新审视特征创建吗?

    谢谢!!

    • Jason Brownlee 2020 年 10 月 7 日下午 1:53 #

      很难说,我们能做的最好的事情就是通过受控实验来发现哪种方法对给定的数据集效果最好。

  53. Sophie 2020 年 10 月 7 日下午 2:09 #

    嗨,Jason,
    非常感谢您的解释。我在使用 SMOTE 拟合模型时有一个问题
    为什么您使用 .fit_resample 而不是 .fit_sample?这两个函数有什么区别?

    另外,在 SMOTE 过采样后,是否有办法知道原始数据集的索引?我如何知道 SMOTE 上采样数据集中哪些数据来自原始数据集?

    谢谢!

  54. Fatima 2020 年 10 月 10 日上午 7:30 #

    你好,我应用了 SMOTE 进行数据平衡。首先,我的数据有 27 个特征,当我在 make_classification 中定义数据集时,我写了 n_features=27 而不是 2,这正确吗?当我的模型目标是预测时,我可以使用 SMOTE 进行数据平衡吗?

    其次,我如何将新数据集保存到 CSV 中?

    谢谢!

    • Jason Brownlee 2020 年 10 月 10 日上午 8:15 #

      如果您有自己的数据,则无需使用 make_classification,因为它是一个用于创建合成数据集的函数。

      • Fatima 2020 年 10 月 10 日下午 11:07 #

        好的,我想应用 SMOTE。我的数据包含 1,469 行,类别标签有 Risk= 1219,NoRisk= 250,数据不平衡,我想应用过采样 (SMOTE) 来平衡数据。
        首先,我运行这段代码,它显示了类别标签的图表,然后我应用了 SMOTE,

        target_count = data[‘Having DRPs’].value_counts()
        print(‘Class 1:’, target_count[1])
        print(‘Class 0:’, target_count[0])
        print(‘Proportion:’, round(target_count[1] / target_count[0], 2), ‘: 1′)

        target_count.plot(kind=’bar’, title=’Count (Having DRPs)’);
        ****
        (过采样:SMOTE)

        from imblearn.over_sampling import SMOTE

        smote = SMOTE(ratio=’minority’)
        X_sm, y_sm = smote.fit_sample(X, y)

        plot_2d_space(X_sm, y_sm, ‘SMOTE over-sampling’)

        它给我一个错误
        TypeError: __init__() 得到了一个意外的关键字参数 ‘ratio’

        我该如何解决这个问题!

    • Emma 2022 年 1 月 28 日下午 6:32 #

      你好,法蒂玛!您能向我解释一下您是如何在数据集上进行 smote 操作的吗?我的数据集有 4 个类别(感染(2555)、无(2552)、两者(621)、缺血(227))

  55. Fatima 2020 年 10 月 15 日上午 4:09 #

    你好 Jason,我对我的数据应用了 SMOTE,并解决了数据不平衡的问题。下一步我想开始深度学习(DL)。在 DL 中,我需要保存新数据(平衡后的数据),然后在新数据上开始 DL 算法吗?

    谢谢!

    • Jason Brownlee 2020 年 10 月 15 日上午 6:19 #

      只有训练集应该平衡,测试集不应该平衡。

      您可以在拟合模型之前在内存中转换数据。或者如果对您来说更容易,也可以保存它。

    • hamyy 2022 年 1 月 28 日下午 9:38 #

      你好,法蒂玛!你是怎么对你的数据集应用 smote 的?我的数据集有 4 个类别(无(2552),缺血(227),两者(621)和感染(2555))。我怎么能整合 SMOTE?

  56. Samuel Smets 2020 年 10 月 16 日下午 6:39 #

    亲爱的 Jason,

    感谢这篇精彩的文章!

    我尝试在我的项目中实现 SMOTE,但 cross_val_score 始终返回 nan。

    然后我尝试了您的代码片段

    # 在具有 SMOTE 过采样的不平衡数据集上评估的决策树
    from numpy import mean
    从 sklearn.datasets 导入 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
    # 定义数据集
    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)
    # 定义流水线
    步骤 = [(‘over’, SMOTE()), (‘model’, DecisionTreeClassifier())]
    管道 = Pipeline(steps=steps)
    # 评估流水线
    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(‘平均 ROC AUC:%.3f’ % scores 的平均值)

    这也返回 nan。

    我无法弄清楚为什么它返回 nan。在您的文章中,您描述了您确实得到了此代码片段的答案。

    非常感谢!

    塞缪尔

  57. deva 2020 年 10 月 17 日下午 10:33 #

    ```

    from sklearn.model_selection import StratifiedKFold
    from sklearn import metrics

    cv = StratifiedKFold(n_splits=10,shuffle=True)
    classifier = AdaBoostClassifier(n_estimators=200)
    y = df['label'].values
    X = df
    X = X.drop('label',axis=1)
    X = X.values
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.10, random_state = 0, stratify = y)
    oversampler= sv.CCR()
    X_samp, y_samp= oversampler.sample(X_train, y_train)
    X_train = X_samp
    y_train = y_samp

    tprs = []
    aucs = []
    mean_fpr = np.linspace(0, 1, 100)
    plt.figure(figsize=(10,10))
    i = 0
    # cv.sh
    for train, test in cv.split(X_train, y_train)
    probas_ = classifier.fit(X_train[train], y_train[train]).predict_proba(X_train[test])
    # 计算 ROC 曲线和曲线下面积
    fpr, tpr, thresholds = metrics.roc_curve(y_train[test], probas_[:, 1])
    tprs.append(np.interp(mean_fpr, fpr, tpr))
    tprs[-1][0] = 0.0
    roc_auc = metrics.auc(fpr, tpr)
    aucs.append(roc_auc)
    plt.plot(fpr, tpr, lw=1, alpha=0.3,
    label='ROC fold %d (AUC = %0.2f)' % (i, roc_auc))

    i += 1
    plt.plot([0, 1], [0, 1], linestyle='--', lw=2, color='r',
    label='Chance', alpha=.8)

    mean_tpr = np.mean(tprs, axis=0)
    mean_tpr[-1] = 1.0
    mean_auc = metrics.auc(mean_fpr, mean_tpr)
    std_auc = np.std(aucs)
    plt.plot(mean_fpr, mean_tpr, color='b',
    label=r'Mean ROC (AUC = %0.2f $\pm$ %0.2f)' % (mean_auc, std_auc),
    lw=2, alpha=.8)

    std_tpr = np.std(tprs, axis=0)
    tprs_upper = np.minimum(mean_tpr + std_tpr, 1)
    tprs_lower = np.maximum(mean_tpr - std_tpr, 0)
    plt.fill_between(mean_fpr, tprs_lower, tprs_upper, color='grey', alpha=.2,
    label=r'$\pm$ 1 std. dev.')

    ```

    plt.xlim([-0.01, 1.01])
    plt.ylim([-0.01, 1.01])
    plt.xlabel('False Positive Rate',fontsize=18)
    plt.ylabel('True Positive Rate',fontsize=18)
    plt.title('ADABOOST 的交叉验证 ROC',fontsize=18)
    plt.legend(loc="lower right", prop={'size': 15})
    plt.show()

    ```
    检查此输出
    https://ibb.co/PYLs8qF

    我很困惑,因为在 Adaboost 之后 SMOTE 对训练集效果很好,但测试集效果不好。
    https://ibb.co/yPSrLx2

  58. Karrtik Iyer 2020 年 11 月 11 日下午 8:34 #

    嗨 @jasonBrowniee,感谢上面的例子。快速提问,对于 SMOTE,您使用了过采样,然后是随机欠采样,想知道如果我们使用 ADASYN 或 SVMSMOTE,您是否建议我们像 SMOTE 一样使用随机欠采样?

    • Jason Brownlee 2020 年 11 月 12 日上午 6:38 #

      也许可以尝试几种不同的组合,并发现哪种方法对您的特定数据集效果好/最好。

  59. Marlon Lohrbach 2020 年 11 月 30 日上午 4:48 #

    嗨,Jason,

    希望您一切顺利!如果我使用分层 k 折叠或重复分层 k 折叠,还需要使用 Smote() 进行上采样吗?我认为我的分层折叠已经处理了类别不平衡。那么在什么情况下您会更喜欢 Smote 而不是分层折叠呢?

    谢谢

    • Jason Brownlee 2020 年 11 月 30 日上午 6:40 #

      SMOTE 可以与分层交叉验证一起使用,也可以不使用,它们解决的是不同的问题——训练数据集的采样与模型的评估。

  60. Michael Tamillow 2020 年 12 月 9 日上午 4:41 #

    我不相信这种技术在许多情况下“真正”有效。你可以阅读 Jonas Peters 的作品来理解为什么。它实际上是机器学习的魔法戏法,或者是数据科学的创造性一面,将“有效”定义为“我尝试过并看到了改进”的轶事证据。总体而言,不通过分析和逻辑方法严格评估此类方法是不好的。

  61. Mohammad 2021 年 1 月 2 日下午 8:00 #

    嗨,Jason,

    感谢您建议的这些用于平衡数据集的启发式替代方法。

  62. Ammar Sani 2021 年 1 月 3 日上午 2:50 #

    嗨,杰森博士。我在几篇文章中看到,作者比较了不平衡类别和重叠类别。您有关于这方面的文章吗?

    • Jason Brownlee 2021 年 1 月 3 日上午 5:58 #

      几乎所有的类都重叠——如果不是,问题就会变得微不足道(例如,线性可分)。

      你到底是什么意思?

      • Ammar Sani 2021 年 1 月 4 日下午 1:19 #

        谢谢博士。

        实际上,我刚接触机器学习,对不平衡分类很感兴趣。我正在这里学习机器学习和不平衡分类的基础知识:https://machinelearning.org.cn/start-here/

        然后,我开始阅读其他资料,以加强和验证我的理解。我找到了这篇文章:https://link.springer.com/chapter/10.1007/978-3-642-13059-5_22,它讲述了不平衡和重叠之间的区别。

        也许是因为我的基础不是很扎实,我不太明白这篇文章在说什么。所以,我像往常一样来到您的博客(它真的对像我这样的新手很有帮助),希望能找到一篇关于重叠和不平衡之间区别的文章。不幸的是,我找不到。????

        • Jason Brownlee 2021 年 1 月 4 日下午 1:42 #

          感谢分享,抱歉我对这篇文章不熟悉。

          • Ammar Sani 2021 年 1 月 4 日下午 2:04 #

            好的,杰森博士

            顺便问一下,我是否需要了解数据集中重叠问题?有没有关于这方面的文章?

            再次感谢博士

          • Jason Brownlee 2021 年 1 月 5 日上午 6:14 #

            我不这么认为,我以前没有听说过这个概念。

  63. Ammar Sani 2021 年 1 月 5 日下午 2:01 #

    好的,博士,非常感谢

  64. Keith 2021 年 1 月 26 日下午 5:32 #

    嗨,杰森,感谢这篇信息量很大的文章。但我只是想知道,在过采样/欠采样数据集上调整模型超参数是否有意义,像这样?

    paramgrid_rf = {‘n_estimators’: [500],
    ‘max_depth’: [4],
    ‘random_state’: [0],
    ‘max_features’: [‘sqrt’],
    ‘criterion’ :[‘mse’]
    }

    rfc = GridSearchCV(RandomForestRegressor(), paramgrid, cv=5)

    steps = [(‘over’, SMOTE(sampling_strategy=0.2)), (‘model’, rfc)]
    管道 = Pipeline(steps=steps)
    # 评估流水线
    cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
    scores = cross_val_score(pipeline, x_train, y_train, scoring=’f1′, cv=cv, n_jobs=-1)

    • Jason Brownlee 2021 年 1 月 27 日上午 6:03 #

      也许可以。

      尽一切可能在您的测试工具上取得更好的结果。

  65. David 2021 年 2 月 2 日下午 2:13 #

    请指定需要哪些模块。我花了一个小时才找到 numpy 中该死的 where 属性。

  66. David 2021 年 2 月 2 日下午 2:15 #

    我上面的评论看起来太负面了。这太棒了;只是请指定要导入的模块。

    感谢您的工作

  67. JAIKISHAN 2021 年 2 月 13 日下午 1:13 #

    嗨,Jason,
    这是一个非常有用的教程。
    谢谢您。

  68. Aya 2021 年 2 月 16 日上午 10:40 #

    谢谢,但我对在训练数据上应用 SMOTE 还是在 x 和 y 上应用 SMOTE 感到困惑,就像示例中那样,它们之间有什么区别

      • Aya 2021 年 2 月 17 日上午 12:42 #

        好的,那是 x 和 y(特征和目标),但是为什么你要在它上面应用 smote?在训练数据上应用 smote 是否意味着 x 分成训练和测试,y 保持不变,然后将 smote 应用于 xtrain 和 ytrain?

        • Jason Brownlee 2021 年 2 月 17 日上午 5:29 #

          是的,SMOTE 仅应用于训练数据集。

          上面的例子向您展示了如何使用 SMOTE 类及其效果——这样您就可以熟悉它,并开始在自己的项目中使用它。

  69. MS 2021 年 3 月 3 日下午 9:56 #

    你好,Jason
    我们可以在 imblearn 管道中用 FAMD(prince) 实现 SMOTENC 吗?如果可以,您能提供一些关于方法和代码的参考资料吗?

    • Jason Brownlee 2021 年 3 月 4 日上午 5:48 #

      我不能直接回答,抱歉。也许可以尝试使用原型来探索一下。

      • MS 2021 年 3 月 4 日下午 9:30 #

        谢谢

  70. Ethan 2021 年 3 月 16 日下午 1:14 #

    嗨,杰森,感谢 SMOTE 的精彩内容。我的数据中有一个分类变量,即位置。我可以使用 SMOTENC 在重采样中使用它。但是有没有一种方法可以实现 SMOTE,以便我可以在位置上对少数类别实现同质性。因此,SMOTE 将在最初具有少量少数类别实例的位置生成合成数据。

    • Jason Brownlee 2021 年 3 月 17 日上午 5:58 #

      您可能需要自己实现该算法,以便对算法选择重新采样的位置进行精细控制。

      • Ethan 2021 年 3 月 17 日上午 7:19 #

        一如既往,感谢您的及时回复!

  71. Anthony 2021 年 3 月 20 日上午 12:50 #

    我们也可以将 SMOTE 应用于测试数据集吗?

  72. hou 2021 年 3 月 22 日下午 12:22 #

    那么如果测试数据不平衡,我该怎么做呢?我将数据集分成 70% 的训练集和 30% 的测试集。在我使用 SMOTE 平衡训练集之后,我想在测试集上测试模型,然后由于测试集不平衡,AUC 会非常低,我该怎么做?非常感谢!

    • Jason Brownlee 2021 年 3 月 23 日上午 4:55 #

      也许 AUC 不是您问题的最佳指标?
      也许您可以使用重复的 k 折交叉验证来估计 AUC?

  73. sanket 2021 年 3 月 27 日下午 6:06 #

    嗨,Json,
    这篇关于不平衡类别的文章非常简洁。非常感谢您的文章和原始论文的链接。

  74. Dorian 2021 年 3 月 31 日上午 2:07 #

    你好,文章很棒,但请不要推荐使用 sudo 权限从 pip 安装 python 包!你基本上是在将管理员权限授予从互联网上拉取的一些随机脚本,这真的不是一个好习惯,甚至很危险。更多参考资料,请看这里:https://askubuntu.com/a/802594
    非常感谢!

  75. Minh 2021 年 4 月 1 日下午 1:44 #

    你好,Jason
    我是这里的新手。我正在处理时间序列预测回归问题。这意味着预测模型需要从一系列过去的观测中学习,以预测序列中的下一个值。
    我正在使用 1998 年世界杯网站数据集(包含 1998 年 4 月 30 日至 1998 年 7 月 26 日期间对 1998 年世界杯网站发出的所有请求)。这是 FTP 链接:ftp://ita.ee.lbl.gov/html/contrib/WorldCup.html
    我通过将同一分钟内发生的所有日志聚合到一个累积记录中来预处理数据集。
    我想问一下我的数据集是否不平衡?以及为什么?
    谢谢你的帮助。

    • Jason Brownlee 2021 年 4 月 2 日上午 5:35 #

      不。通常不平衡是针对分类任务的,您说您的问题是回归(预测数值)。

  76. m.cihat 2021 年 4 月 15 日上午 12:23 #

    你好 Jason,感谢你的文章。
    我看到了一篇关于 SMOTE 的文章,我很困惑。这是他们使用的代码

    from imblearn.over_sampling import SMOTE

    sm = SMOTE(random_state=42)

    X_sm, y_sm = sm.fit_resample(X, y)

    X_train, X_test, y_train, y_test = train_test_split(
    X_sm, y_sm, test_size=0.25, random_state=42
    )

    model = RandomForestClassifier(random_state=42)

    model.fit(X_train, y_train)

    preds = model.predict(X_test)

    你说 SMOTE 只应用于训练集。所以上面的代码是错误的?

  77. Salah 2021 年 5 月 1 日上午 3:16 #

    你好,我想感谢你的博客。它真的对我帮助很大。作为一个初学者,我想问你一个问题。使用 SMOTE 进行交叉验证会导致模型出现偏差吗?我的意思是,当你设置管道以应用 SMOTE 然后进行模型拟合时,交叉验证是在原始测试集上进行验证过程还是在过采样测试集上进行?我在 stackoverflow 上看到一个帖子说,当我们使用 SMOTE 时,它应该只在训练集上完成,并且模型应该只在原始数据上进行测试。交叉验证也符合这个标准吗?谢谢。

    • Jason Brownlee 2021 年 5 月 1 日上午 6:10 #

      当在管道中使用 SMOTE 时,它仅应用于训练集,绝不应用于交叉验证评估/测试工具中的测试集。

  78. Jainey 2021 年 5 月 7 日下午 1:14 #

    嗨,首先,我只想感谢您的贡献。我有一个问题
    scores = cross_val_score(pipeline, X, y, scoring=’roc_auc’, cv=cv, n_jobs=-1)
    score = mean(scores)
    当您在训练数据上计算 cross_val_score 时,平均值似乎无关紧要,我的意思是当您在测试数据上计算时,AUC 才重要。我的交叉验证 AUC 很高,但在测试数据上只有 0.5。

    • Jason Brownlee 2021 年 5 月 8 日上午 6:32 #

      抱歉,我不明白你的问题。也许你可以重新表述一下?

  79. emma 2021 年 5 月 17 日下午 10:59 #

    您好,谢谢您,

    我想知道 smote 方法是否适用于文本数据。我正在处理不平衡数据的文本分类。

  80. Xu Zhang 2021 年 5 月 21 日上午 8:45 #

    感谢您的精彩帖子。我认为 SMOTE 仅适用于不平衡的表格数据集,这是一个分类问题。您知道任何用于具有表格数据的回归问题的数据增强方法吗?非常感谢!

    • Jason Brownlee 2021 年 5 月 22 日上午 5:29 #

      不客气。

      正确。

      抱歉,不知道。据我所知,大多数重采样方法都是为不平衡分类(而不是回归)设计的。

  81. ZJ 2021 年 6 月 1 日下午 8:20 #

    希望这能说得通,但我认为 CV 中计算的 ROC 分数不正确。

    原因如下:在您的管道代码中,进行了过采样和欠采样。但我希望分数是在原始数据集上计算的,而不是在样本上。如果您生成合成数据,那么您当然可以使合成数据上的 ROC 看起来更好,但我想知道数据集在原始数据上的表现如何。

    目前的分数是

    score = ROC(sampled(X), sampled(y))

    但我想要

    score = ROC(X, y)

    实际上,我删除了 k 折叠的部分,但你可以明白我的意思。所以我认为代码没有正确地完成工作

    • Jason Brownlee 2021 年 6 月 2 日上午 5:42 #

      ROC 分数仅使用原始数据计算,不使用合成数据。例如,SMOTE 仅用于训练,不用于测试。

      管道确保了这一点。

  82. Kingsley Udeh 2021 年 6 月 12 日下午 11:07 #

    嗨,Jason博士,

    我们如何将 SMOTE 方法应用于不平衡分类时间序列数据?另外,repeatedStratefied() 是否应用于时间序列 cv k 折?

    谢谢你

  83. K.K.F. 2021 年 6 月 15 日上午 5:34 #

    嗨,Jason,

    使用 Smote 平衡了严重不平衡的数据(1:1000)后,我是否需要创建一个集成分类器,以避免因少数类别过采样和多数类别欠采样而导致的过拟合?另外,如果我使用了随机森林(本身就是一个集成),我是否可以创建一个随机森林集成,即集成的集成?这会导致过拟合吗?

    谢谢你

    • Jason Brownlee 2021 年 6 月 15 日上午 6:10 #

      尝试一下并比较结果。

      关注评估指标。过拟合是结果不佳的一个可能原因。

  84. K.K.F. 2021 年 6 月 15 日上午 6:26 #

    此外,欠采样和过采样可能导致数据集信息丢失。

    您如何将此(Smote)与使用随机森林的权重进行比较?

    谢谢你。

    • Jason Brownlee 2021 年 6 月 16 日上午 6:15 #

      也许可以直接比较一个 RF 和一个在 SMOTE 版本数据集上拟合的 RF。

  85. Yasas Sandeepa 2021 年 6 月 17 日下午 6:46 #

    你好 Jason,
    感谢您精彩地描述了如何使用 SMOTE 及其替代方法处理不平衡数据集。

    在使用 SMOTE 后跟 PCA 时,我有一个小疑问。应用 SMOTE 的最佳方法是什么?是先 PCA 后 SMOTE 还是反之?这背后的原理是什么?

    • Jason Brownlee 2021 年 6 月 18 日上午 5:38 #

      也许可以尝试几种不同的方法/顺序,并发现哪种方法对您的数据集和模型效果最好。

      • Yasas Sandeepa 2021 年 6 月 18 日下午 12:12 #

        好的!谢谢杰森

  86. Rajaram 2021 年 6 月 18 日下午 1:34 #

    你好,杰森,一如既往,感谢您的精彩文章。我正在研究一个疾病进展预测问题。目标是预测未来某个时间点的疾病状态(目标类别之一),给定疾病状况随时间(进展中的时间依赖性)的进展。

    我的大部分数据集属于“健康”状况,我只有少量样本代表各种其他疾病状况(其他目标类别)。您能就如何在这种特定情况下对少数类别样本进行过采样提出建议吗?再次感谢。

    • Jason Brownlee 2021 年 6 月 19 日上午 5:45 #

      也许可以尝试上面描述的 SMOTE,并将其结果与不使用 SMOTE 的结果进行比较?

      • Rajaram 2021 年 7 月 4 日下午 1:52 #

        谢谢你,杰森。你是说比较使用 SMOTE 的结果和使用“其他”技术的结果吗?你能详细说明一下吗?再次感谢。

        • Jason Brownlee 2021 年 7 月 5 日上午 5:06 #

          是的,也许是其他过采样方法或不过采样方法。

  87. tim 2021 年 6 月 20 日下午 9:38 #

    嗨,Jason,

    我有一个关于散点图轴上的数字(-0.5 到 3 和 -3 到 4)的问题。轴值的含义是什么?

    • Jason Brownlee 2021 年 6 月 21 日上午 5:37 #

      它们是输入变量的值,只是 SMOTE 作用的演示。

      • tim 2021 年 6 月 22 日上午 1:11 #

        谢谢您的回答。我想我还没有完全理解

        我以为这些值是类标签(输入 = 类标签)。但如何解释 x 轴和 y 轴呢?

        再次感谢您?

        • Jason Brownlee 2021 年 6 月 22 日上午 6:33 #

          X 是变量 1,y 是变量 2,颜色是类别标签。

  88. L 2021 年 7 月 2 日上午 8:56 #

    开发人员是否应该始终将预测概率与 SMOTE 或其他再平衡技术结合起来进行校准?

    • Jason Brownlee 2021 年 7 月 3 日上午 6:06 #

      可能不会——只在模型不能原生提供概率时才需要。

  89. MUHAMAD FAUZI 2021 年 7 月 11 日下午 1:54 #

    嗨,杰森,这是一篇很棒的文章,它真的帮助我理解了 SMOTE。我还有更多关于 K-means SMOTE 和 CURE SMOTE 的问题,您可以在您的论文中添加这两个示例吗?因为我觉得它很难实现,因为外面没有太多例子。提前致谢

  90. Eman 2021 年 7 月 13 日上午 8:16 #

    我如何将 SMOTE 应用于人类活动数据集等多变量时间序列数据?

    谢谢

    • Jason Brownlee 2021 年 7 月 14 日上午 5:23 #

      SMOTE 不适用于时间序列或序列数据。

      也许您可以查阅文献,寻找一种适合时间序列数据的过采样方法。

  91. THK 2021 年 7 月 22 日上午 10:39 #

    非常感谢!
    只是一个快速问题。
    在下面的这句话中
    “这被称为 Borderline-SMOTE1,而仅对少数类别中的边缘情况进行过采样则被称为 Borderline-SMOTE2。”
    我猜如果 1 只影响一个类,而 2 影响两个类,那么 1 和 2 应该互换。
    “””Borderline-SMOTE2 不仅从 DANGER 中的每个示例及其在 P 中的正最近邻居生成合成示例,而且还从其在 N 中的最近负邻居生成合成示例。”””
    如果我理解错了,请告诉我。
    谢谢!

  92. ML 2021 年 10 月 4 日上午 4:50 #

    # 定义流水线
    步骤 = [(‘over’, SMOTE()), (‘model’, DecisionTreeClassifier())]
    管道 = Pipeline(steps=steps)
    # 评估流水线
    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)

    嗨,杰森。在每个折叠中,在仅对训练数据集进行过采样之前,训练和验证数据集的拆分部分在哪里?我不明白。它是隐式的吗?我无法确定过采样过程是否仅应用于训练数据集,而不是在拆分后应用于验证数据集。谢谢。

    • Adrian Tam
      Adrian Tam 2021 年 10 月 6 日上午 8:16 #

      这里您正在进行 CV。CV 的模型是管道,其中包括 SMOTE 和决策树。它将执行 k 折叠并将拆分输入模型进行训练,然后使用保留集进行测试。所有这些都在 RepeatedStratifiedKFold() 函数内部完成。

  93. Fatih 2021 年 11 月 5 日下午 9:25 #

    # 定义流水线
    步骤 = [(‘over’, SMOTE()), (‘model’, DecisionTreeClassifier())]
    管道 = Pipeline(steps=steps)
    # 评估流水线
    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)

    嗨,杰森。在这里,您直接将 smote 算法提供给交叉验证分数。这意味着它将首先应用 smote 算法,然后拆分数据集。所以我们也对将用于测试的折叠应用了 SMOTE。难道我们不应该先进行 smote,然后将数据集提供给 cross_val_score 以避免这种情况吗?

    • Adrian Tam
      Adrian Tam 2021 年 11 月 7 日上午 8:11 #

      不。管道将使用拆分数据集进行拟合,而不是整个数据集。这样做的步骤顺序是为了避免数据泄漏。

  94. Fatih 2021 年 11 月 5 日下午 9:32 #

    好吧,我知道这样做应该不会改变什么,但即使如此,我还是尝试了一下,令我惊讶的是。ROC AUC 分数平均增加了 0.1 个百分点,为什么会这样?
    新的 ROC AUC 分数
    > k=1,平均 ROC AUC:0.951
    > k=2,平均 ROC AUC:0.927
    > k=3,平均 ROC AUC:0.925
    > k=4,平均 ROC AUC:0.919
    > k=5,平均 ROC AUC:0.925
    > k=6,平均 ROC AUC:0.909
    > k=7,平均 ROC AUC:0.899

    使用这里的代码
    > k=1,平均 ROC AUC:0.835
    > k=2,平均 ROC AUC:0.825
    > k=3,平均 ROC AUC:0.840
    > k=4,平均 ROC AUC:0.855
    > k=5,平均 ROC AUC:0.846
    > k=6,平均 ROC AUC:0.830
    > k=7,平均 ROC AUC:0.845

    我的代码
    for k in k_values
    # 定义流水线
    model = DecisionTreeClassifier()
    over = SMOTE(sampling_strategy=0.1, k_neighbors=k)
    under = RandomUnderSampler(sampling_strategy=0.5)
    steps = [(‘over’, over), (‘under’, under)]
    管道 = Pipeline(steps=steps)
    X_t,y_t = pipeline.fit_resample(X,y)
    # 评估流水线
    cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
    scores = cross_val_score(model, X_t, y_t, scoring=’roc_auc’, cv=cv, n_jobs=-1)
    score = mean(scores)
    print(‘> k=%d,平均 ROC AUC:%.3f’ % (k,分数))

    • Adrian Tam
      Adrian Tam 2021 年 11 月 7 日上午 8:15 #

      你在这里做得对吗?我看到定义了“pipeline”,但您评估了“model”。

  95. Aminu Musa 2021 年 12 月 19 日上午 3:55 #

    你好 Jason,我正在处理一个平衡但实例很少的数据,每个类有 171 个实例,请指导我如何使用 smote 并增加(过采样)每个类,谢谢。

    • Adrian Tam
      Adrian Tam 2021 年 12 月 19 日下午 2:12 #

      我没有看到 imblearn 库允许您这样做。但是您可以故意向数据中添加一个虚假的多数类并应用 SMOTE。之后,您只需删除该虚假类。

  96. Hosein Kazemi 2022 年 1 月 14 日下午 9:50 #

    嗨,杰森,感谢您出色的网站,
    我已成功安装 imbalanced-learn,但是当我尝试导入 imblearn 时,它给我以下错误

    AttributeError: partially initialized module 'logging' has no attribute 'StreamHandler' (most likely due to a circular import)

    你知道我怎么解决这个问题吗?

    提前感谢您的回答。

  97. Eva 2022 年 1 月 24 日上午 4:16 #

    嗨,杰森,感谢您所有帖子中清晰且信息丰富的教程。对于这些欠采样/过采样方法或更改权重方法,我有一个问题,在验证/测试步骤中,在训练阶段之后我们不需要进行缩放还原吗?谢谢。

    • James Carmichael 2022 年 2 月 13 日下午 1:11 #

      你好伊娃……建议在验证期间计算性能指标时对数据进行逆变换。

  98. AGGELOS PAPOUTSIS 2022 年 2 月 15 日上午 2:39 #

    大家好。请问一个问题。当我们使用 smote 时,我们得到了类别平衡。在这种情况下,我们可以使用准确率作为我们的指标吗?还是我们仍然必须使用这里的一些指标 https://machinelearning.org.cn/tour-of-evaluation-metrics-for-imbalanced-classification/

  99. Tomás 2022 年 2 月 17 日上午 1:01 #

    嗨,杰森,我昨天发现了您的网站,我对您的内容感到惊讶。

    我有个问题
    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()

    这个循环是如何工作的?

    非常感谢。

    • James Carmichael 2022 年 2 月 17 日下午 1:20 #

      嗨,托马斯……我的建议是在您的 Python 环境中实现这样的功能,以便最好地理解。换句话说,尝试使用它以了解更多信息。

  100. John 2022 年 4 月 13 日下午 8:46 #

    如果您想在应用 SMOTE 和欠采样后,将数组转换回数据帧并进行特征选择或排名,该怎么做?

  101. Evan 2022 年 4 月 26 日下午 5:39 #

    正如 Jason 指出的,当特征是数值时,SMOTE 生成的合成样本是原始样本的凸组合。SMOTE 如何处理分类特征?一种天真的方法是使用组件样本中的主导类别,但我没有在任何论文中看到过这种方法。

  102. Jakob 2022 年 5 月 6 日下午 7:48 #

    感谢 Jason 的精彩解释。

  103. Ali 2022 年 6 月 11 日上午 3:10 #

    您的博客真的很棒。

    • James Carmichael 2022 年 6 月 11 日上午 9:02 #

      感谢您的宝贵反馈!

  104. Ali 2022 年 6 月 24 日上午 10:04 #

    非常感谢。
    我尝试使用“from imblearn.over_sampling import SMOTE”
    但是 Python 说
    No module named 'imblearn'
    于是,我尝试安装它。我使用了以下命令行
    “!pip install -U imbalanced-learn”
    仍然是同样的错误。
    我该怎么办?
    提前感谢您的时间

    • James Carmichael 2022 年 6 月 25 日上午 7:10 #

      你好阿里……您可能希望在研究纠正本地环境的选项时尝试使用 Google Colab。

  105. Marc 2022 年 7 月 3 日上午 1:12 #

    很棒的文章和教程,谢谢。
    在我的案例中,我有一个 16/84 的不平衡数据集,并使用和不使用 SMOTE 对多个估计器进行了多次测试。我在没有 SMOTE 的情况下总体上取得了更好的结果(F1 和 Matthew Corr)。我应该保持不平衡吗?

    • James Carmichael 2022 年 7 月 3 日下午 1:08 #

      嗨,马克……我发现您的建议没有任何问题。您已经实现了您的模型了吗?请告诉我们您的发现。

  106. y 2022 年 9 月 15 日下午 9:07 #

    感谢您的本教程。在 SMOTE 的上一个示例中,数据有两个 x 特征,如果数据集有多个 x,那么散点图中的 x 轴和 y 轴代表什么?

  107. Shriraj 2022 年 11 月 30 日上午 9:17 #

    嘿,詹姆斯,

    为什么在 SMOTE 中,使用线性近似来复制数据点有效?为什么不能是非线性的?

    • James Carmichael 2022 年 12 月 1 日上午 8:24 #

      嗨,Shriraj……还有其他合适的方法可以使用。您是否应用过非线性方法?

  108. Marta 2022 年 12 月 28 日上午 4:04 #

    你好詹姆斯,谢谢你的辛勤工作!

    您知道 SMOTE 方法是否可以应用于无监督学习(聚类)吗?

    我正在尝试准备数据以应用聚类,我不明白在这种情况下是否应该“纠正”不平衡数据。

  109. Nishant 2023 年 5 月 24 日下午 9:44 #

    你好 Jason,
    希望您能阅读此查询。

    想知道如果使用 SMOTE,如何获得最终的生产模型?
    一般来说,在交叉验证对结果满意后,我们会结合所有数据拆分,并对整个数据应用/重复使用从交叉验证获得的最佳超参数。在重采样的情况下——我们是否平衡整个数据以获得生产模型?

  110. Mohammad 2023年6月12日 早上6:30 #

    你好,

    非常感谢您分享您的机器学习知识!

    假设我们有一个不平衡的数据集(1:100)。由于数据集应该进行分层,训练集、验证集和测试集这三个子集具有相同的比例。现在,如果我们只对训练子集应用SMOTE以获得例如1:2的比例,那么其他两个子集将保持相同的不平衡1:100比例。

    我的理解正确吗?

    因此,我不明白在存在上述问题的情况下,SMOTE如何能提高性能。

    谢谢你,
    Mohammad

  111. Abitama 2023年10月24日 下午3:36 #

    你好 Jason,感谢您分享本教程

    顺便问一下,您能否解释一下您是如何只对训练数据集应用过采样操作的?我没有在您的代码示例中看到训练集-测试集分割。

  112. Sasadhar 2023年12月13日 下午1:02 #

    !pip install scikit-learn
    !pip install imblearn

    from imblearn.over_sampling import SVMSMOTE

    显示错误
    无法从“sklearn.utils._param_validation”(C:\Users\Acer\anaconda3\Lib\site-packages\sklearn\utils\_param_validation.py)导入名称“_MissingValues”

    我无法解决这个问题。

    请告诉我如何解决此问题或使用 sklearn 和 imblearn 的替代方法。

  113. George 2024年2月28日 下午4:54 #

    你好,

    您有 SMOTE + GAN 采样的示例吗?

  114. sherif 2024年7月17日 下午1:10 #

    你好,
    如何检查生成数据的质量?

    • James Carmichael 2024年7月18日 早上8:28 #

      在使用合成少数过采样技术(SMOTE)时检查生成数据的质量至关重要,以确保合成样本合理且不会将噪声或偏差引入数据集。以下是评估SMOTE生成的合成数据质量的一些步骤和技术。

      ### 1. 目视检查
      – **散点图**:如果特征数量较少,可以在2D或3D空间中绘制原始数据和合成数据。这有助于直观地评估合成样本是否与少数类良好重叠。

      r
      library(ggplot2)

      # 假设您有一个数据框“data”,其中包含特征“feature1”和“feature2”
      # 以及一个指示类别标签的“Class”列
      ggplot(data, aes(x = feature1, y = feature2, color = Class)) +
      geom_point() +
      theme_minimal() +
      ggtitle("原始数据和SMOTE生成数据的散点图")

      ### 2. 统计度量
      – **特征分布比较**:使用Kolmogorov-Smirnov检验等统计测试或直方图和密度图等可视化工具,比较原始数据和合成数据之间的特征分布。

      r
      # 特征分布的Kolmogorov-Smirnov检验
      ks.test(original_data$feature1, synthetic_data$feature1)

      – **汇总统计**:比较原始少数类和合成数据中特征的均值、方差、偏度和峰度。

      r
      summary(original_data$feature1)
      summary(synthetic_data$feature1)

      ### 3. 机器学习性能
      – **分类器性能**:在增强数据集上训练分类器,并使用交叉验证评估其性能。F1分数、召回率和精确度等指标的改进表明合成数据质量良好。

      r
      library(caret)

      # 假设您有一个训练数据集“trainData”和标签“trainLabels”
      control <- trainControl(method = "cv", number = 10) model <- train(Class ~ ., data = trainData, method = "rf", trControl = control) print(model)

      ### 4. 聚类分析
      - **聚类技术**:使用聚类算法(例如,k-means,DBSCAN)来查看合成样本是否与原始少数类很好地聚类。聚类不良可能表明合成样本质量较低。

      r
      library(cluster)
      clustering <- kmeans(rbind(original_data, synthetic_data), centers = 2) plot(original_data$feature1, original_data$feature2, col = clustering$cluster) points(synthetic_data$feature1, synthetic_data$feature2, col = clustering$cluster, pch = 2)

      ### 5. 最近邻分析
      - **K-最近邻(KNN)距离**:计算合成样本到其在原始少数类中的最近邻居的平均距离。距离过大可能表明合成样本是异常值。

      r
      library(FNN)
      knn_distances <- get.knnx(data = original_data[, c("feature1", "feature2")], query = synthetic_data[, c("feature1", "feature2")], k = 5)$nn.dist mean(knn_distances)

      ### 6. 平衡检查
      - **类别比例**:应用SMOTE后,确保类别比例平衡或达到所需水平。SMOTE后不平衡可能表示实施存在问题。

      r
      table(new_data$Class)

      ### R语言中的示例实现

      以下是在R语言中应用和评估SMOTE的示例:

      r
      library(DMwR)
      library(ggplot2)

      # 示例数据集
      data(iris)
      iris <- iris[iris$Species != "setosa", ] # 删除一个类别进行二元分类 # 应用SMOTE set.seed(123) smote_data <- SMOTE(Species ~ ., data = iris, perc.over = 200, perc.under = 200) # 目视检查 ggplot(smote_data, aes(x = Petal.Length, y = Petal.Width, color = Species)) + geom_point() + theme_minimal() + ggtitle("原始数据和SMOTE生成数据的散点图") # 统计度量 ks.test(iris$Petal.Length, smote_data$Petal.Length) summary(iris$Petal.Length) summary(smote_data$Petal.Length) # 分类器性能 control <- trainControl(method = "cv", number = 10) model <- train(Species ~ ., data = smote_data, method = "rf", trControl = control) print(model) # 最近邻分析 knn_distances <- get.knnx(data = iris[, c("Petal.Length", "Petal.Width")], query = smote_data[smote_data$Species == "versicolor", c("Petal.Length", "Petal.Width")], k = 5)$nn.dist mean(knn_distances) # 平衡检查 table(smote_data$Species)

      这种方法结合了多种方法,以全面评估SMOTE生成的合成数据的质量。

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。