scikit learn中的类权重参数是如何工作的?

2024-05-28 20:13:15 发布

您现在位置:Python中文网/ 问答频道 /正文

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

情况

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

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

我把数据分成不相交的集合进行训练和测试(大约80/20)。然后我用手随机抽取训练数据,得到不同比例的训练数据,而不是19:1;从2:1->;16:1。

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

结果与预期一致:在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

我还包括Noneauto

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

我的问题

1)如何正确使用class_weight来实现培训数据与实际数据之间的不同平衡?具体来说,我应该传递给class_weight什么字典来使用n:m比例的负:正训练样本?

2)如果您将各种class_weight字典传递给GridSearchCV,在交叉验证期间,它是否会根据字典重新平衡训练折叠数据,但使用真正给定的样本比例计算我在测试折叠上的得分函数?这一点很关键,因为任何指标只有来自观测比例的数据时才对我有用。

3)对于比例,class_weightauto值做什么?我阅读了文档,我假设“数据与频率成反比地平衡”就意味着它是1:1。是这样吗?如果没有,有人能澄清吗?

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


Tags: 数据函数gt网格auto参数字典分类
1条回答
网友
1楼 · 发布于 2024-05-28 20:13:15

首先,光靠回忆可能不太好。你只需把每件事都归为积极类,就可以达到100%的召回率。 我通常建议使用AUC来选择参数,然后为您感兴趣的操作点(比如给定的精度级别)找到一个阈值。

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

关于class_weight="auto"的工作原理,您可以查看this discussion。 在dev版本中,您可以使用class_weight="balanced",这更容易理解:它基本上意味着复制较小的类,直到您拥有与较大的类一样多的样本,但是是以一种隐式的方式。

相关问题 更多 >

    热门问题