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

我很难理解scikit-learn的Logistic回归中的class_weight参数是如何运作的。

情况

我想用逻辑回归来对非常不平衡的数据集进行二元分类。 这些类别被标记为0(负)和1(正),并且观察到的数据与大多数样品具有负面结果的比率约为19:1。

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

我将这些数据分成了不相交的集合,用于训练和testing(约80/20)。 然后我手工对训练数据进行随机抽样,得到不同比例的训练数据,比例为19:1; 从2:1 – > 16:1。

然后,我对这些不同的训练数据子集进行逻辑回归训练,并作为不同训练比例的函数绘制回忆(= TP /(TP + FN))。 当然,召回是在不相交的TEST样品上计算出来的,其比例为19:1。 请注意,尽pipe我在不同的训练数据上训练了不同的模型,但我还是在相同的(不相交的)testing数据上计算了所有的模型。

结果如预期:在2:1的训练比例下,回收率约为60%,到达16:1时相当快地下降。 召回率在5%以上的比例为2:1 – > 6:1。

第二次尝试:网格search

接下来,我想testing不同的正则化参数,所以我使用了GridSearchCV,并创build了一个包含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 

我也包括Noneauto

这一次结果完全被摧毁了。 除了auto之外,我所有的召回都是很小的(<0.05)。 所以我只能假设我对如何设置class_weight字典的理解是错误的。 有趣的是,在网格search中,“auto”的class_weight值对于C所有值都大约为59%,我猜想它平衡到1:1。

我的问题

1)您如何正确使用class_weight来实现您实际给予的训练数据的不同平衡? 具体来说,我传递给class_weight字典使用n:m比例的否定:正面训练样本?

2)如果您将各种class_weight字典传递给GridSearchCV,那么在交叉validation期间,它将根据字典重新平衡训练折叠数据,但是使用真实的给定样本比例来计算testing折叠上的评分函数? 这是至关重要的,因为任何度量标准对于我来说都是有用的,如果它来自于观察比例的数据。

3) class_weightauto价值是什么比例? 我阅读文档,我假设“平衡数据与其频率成反比”就意味着它使它成为1:1。 它是否正确? 如果没有,有人可以澄清?

非常感谢,任何澄清将不胜感激!

首先,单单回顾可能并不好。 您可以简单地通过将所有内容归类为正面类来实现100%的回忆。 我通常build议使用AUC来select参数,然后find您感兴趣的操作点(比如给定的精确度)的阈值。

对于class_weight是如何工作的:它用class_weight[i]而不是1来惩罚class[i]样本中的错误。因此,更高的类别权重意味着您希望更强调类。 从你所说的看来,类0比类1的频率高19倍。所以你应该增加类1相对于类0的class_weight ,比如说{0: class_weight :.9}。 如果class_weight不等于1,它将基本上改变正则化参数。

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