scikit-learn 中的 class_weight 参数如何工作?

2023-11-29

我很难理解如何class_weightscikit-learn 的逻辑回归中的参数运行。

情况

我想使用逻辑回归对非常不平衡的数据集进行二元分类。这些类别被标记为 0(阴性)和 1(阳性),观察到的数据比例约为 19:1,大多数样本具有阴性结果。

第一次尝试:手动准备训练数据

我将拥有的数据分成不相交的数据集进行训练和测试(大约 80/20)。然后我手工对训练数据进行随机采样,得到比19:1不同比例的训练数据;从 2:1 -> 16:1。

然后,我在这些不同的训练数据子集上训练逻辑回归,并绘制召回率 (= TP/(TP+FN)) 作为不同训练比例的函数。当然,召回率是根据观察到的比例为 19:1 的不相交 TEST 样本计算的。请注意,虽然我在不同的训练数据上训练了不同的模型,但我在相同(不相交)的测试数据上计算了所有模型的召回率。

结果正如预期的那样:在 2:1 的训练比例下,召回率约为 60%,当达到 16:1 时,召回率下降得相当快。有几个比例为 2:1 -> 6:1,召回率远高于 5%。

第二次尝试:网格搜索

接下来,我想测试不同的正则化参数,因此我使用 GridSearchCV 并制作了一个由多个值组成的网格C参数以及class_weight范围。将我的 n:m 比例的负:正训练样本翻译成字典语言class_weight我以为我只是指定几个字典如下:

{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 }   #expected 4:1

我还包括None and auto.

这一次的结果完全出乎意料。对于每个值,我的所有回忆都很小(class_weight except auto。所以我只能假设我对如何设置的理解class_weight字典错了。有趣的是,class_weight对于所有值,网格搜索中“auto”的值约为 59%C,我猜它平衡为 1:1?

我的问题

  1. 你如何正确使用class_weight在训练数据中实现与实际提供的数据不同的平衡?具体来说,我传递给什么字典class_weight使用 n:m 比例的负:正训练样本?

  2. 如果你通过了各种class_weight字典到 GridSearchCV,在交叉验证期间,它会根据字典重新平衡训练折叠数据,但使用真实的给定样本比例来计算测试折叠上的评分函数吗?这一点至关重要,因为任何指标只有来自观察到的比例的数据才对我有用。

  3. 什么是auto的价值class_weight尽量按比例做?我阅读了文档,我认为“平衡数据与其频率成反比”只是意味着它使其达到 1:1。它是否正确?如果没有,有人可以澄清吗?


首先,仅仅依靠回忆可能并不好。通过将所有内容分类为正类,您可以简单地实现 100% 的召回率。 我通常建议使用 AUC 来选择参数,然后找到您感兴趣的操作点(例如给定的精度水平)的阈值。

For how class_weight有效:它会惩罚样本中的错误class[i] with class_weight[i]而不是 1。所以较高的班级权重意味着您想要更加重视某个班级。从你的说法来看,0 类的出现频率似乎是 1 类的 19 倍。所以你应该增加class_weight类 1 相对于类 0,例如 {0:.1, 1:.9}。 如果class_weight总和不等于 1,它基本上会改变正则化参数。

For how class_weight="auto"有效,你可以看看这次讨论。 在开发版本中您可以使用class_weight="balanced",这更容易理解:它基本上意味着复制较小的类,直到拥有与较大类中的样本一样多的样本,但以隐式方式进行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

scikit-learn 中的 class_weight 参数如何工作? 的相关文章

随机推荐