【问题标题】:Dealing with the class imbalance in binary classification处理二元分类中的类不平衡
【发布时间】:2023-03-17 03:35:01
【问题描述】:

以下是我的问题的简要说明:

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

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

  1. 通过为数据集的实例分配权重来采用成本敏感方法(参见post
  2. 阈值化分类器返回的预测概率,以减少误报和误报的数量。

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

P.S:我正在使用 Python 和 scikit-learn 库。

【问题讨论】:

  • 这更像是一个统计问题而不是编程问题。目前还不清楚这些模型是如何构建的。你的数据集有多大?您是否使用了分层 CV,或者您如何确定您没有过度拟合您的模型(因此 F 值较低)?也就是说,一般而言,我会遵从 cost-sensitive,因为 thresholding 方法对于指定截止值(恕我直言)的用户更为主观。
  • 我有 3000 个实例,是的,我确实使用了 10 倍分层 CV 来防止过度拟合。
  • 我遇到了二进制分类问题,其中存在 97%/3% 的偏度。平衡训练用例的数量,大大提高了 3% 端的预测。我之前没有在我的分类器中尝试过阈值化。
  • 可能有点晚了,但我们最近研究了这个问题并表明阈值处理效果更好,并且与 bagging ensemble 结合起来也更灵活。请参阅“Reviving Threshold-Moving:用于二进制和多类不平衡数据的简单插件 Bagging Ensemble”arxiv.org/abs/1606.08698。我希望这会有所帮助。

标签: python r machine-learning classification


【解决方案1】:

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

权重

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

阈值

如果算法返回概率(或其他分数),则可以在建立模型后应用阈值。本质上,您将分类阈值从 50-50 更改为适当的权衡级别。这通常可以通过生成评估指标的曲线(例如 F-measure)来优化。这里的限制是你在做绝对的权衡。对截止值的任何修改都会反过来降低预测其他类别的准确性。如果您的大多数常见类的概率都非常高(例如,大多数高于 0.85),那么您更有可能通过这种方法获得成功。它也是独立于算法的(假设算法返回概率)。

抽样

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

欠采样

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

过采样

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

高级方法

还有其他更“复杂”的方法可以帮助解决潜在的偏见。其中包括 SMOTESMOTEBoostEasyEnsemble 等方法,正如 prior question 中提到的关于不平衡数据集和 CSL 的方法。

模型构建

关于使用不平衡数据构建模型的另一个注意事项是,您应该牢记您的模型指标。例如,诸如 F-measures 之类的指标没有考虑到真正的否定率。因此,通常建议在不平衡的设置中使用 Cohen’s kappa metric 等指标。

【讨论】:

  • 我还要补充一点,下采样/上采样是第三种选择。丢弃多数类,直到你有 50/50 的拆分(或在多类情况下的统一拆分)。这在理论上不如加权有吸引力,但如果您有大量数据,则具有实用优势。
  • @BenAllison,你是对的,过采样/欠采样是其他选项。鉴于问题仅与加权和阈值有关,我省略了。我添加了关于采样的部分,以便更加彻底。
【解决方案2】:

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

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

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)

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

【讨论】:

    猜你喜欢
    • 2019-08-27
    • 2013-12-26
    • 2016-06-19
    • 2020-06-27
    • 2017-04-19
    • 2021-06-28
    • 2016-05-11
    • 2018-03-27
    • 1970-01-01
    相关资源
    最近更新 更多