为什么sklearn中LogisticRegression等价class_weight会得到不同结果?
问题1:class_weight运行逻辑及等价权重结果不同的原因
首先明确class_weight的核心运行逻辑:
- 传入的类别权重会直接乘以对应类别每个样本的损失值,修改损失函数中不同类别样本的贡献占比,但正则项不会乘以该权重。
- sklearn的LogisticRegression默认启用L2正则,参数
C是正则强度的倒数,即完整损失函数为:总损失 = sum(样本损失 * 对应类别权重) + (1/C) * L2正则项
你观察到的同比例权重结果不同,本质是正则项没有随损失项同步缩放导致的:
- 配置
{1:0.5, 0:0.5}的总损失:0.5 * sum(样本损失) + 1 * L2正则项 - 配置
{1:1, 0:1}的总损失:1 * sum(样本损失) + 1 * L2正则项
两个损失函数不存在等比例缩放关系,最优参数自然不同,最终精度也有微小差异。
你可以做两个验证确认该逻辑:
- 将
C设置为极大值(比如C=1e10)关闭正则,两次训练的结果会几乎完全一致 - 将第一个模型的
C改为2,总损失变为0.5*sum(样本损失) + 0.5*L2正则项 = 0.5*(sum(样本损失) + 1*L2正则项),和第二个模型的损失函数完全等价,训练结果也会一致。
另外优化器的数值迭代截断误差也会带来微小的结果差异,但核心影响因素是正则项的缩放不匹配。
问题2:class_weight的正确设置方法
根据你的使用场景选择对应配置即可:
- 数据集平衡、无特殊业务代价要求:直接不设置
class_weight即可,默认等价于所有类别权重为1,不要手动传入等比例的权重配置,避免不必要的正则比例变化 - 数据集不平衡、需要按类别频率反算权重:直接传
class_weight='balanced',sklearn会自动计算总样本数/(类别数 * 对应类别样本数)作为权重,不需要手动计算 - 有明确的业务错判代价要求:比如漏判正例的代价是误判负例的k倍,手动传入
{1:k, 0:1}即可,如果你需要保持和无缩放场景下相同的正则比例,需要同步将C乘以和权重缩放相同的系数 - 注意训练时的权重设置要和后续评估指标的权重对齐,避免训练优化目标和实际评估目标不匹配的问题
内容的提问来源于stack exchange,提问作者Crunchy Shark
相关产品推荐
相关产品推荐

