不平衡分类的成本敏感逻辑回归

逻辑回归不直接支持不平衡分类。

相反,用于拟合逻辑回归模型的训练算法必须进行修改,以考虑倾斜的分布。这可以通过指定一个类权重配置来实现,该配置用于影响训练期间逻辑回归系数的更新量。

权重可以对多数类示例上的错误给予较少的惩罚,而对少数类示例上的错误给予更多的惩罚。结果是逻辑回归的一个版本,它在不平衡分类任务上表现更好,通常被称为成本敏感或加权逻辑回归。

在本教程中,您将了解用于不平衡分类的成本敏感逻辑回归。

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

  • 标准逻辑回归如何不支持不平衡分类。
  • 如何修改逻辑回归以在拟合系数时根据类权重对模型误差进行加权。
  • 如何为逻辑回归配置类权重以及如何网格搜索不同的类权重配置。

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

让我们开始吧。

  • 2020 年 2 月更新:修复了权重计算中的一个错字。
  • 2020 年 10 月更新:修复了平衡比描述中的一个错字。
Cost-Sensitive Logistic Regression for Imbalanced Classification

不平衡分类的成本敏感逻辑回归
图片由 Naval S 拍摄,保留部分权利。

教程概述

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

  1. 不平衡分类数据集
  2. 用于不平衡分类的逻辑回归
  3. 使用 Scikit-Learn 的加权逻辑回归
  4. 网格搜索加权逻辑回归

不平衡分类数据集

在我们深入探讨不平衡分类的逻辑回归修改之前,让我们首先定义一个不平衡分类数据集。

我们可以使用 make_classification() 函数来定义一个合成的不平衡二分类数据集。我们将生成 10,000 个示例,其中少数类与多数类的比例约为 1:100。

生成后,我们可以总结类别分布,以确认数据集的创建符合预期。

最后,我们可以创建一个样本的散点图,并根据类别标签对其进行着色,以帮助理解对该数据集中的样本进行分类的挑战。

综合起来,生成合成数据集并绘制样本的完整示例如下所示。

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

我们可以看到数据集的类别分布约为1:100,多数类有不到10,000个样本,少数类有100个样本。

接下来,创建数据集的散点图,显示多数类(蓝色)的大量样本和少数类(橙色)的少量样本,并存在一些适度的类别重叠。

Scatter Plot of Binary Classification Dataset With 1 to 100 Class Imbalance

具有1比100类别不平衡的二元分类数据集散点图

接下来,我们可以使用标准逻辑回归模型对数据集进行拟合。

我们将使用重复交叉验证来评估模型,其中包含三次 10 折交叉验证。模型性能将使用在重复和所有折叠中平均的 ROC 曲线下面积 (ROC AUC) 来报告。

总而言之,下面列出了在不平衡分类问题上评估标准逻辑回归的完整示例。

运行该示例,评估不平衡数据集上的标准逻辑回归模型,并报告平均 ROC AUC。

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

我们可以看到该模型具有技能,ROC AUC 高于 0.5,在这种情况下,平均分数为 0.985。

这为对标准逻辑回归算法执行的任何修改提供了比较基准。

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

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

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

用于不平衡分类的逻辑回归

逻辑回归是二分类任务的有效模型,但默认情况下,它在不平衡分类中无效。

逻辑回归可以进行修改以更好地适用于逻辑回归。

逻辑回归算法的系数使用优化算法进行拟合,该算法最小化训练数据集上模型的负对数似然(损失)

  • 最小化 sum i to n -(log(yhat_i) * y_i + log(1 – yhat_i) * (1 – y_i))

这涉及重复使用模型进行预测,然后根据减少模型损失的方向调整系数。

可以修改给定系数集的损失计算,以考虑类别平衡。

默认情况下,每个类别的错误可能被认为是具有相同的权重,例如 1.0。这些权重可以根据每个类别的重要性进行调整。

  • 最小化 sum i to n -(w0 * log(yhat_i) * y_i + w1 * log(1 – yhat_i) * (1 – y_i))

权重应用于损失,因此较小的权重值会导致较小的误差值,进而减少模型系数的更新。较大的权重值会导致较大的误差计算,进而增加模型系数的更新。

  • 小权重:重要性较低,模型系数更新较少。
  • 大权重:重要性较高,模型系数更新较多。

因此,修改后的逻辑回归版本被称为加权逻辑回归、类加权逻辑回归或成本敏感逻辑回归。

这些权重有时被称为重要性权重。

尽管加权逻辑回归实现起来很简单,但挑战在于为每个类别选择要使用的权重。

使用 Scikit-Learn 的加权逻辑回归

scikit-learn Python 机器学习库提供了支持类权重的逻辑回归实现。

LogisticRegression 类提供了 class_weight 参数,可以将其指定为模型超参数。class_weight 是一个字典,定义了每个类别标签(例如 0 和 1)以及在拟合模型时计算负对数似然时要应用的权重。

例如,类别 0 和 1 的 1 比 1 权重可以定义如下:

类别加权可以通过多种方式定义;例如:

  • 领域专业知识,通过与主题专家交谈确定。
  • 调优,通过超参数搜索(如网格搜索)确定。
  • 启发式方法,使用一般的最佳实践指定。

使用类别加权的最佳实践是使用训练数据集中类别分布的倒数。

例如,训练数据集的类别分布是少数类与多数类的比例为 1:100。这种比例的倒数可以用于多数类为 1,少数类为 100;例如

我们也可以使用分数定义相同的比例,并达到相同的结果;例如

我们可以使用上一节中定义的相同评估程序来评估具有类权重的逻辑回归算法。

我们预计加权类别的逻辑回归版本将比不带任何类别权重的标准逻辑回归版本表现更好。

完整的示例如下所示。

运行示例会准备合成的不平衡分类数据集,然后使用重复交叉验证评估加权类别的逻辑回归版本。

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

报告了平均 ROC AUC 分数,在这种情况下,显示的分数优于未加权版本的逻辑回归,为 0.989,而未加权版本为 0.985。

scikit-learn 库提供了类别权重最佳实践启发式的实现。

它通过 compute_class_weight() 函数实现,计算方式为

  • n_samples / (n_classes * n_samples_with_class)

我们可以手动测试我们数据集上的这个计算。例如,我们数据集中有 10,000 个示例,其中 9900 个在类别 0 中,100 个在类别 1 中。

类别 0 的权重计算如下

  • 权重 = 样本数 / (类别数 * 该类别样本数)
  • 权重 = 10000 / (2 * 9900)
  • 权重 = 10000 / 19800
  • 权重 = 0.05

类别 1 的权重计算如下

  • 权重 = 样本数 / (类别数 * 该类别样本数)
  • 权重 = 10000 / (2 * 100)
  • 权重 = 10000 / 200
  • 权重 = 50

我们可以通过调用 compute_class_weight() 函数并指定 class_weight 为“balanced”来确认这些计算。例如

运行示例,我们可以看到类别 0 的权重约为 0.5,类别 1 的权重约为 50。

这些值与我们手动计算的结果相符。

这些值也与我们上面对训练数据集中类别分布比例倒数启发式计算的结果相符;例如

  • 0.5:50 == 1:100

我们可以通过将 class_weight 参数设置为 'balanced',直接将默认的类平衡用于 LogisticRegression 类。例如

完整的示例如下所示。

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

运行示例会得到与我们手动指定逆类比率相同的平均 ROC AUC。

网格搜索加权逻辑回归

使用训练数据逆比例的类别权重只是一种启发式方法。

使用不同的类别权重可能会获得更好的性能,这也将取决于用于评估模型的性能指标的选择。

在本节中,我们将对加权逻辑回归的不同类别权重范围进行网格搜索,并发现哪个结果能获得最佳的 ROC AUC 分数。

我们将尝试以下类别 0 和 1 的权重:

  • {0:100,1:1}
  • {0:10,1:1}
  • {0:1,1:1}
  • {0:1,1:10}
  • {0:1,1:100}

这些可以定义为 GridSearchCV 类的网格搜索参数,如下所示

我们可以使用重复交叉验证对这些参数执行网格搜索,并使用 ROC AUC 评估模型性能。

执行后,我们可以总结最佳配置以及所有结果,如下所示:

综上所述,下面的示例网格搜索了不平衡数据集上逻辑回归的五种不同类别权重。

我们可能会期望启发式类别加权是表现最好的配置。

运行示例会使用重复的k折交叉验证评估每个类别权重,并报告最佳配置和相关的平均ROC AUC分数。

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

在这种情况下,我们可以看到1:100多数类与少数类加权取得了最佳的平均ROC分数。这与通用启发式方法的配置相符。

探索更极端的类别权重以查看它们对平均ROC AUC分数的影响可能会很有趣。

进一步阅读

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

论文

书籍

API

总结

在本教程中,您学习了用于不平衡分类的成本敏感逻辑回归。

具体来说,你学到了:

  • 标准逻辑回归如何不支持不平衡分类。
  • 如何修改逻辑回归以在拟合系数时根据类权重对模型误差进行加权。
  • 如何为逻辑回归配置类权重以及如何网格搜索不同的类权重配置。

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

掌控不平衡分类!

Imbalanced Classification with Python

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

...只需几行python代码

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

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

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

查看内容

成本敏感逻辑回归用于不平衡分类的 34 条回复

  1. Elie 2020 年 1 月 27 日上午 7:11 #

    杰森,书快读完了。

    真是太棒了!

    一个小小的建议:我希望看到更多关于算法的解释性信息图。

    • Jason Brownlee 2020 年 1 月 27 日上午 7:40 #

      为你的进步喝彩!

      很好的建议,谢谢。

  2. Rodney Silva 2020 年 1 月 27 日上午 10:18 #

    我希望看到少数类的精确率和召回率有所提高。

  3. marco 2020 年 1 月 29 日上午 2:42 #

    你好 Jason,
    关于 SVC 和 linearSVC 的问题。
    有什么区别?
    我正在尝试使用 1000 个观测值(750 个训练 + 250 个测试)进行情感分析。
    对于分析,使用 SVC 还是 linearSVC 更好?
    linearSVC 中 C 超参数的含义是什么(简单来说)?
    我发现 C 参数在其他算法中也很常见。含义是否相同?
    谢谢

  4. Diane Halliwell 2020 年 1 月 30 日上午 6:58 #

    您的书是否涵盖了依赖于示例的成本敏感分类?

  5. Temitope Mamukuyomi 2020 年 1 月 31 日上午 8:22 #

    感谢您的教程

  6. macilane manjate 2020 年 1 月 31 日下午 3:43 #

    亲爱的 Jason Browniee,
    早上好。
    您什么时候会有 R 语言版本的书。
    诚挚的问候,
    Macilane

    • Jason Brownlee 2020 年 2 月 1 日上午 5:46 #

      目前没有计划。鉴于 Python 是目前最流行的机器学习语言,我的重点是 Python。

  7. Sergio Garcia Garcia 2020 年 1 月 31 日下午 7:53 #

    “例如,我们的数据集中有 10,000 个示例,其中 9990 个在类别 0 中,100 个在类别 1 中。”

    不是 9990-10 或 9900-100 吗?

    好文章,解释清晰

  8. Carlos 2020 年 2 月 7 日上午 3:20 #

    您能提供“Counter”的代码吗?
    NameError: 名称 'Counter' 未定义
    谢谢你

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

      您必须复制包含重要语句的完整代码示例。

  9. Atefeh 2020 年 4 月 12 日上午 4:19 #

    感谢您的出色工作。这非常有帮助。我正在寻找如何同时使用分类和回归模型来解决特定问题?假设我想研究气温与土壤温度之间的关系,同时使用分类和回归模型,以获得最佳拟合和决策边界。有没有任何文章可以说明这两种方法的步骤会有何不同?

    • Jason Brownlee 2020 年 4 月 12 日上午 6:25 #

      不客气。

      抱歉,我没有这方面的例子。

  10. John Sammut 2020 年 5 月 9 日上午 7:03 #

    你好 Jason,

    感谢又一篇精彩文章。

    我假设对数据集进行过采样和欠采样的替代方法(而不是使用类别权重)也适用于逻辑回归。

    我说的对吗?

    如果我没错,您会建议在面对不平衡数据集时同时采用这两种方法并比较结果吗?

    谢谢你。

    • Jason Brownlee 2020 年 5 月 9 日下午 1:46 #

      是的,您可以使用重采样数据而不是使用成本敏感分类器。

      不,结合这两种方法并没有帮助,因为重采样后类别会平衡。尽管如此,还是可以尝试一下!也许您会发现一些不直观的东西?

  11. ChiSu 2020 年 8 月 11 日上午 1:52 #

    你好,

    好文!

    您能否也添加关于如何在未见测试数据集上部署此模型的代码?

    谢谢

  12. Mario USECHE 2020 年 10 月 17 日上午 3:37 #

    嗨,Jason,
    感谢您的教程。它们激励我购买了您的《使用 Python 进行不平衡分类》一书。
    我正在尝试将本教程应用于多标签分类问题。我正在努力弄清楚如何在 cross_val_score 方法中正确设置评分指标。
    任何提示都将不胜感激。
    此致,
    马里奥

    • Jason Brownlee 2020 年 10 月 17 日上午 6:13 #

      谢谢!

      您可以将要优化的指标指定给 cross_val_score 函数。

  13. Sweta Prasad 2020 年 11 月 10 日上午 9:09 #

    R 中可以使用逻辑回归、决策树和随机森林进行成本敏感学习吗?

  14. 一位日本学生 2020 年 12 月 16 日下午 5:02 #

    感谢这篇精彩的文章。它非常有帮助!
    我有一个问题想请教您。
    “sklearn.linear_model.LogisticRegression”这个类默认模型是否使用最大似然估计和 lbfgs 来估计参数?如果是,这是否意味着 sklearn 的类使用 lbfgs 是因为我们不能使用解析解来最小化负对数似然损失?
    抱歉我的英语不好。

    • Jason Brownlee 2020 年 12 月 17 日上午 6:33 #

      不客气。

      是的,它使用 MLE 并使用二阶优化算法,因为没有稳定的解析解。

      • 一位日本学生 2020 年 12 月 17 日下午 8:53 #

        谢谢您的回复!

  15. Jacob 2021 年 10 月 8 日下午 7:03 #

    您一开始提到

    “逻辑回归不直接支持不平衡分类。”

    您有支持这一说法的理论或理论论文吗?

    • Adrian Tam
      Adrian Tam 2021 年 10 月 13 日上午 5:28 #

      想想您如何在逻辑回归中计算误差分数。然后您会发现不平衡分类会偏向多数类别。

  16. Liz 2023 年 8 月 4 日晚上 11:50 #

    感谢所有全面的教程!
    我想知道是否可以使用 sklearn 对聚类数据进行具有稳健标准误差的逻辑回归?
    我的网络搜索没有找到 sklearn 的任何结果(只找到了 statsmodel,但它有一些其他缺点)。
    我有一个数据集,其中包含来自 15 个研究地点的观测值,并且假设一个研究地点内观测值之间的方差小于研究地点之间。因此,我们希望计算考虑聚类(研究地点)的稳健标准误差。
    有人知道 sklearn 是否可以做到这一点吗?

发表回复

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