我很难理解 scikit-learn Logit模型中的 class_weight
参数是如何运作的。
情况
我想用 Logit模型对一个非常不平衡的数据集进行二进制分类。这些类别被标记为0(阴性)和1(阳性) ,观察数据的比例约为19:1,大多数样本有阴性结果。
第一次尝试: 手动准备训练数据
为了训练和测试,我把数据分割成不相交的集合(大约80/20)。然后,我随机抽取手工训练数据,得到不同比例的训练数据比19:1; 从2:1-> 16:1。
然后,我就这些不同的训练数据子集对 Logit模型进行训练,并将回忆(= 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
和 auto
。
这一次的结果完全出乎意料。除了 auto
之外,我所有的回忆对于 class_weight
的每一个值来说都是微不足道的(< 0.05)。所以我只能假设我对如何设置 class_weight
字典的理解是错误的。有趣的是,在网格搜索中,“ auto”的 class_weight
值对于 C
的所有值都在59% 左右,我猜它的比例是1:1?
我的问题
如何正确使用 class_weight
来实现训练数据与实际数据的不同平衡?具体来说,我应该传递给 class_weight
什么样的字典来使用 n: m 比例的负: 正训练样本?
如果你把各种各样的 class_weight
字典传给 GridSearchCV,在交叉验证期间,它是否会根据字典重新平衡训练折叠数据,而是使用给定的真实样本比例来计算我在测试折叠上的得分函数?这是至关重要的,因为任何度量对我来说都是有用的,如果它来自观测比例的数据。
就比例而言,class_weight
的 auto
值有什么作用?我阅读了文档,我假设“平衡数据与其频率成反比”,这意味着它是1:1。是这样吗?如果没有,有人能澄清一下吗?