繁体   English   中英

处理二分类中的类不平衡

[英]Dealing with the class imbalance in binary classification

这是我的问题的简要说明:

  1. 我正在从事一项监督学习任务来训练二元分类器。
  2. 我有一个大类不平衡分布的数据集:8 个负实例,每个正实例。
  3. 我使用f-measure ,即特异性和灵敏度之间的调和平均值,来评估分类器的性能。

我绘制了几个分类器的 ROC 图,并且都呈现出很好的 AUC,这意味着分类很好。 然而,当我测试分类器并计算 f-measure 时,我得到了一个非常低的值。 我知道这个问题是由数据集的类偏度引起的,到目前为止,我发现了两种解决方法:

  1. 通过为数据集的实例分配权重来采用成本敏感的方法(请参阅此帖子
  2. 对分类器返回的预测概率进行阈值处理,以减少误报和漏报的数量。

我选择了第一个选项,这解决了我的问题(f-measure 令人满意)。 但是,现在,我的问题是:这些方法中哪一种更可取? 有什么区别?

PS:我将 Python 与 scikit-learn 库一起使用。

加权(成本敏感)和阈值处理都是成本敏感学习的有效形式。 简而言之,您可以将两者想象如下:

权重

基本上有人断言,对稀有类别进行错误分类的“成本”比对普通类进行错误分类更糟糕。 这在诸如SVM,ANN和随机森林之类的算法中应用于算法级别 这里的限制包括算法是否可以处理权重。 此外,这方面的许多应用试图解决进行更严重的错误分类的想法(例如,将患有胰腺癌的人分类为无癌症)。 在这种情况下,您知道为什么要确保即使在不平衡的设置中也要对特定类进行分类。 理想情况下,您希望像任何其他模型参数一样优化成本参数。

阈值

如果算法返回概率 (或其他一些分数),则可以在构建模型后应用阈值。 基本上,您将分类阈值从50-50更改为适当的权衡级别。 这通常可以通过生成评估度量的曲线(例如,F-度量)来优化。 这里的限制是你正在做出绝对的权衡。 截止值的任何修改都将降低预测其他类别的准确性。 如果您的大多数普通班级的概率非常高(例如大多数超过0.85),那么您更有可能使用此方法取得成功。 它也与算法无关(假设算法返回概率)。

采样

采样是应用于不平衡数据集的另一种常见选项,可为类分布带来一些平衡。 基本上有两种基本方法。

欠采样

提取较小的多数实例集并保留少数实例。 这将导致较小的数据集,其中类之间的分布更接近; 但是,您丢弃了可能有价值的数据。 如果您拥有大量数据,这也可能是有益的。

过采样

通过复制它们来增加少数群体实例的数量。 这将导致更大的数据集保留所有原始数据,但可能会引入偏差。 但是,随着您增加大小,您可能也会开始影响计算性能。

高级方法

还有一些更复杂的方法可以帮助解决潜在的偏见。 这些方法包括如SMOTESMOTEBoostEasyEnsemble在此引用之前问题就不平衡数据集和CSL。

建筑模型

关于使用不平衡数据构建模型的另一个注意事项是,您应该牢记您的模型指标。 例如,F-measures等指标未考虑真实的负利率。 因此,通常建议在不平衡设置中使用Cohen的kappa指标等指标

在尝试解决问题之前(我认为@cdeterman 的回答彻底涵盖了这一点),最好先定义度量。

除了像 Cohen 的 kappa 这样的“多合一”指标外,我发现仅计算问题中每个类别的通用指标(例如精度、召回率和 f 度量)非常有用。 Scikit-learn 的分类报告可以很方便地做到这一点:

from sklearn.metrics import classification_report
print(classification_report(test_df['target'], model.predict(test_df[features])))

              precision    recall  f1-score   support

           0       0.99      1.00      0.99      2640
           1       0.94      0.73      0.82        84

    accuracy                           0.99      2724
   macro avg       0.96      0.86      0.91      2724
weighted avg       0.99      0.99      0.99      2724

如果您想要更直观的输出,您可以使用Deepchecks内置检查之一(披露 - 我是维护者之一):

from deepchecks.checks import PerformanceReport
from deepchecks import Dataset
PerformanceReport().run(Dataset(train_df, label='target'), Dataset(test_df, label='target'), model)

使用此类每类指标会从一开始就提醒您您的模型在某些类(以及哪些类)上表现不佳。 在使用一些对成本敏感的学习之后再次运行它会让你知道你是否设法平衡了课程之间的表现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM