使用sklearn.metrics.cohen_kappa_score计算科恩卡帕系数结果为0的问题排查与解决
为什么你的科恩卡帕系数为0?
这其实是科恩卡帕系数的设计逻辑导致的——它衡量的是模型表现比随机猜测好多少,而不是单纯的准确率。我们来拆解一下你的案例:
问题根源:卡帕系数的计算逻辑
科恩卡帕的核心公式是:
κ = (Po - Pe) / (1 - Pe)
其中:
- Po:观察一致率(你的模型正确预测的比例),这里是33/35 ≈ 0.9429
- Pe:期望一致率(真实标签和预测结果这两个“评判者”随机达成一致的概率)
在你的案例中,预测结果全是0(相当于模型“无脑猜多数类”),真实标签中0占33/35,1占2/35。此时Pe的计算是两个分布的交叉乘积之和:
Pe = (真实0的比例 × 预测0的比例) + (真实1的比例 × 预测1的比例) = (33/35 × 1) + (2/35 × 0) = 33/35 ≈ 0.9429
代入公式后,(Po - Pe)等于0,所以κ自然为0——你的模型表现和“总是猜最常见类别”的随机策略完全一样,没有任何额外的预测能力,因此卡帕系数认为你没有比随机更好。
如何解决?
1. 正确理解卡帕系数的适用场景
卡帕系数适合评估模型是否具备超越随机猜测的分类能力,但在极端类别不平衡的场景下,单纯的“多数类预测”会得到很高的准确率,但卡帕会暴露这种模型的无效性——这其实是卡帕的优点,而不是bug。
2. 改用更适合的评估指标
如果你的目标是关注少数类(这里的标签1)的表现,建议使用:
- 召回率(Recall):衡量模型能正确识别多少少数类样本(你的模型召回率为0,能直观反映问题)
- F1分数:综合精确率和召回率的指标,更适合不平衡数据集
- 混淆矩阵:清晰展示各类别的预测对错情况
3. 改进模型以提升卡帕系数
要让卡帕系数变为正数,你需要让模型学会正确预测少数类:
比如当模型能正确预测1个标签1时,Po=34/35≈0.9714,Pe仍为33/35≈0.9429,此时κ≈(0.9714-0.9429)/(1-0.9429)≈0.5,卡帕系数就会体现出模型的进步。
你可以用以下代码验证这个逻辑:
from sklearn.metrics import cohen_kappa_score # 修改preds,正确预测一个1 labels = [0]*33 + [1]*2 preds = [0]*34 + [1] print(cohen_kappa_score(labels, preds)) # 输出约0.5 print(cohen_kappa_score(labels, preds, weights='quadratic')) # 输出约0.75
内容的提问来源于stack exchange,提问作者arshad
相关产品推荐
相关产品推荐

