二分类评价指标整理
先来看一个例子
假设我们做了一个疾病筛查模型,并把“患病”定义为正类,把“健康”定义为负类。
模型检查了100个人,最后得到下面的结果:
| 实际患病 | 实际健康 | |
|---|---|---|
| 模型判断患病 | 30 | 15 |
| 模型判断健康 | 10 | 45 |
这四个格子分别代表:
- 30个人确实患病,模型也判断患病
- 15个人其实健康,但模型误报成患病
- 10个人确实患病,但被模型漏掉了
- 45个人确实健康,模型也正确排除了
后面所有指标,都是围绕这四个数字计算的。
四个基础结果
机器学习里通常用四个英文缩写表示上面的四种情况:
| 缩写 | 中文 | 含义 | 本例数量 |
|---|---|---|---|
TP | 真正例 | 判断为患病,实际也患病 | 30 |
FP | 假正例 | 判断为患病,实际却健康 | 15 |
FN | 假负例 | 判断为健康,实际却患病 | 10 |
TN | 真负例 | 判断为健康,实际也健康 | 45 |
这里可以把英文拆开看:
True和False表示模型判断得对不对Positive和Negative表示模型给出的结果是正类还是负类
例如FP是False Positive,模型给出了“正类”结果,但这个结果是错的,所以在疾病筛查中就是误报。
容易混淆的话,可以暂时不用背缩写,只记住两个问题:
- 实际患病的人,有多少被找出来了?
- 实际健康的人,有多少被误报了?
这两个问题正好对应后面最常见的两个比率。
实际患病的人怎么样了
本例中实际患病的人一共有:
\[ 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,还应该结合精确率、召回率以及精确率-召回率曲线一起判断。
总结
- 先确定哪一类是正类,再理解后面的指标。
TP、FP、FN、TN描述的是预测结果和真实情况的四种组合。- 真正率和假负率都以真实正类为分母,两者相加为1。
- 真负率和假正率都以真实负类为分母,两者相加为1。
- 真正率关心“真实正类找回多少”,精确率关心“预测正类中有多少是真的”。
- ROC曲线展示阈值变化时真正率和假正率之间的取舍,AUC概括整条曲线的整体表现。
最小记忆版如下:
真实正类:找到了 → 真正率;漏掉了 → 假负率
真实负类:排除了 → 真负率;误报了 → 假正率
ROC:横轴是假正率,纵轴是真正率
AUC:ROC曲线下方的面积