LOADING

加载过慢请开启缓存 浏览器默认开启

二分类评价指标整理

二分类评价指标整理

先来看一个例子

假设我们做了一个疾病筛查模型,并把“患病”定义为正类,把“健康”定义为负类。

模型检查了100个人,最后得到下面的结果:

实际患病实际健康
模型判断患病3015
模型判断健康1045

这四个格子分别代表:

  • 30个人确实患病,模型也判断患病
  • 15个人其实健康,但模型误报成患病
  • 10个人确实患病,但被模型漏掉了
  • 45个人确实健康,模型也正确排除了

后面所有指标,都是围绕这四个数字计算的。


四个基础结果

机器学习里通常用四个英文缩写表示上面的四种情况:

缩写中文含义本例数量
TP真正例判断为患病,实际也患病30
FP假正例判断为患病,实际却健康15
FN假负例判断为健康,实际却患病10
TN真负例判断为健康,实际也健康45

这里可以把英文拆开看:

  • TrueFalse表示模型判断得对不对
  • PositiveNegative表示模型给出的结果是正类还是负类

例如FP是False Positive,模型给出了“正类”结果,但这个结果是错的,所以在疾病筛查中就是误报。

容易混淆的话,可以暂时不用背缩写,只记住两个问题:

  1. 实际患病的人,有多少被找出来了?
  2. 实际健康的人,有多少被误报了?

这两个问题正好对应后面最常见的两个比率。


实际患病的人怎么样了

本例中实际患病的人一共有:

\[ 30+10=40 \]

其中30个人被正确找出来,因此真正率为:

\[ \mathrm{TPR}=\frac{TP}{TP+FN}=\frac{30}{40}=0.75 \]

TPR是True Positive Rate的缩写,中文通常叫真正率,也就是:

所有真实正类中,有多少被模型正确找了出来。

它也经常被叫作召回率或者灵敏度。真正率为75%,就表示100个真实患者中,模型大约能找到75个。

剩下没有找到的那部分叫假负率:

\[ \mathrm{FNR}=\frac{FN}{TP+FN}=\frac{10}{40}=0.25 \]

FNR表示所有真实患者中,有多少被漏掉了。因此真正率和假负率一定互补:

\[ \mathrm{TPR}+\mathrm{FNR}=1 \]

筛查严重疾病时,漏掉患者的代价通常很高,所以这类任务会特别关注真正率。


实际健康的人怎么样了

实际健康的人一共有:

\[ 45+15=60 \]

其中45个人被正确排除,因此真负率为:

\[ \mathrm{TNR}=\frac{TN}{TN+FP}=\frac{45}{60}=0.75 \]

TNR表示:

所有真实负类中,有多少被模型正确排除。

它也叫特异度。

另外15个健康者被误报为患病,对应假正率:

\[ \mathrm{FPR}=\frac{FP}{TN+FP}=\frac{15}{60}=0.25 \]

FPR就是所有真实健康者中,有多少被误报。它与真负率同样互补:

\[ \mathrm{TNR}+\mathrm{FPR}=1 \]

把两组关系放在一起看就很清楚了:

先固定真实类别判断正确判断错误
真实正类真正率TPR假负率FNR
真实负类真负率TNR假正率FPR

所以这四个比率的分母不是所有样本,也不是所有“预测为正”的样本,而是先按照真实类别分组。


它和精确率有什么区别

真正率最容易和精确率混淆。

真正率问的是:

所有真正患病的人里,我找到了多少?

精确率问的则是:

所有被我判断为患病的人里,究竟有多少真的患病?

本例中模型一共判断了\(30+15=45\)个人患病,其中30个人判断正确,因此精确率是:

\[ \mathrm{Precision}=\frac{TP}{TP+FP}=\frac{30}{45}\approx0.667 \]

两者虽然都用到了TP,分母却完全不同:

  • 真正率的分母是真实正类:\(TP+FN\)
  • 精确率的分母是预测正类:\(TP+FP\)

调整阈值会发生什么

很多二分类模型并不是直接输出“患病”或“健康”,而是先输出一个分数,例如:

样本A:0.92
样本B:0.63
样本C:0.41

我们再人为设置一个阈值。假设阈值是0.5,那么大于等于0.5的样本被判为正类,其余判为负类。

如果把阈值从0.5降到0.3,模型会更容易判断为正类:

  • 更多真实患者被找出来,真正率通常会上升
  • 更多健康者也会被误报,假正率通常也会上升

如果把阈值升高,变化则大致相反。

因此“真正率高”和“假正率低”通常不能同时无限追求,需要根据实际业务选择平衡点。


ROC曲线在画什么

既然不同阈值会得到不同的真正率和假正率,我们就可以把所有阈值都试一遍,然后把结果画在同一张图上:

  • 横轴是假正率FPR
  • 纵轴是真正率TPR

这张图就叫ROC曲线,中文通常译作“受试者工作特征曲线”。名字听起来很复杂,但图本身只是在回答:

当我不断放宽判断条件时,多找回了多少正类,同时又制造了多少误报?

理想情况当然是尽快把真正率拉到1,同时让假正率保持在0附近,因此曲线越靠近左上角通常越好。

但ROC曲线本身不会替我们决定最终阈值。疾病筛查可能更在意少漏诊,垃圾邮件过滤可能更怕误伤正常邮件,不同场景的代价完全不同。


AUC又是什么

AUC是Area Under the Curve的缩写,意思是ROC曲线下方的面积。

它把整条曲线压缩成一个数字:

  • 接近1:模型通常能把正类排在负类前面
  • 接近0.5:整体排序能力接近随机猜测
  • 小于0.5:模型可能把方向学反了

还可以这样理解:随机取一个正类和一个负类,AUC近似表示模型把正类打分排得更高的概率。

需要注意的是,AUC高不代表默认阈值一定合适。它评价的是模型在所有阈值下的整体排序能力,而真正上线时仍然要结合误报和漏报的成本选择具体阈值。

样本极度不平衡时,也不能只看ROC和AUC,还应该结合精确率、召回率以及精确率-召回率曲线一起判断。


总结

  1. 先确定哪一类是正类,再理解后面的指标。
  2. TPFPFNTN描述的是预测结果和真实情况的四种组合。
  3. 真正率和假负率都以真实正类为分母,两者相加为1。
  4. 真负率和假正率都以真实负类为分母,两者相加为1。
  5. 真正率关心“真实正类找回多少”,精确率关心“预测正类中有多少是真的”。
  6. ROC曲线展示阈值变化时真正率和假正率之间的取舍,AUC概括整条曲线的整体表现。

最小记忆版如下:

真实正类:找到了 → 真正率;漏掉了 → 假负率
真实负类:排除了 → 真负率;误报了 → 假正率

ROC:横轴是假正率,纵轴是真正率
AUC:ROC曲线下方的面积

参考资料

本站不开放评论区,如有讨论内容请移步至本站Github讨论区