AUC指标深度理解
AUC 指标
直观意义
AUC 指标用于评价分类器对于正、负样例的辨别能力,对出结果的排序位置(按照预测为正例的概率)敏感。
为什么提出这个指标?
一般来讲,精确率、召回率等指标,都需要设定一个阈值去判别是属于正类还是负类,例如预测分大于等于0.5判别为正类,小于0.5判别为负类。如何设定这个阈值,是个问题。而AUC这个指标则不需要设阈值。(或者说,每种阈值的情况都考虑了,下面介绍)
计算方式
利用ROC所围面积计算
ROC 如何计算
要计算ROC需要明确混淆矩阵的概念
首先,混淆矩阵中有着Positive、Negative、True、False的概念,其意义如下:
- 算法给出的,预测类别为1的为Positive(阳性),预测类别为0的为Negative(阴性)
- 数据集中,真实类别为1的为True(真), 真实类别为0的为False(伪)
于是就有这个混淆矩阵图:
其次, ROC 使用的是True Positive Rate(真阳率)、False Positive(伪阳率)两个概念:
其中,\(P\) 是所有真实标签为1的数量,\(N\)是所有真实标签为0的数量
因此,
TPRate的意义是所有真实类别为1的样本中,预测类别为1的比例。
FPRate的意义是所有真实类别为0的样本中,预测类别为1的比例。
这两个指标均指出公式围绕预测类别为1进行讨论。
绘制ROC曲线:
曲线的起点和终点是(0,0)和(1,1)
如果\(TPR=FPR\) 即随机猜测,如图所示
举个简单栗子:
通过上述混淆矩阵算法,我们可以得到
进而算得TPRate=3/4,FPRate=2/4,得到ROC曲线:
上述栗子是一个硬分类问题,也就是预测结果要么0,要么1. 如果给出预测概率的呢?下面的栗子:
这时候,我们只需要设置一个阈值,就可以把上面的预测概率转换为0,1这样的硬分类结果,然后套用上面的操作即可画出当前阈值的一个点。
利用ROC面积计算AUC
- AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
- 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
- AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。
- AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。
上面提到当设置一个阈值就可以得到 ROC 曲线上的一个点,对于 AUC 计算,我们实际上就是要把所有阈值都考虑进去(也就是上文提出使用AUC指标的要解决的问题)。
如下图中,我们要设置阈值为0.8,0.6,0.5,0.3
依次计算\(TPR,FPR\),进而绘制 ROC 曲线
上图给出了一个很简单的例子。四个样本,按预测分高到低排序,从上到下依次找到四个阈值(红线),每个阈值的情况下,分别计算出TPR和FPR(分子只统计红线上面的,因为红线下面在阈值以下,也就是说都是预测为阴性的结果,不在公式的计数范围内),并描点,再用线段相连,最后计算出曲线下面的面积(该例子AUC=0.75)。
注:
如果按照阈值排序后,有相同的阈值,那么也是重复计算,只需按照每次下移一行画红线即可
概率角度
一种本质的理解为: 随机给定一个正样本和一个负样本,分类器输出该正样本为正的那个概率值 比 分类器输出该负样本为正的那个概率值 要大的可能性。
暴力求解
按照上面提到的,我们需要统计随机抽取的一对样本,按照上述含义进行计算,即一下公式
举个栗子:
ID | label | probability |
---|---|---|
A | 0 | 0.1 |
B | 0 | 0.4 |
C | 1 | 0.35 |
D | 1 | 0.8 |
假设有4条样本。2个正样本,2个负样本,那么\(M*N=4\)。即总共有4个样本对。分别是:
\((D,B),(D,A),(C,B),(C,A)\)。
在\((D,B)\)样本对中,正样本\(D\)预测的概率大于负样本\(B\)预测的概率(也就是\(D\)的得分比\(B\)高),记为1
同理,对于\((C,B)\)。正样本\(C\)预测的概率小于负样本\(C\)预测的概率,记为0.
最后可以算得,总共有3个符合正样本得分高于负样本得分,故$$AUC=\frac{1+1+0+1}{4}=0.75$$
当得分(probability)有一样(0.4)的情况:
ID | label | probability |
---|---|---|
A | 0 | 0.1 |
B | 0 | 0.4 |
C | 1 | 0.4 |
D | 1 | 0.8 |
同样本是4个样本对,对于样本对\((C,B)\)其I值为0.5。
为什么说这个方法暴力呢?
因为,我们需要罗列出所有正例,负例的组合,相当于一个笛卡尔积,如果正例和负例都很多的情况下,那么这个笛卡尔积的集合很大,计算很费时间。
通过观察可以发现,(D,B),(D,A)统计过程中,由于 \(D\) 的得分很高,我们可以通过一次排序直接数出来比 \(D\)小的有多少个,并不需要全部罗列出来。因此,产生下面的计算方式。
计数统计
ID | label | probability | Rank |
---|---|---|---|
D | 1 | 0.8 | 4 |
B | 0 | 0.4 | 3 |
C | 1 | 0.35 | 2 |
A | 0 | 0.1 | 1 |
按照公式计算:
\(AUC=\frac{4+2-\frac{2(2+1)}{2}}{2\times2}=\frac{3}{4}=0.75\)
与上面计算方法得到的结果一样,但是我们只需要排序一下,不需要笛卡尔积运算,排序的复杂度是 log 级别的
如果得分有相同的:
ID | label | probability | Rank |
---|---|---|---|
G | 0 | 0.3 | 1 |
F | 1 | 0.5 | 2 |
E | 1 | 0.5 | 3 |
D | 0 | 0.5 | 4 |
C | 0 | 0.5 | 5 |
B | 1 | 0.7 | 6 |
A | 1 | 0.8 | 7 |
这里需要注意的是:相等概率得分的样本,无论正负,谁在前,谁在后无所谓。
由于只考虑正样本的rank值:
对于正样本A,其rank值为7
对于正样本B,其rank值为6
对于正样本E,其rank值为(5+4+3+2)/4
对于正样本F,其rank值为(5+4+3+2)/4
上述公式简单推导
经过排序后,按照概念我们只需要找出 正例得分大于负例的(正,负)对的数量即可。
首先,排序后最大的rank就是全部样例的总数。
在所有正例中(P个),
排在第一(No1)的\(D\),统计比他小的所有负例个数,即 \(rank-1-(P-No)=4-1-(2-1)=2\)也就是 \((D,B),(D,A)\)
排在第二(No2)的\(C\), 统计比他小的所有负例个数,\(rank-1-(P-No)=2-1-(2-2)=1\)也就是\((C,A)\)
所以$$AUC=\frac{2+1}{4}=0.75$$
如果用一个公式来表示:
常数项就是一个等差数列
代码
import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([1, 1, 0, 0, 1, 1, 0])
y_scores = np.array([0.8, 0.7, 0.5, 0.5, 0.5, 0.5, 0.3])
print('y_true', y_true)
print('y_score', y_scores)
print(roc_auc_score(y_true, y_scores))
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
print('y_true', y_true)
print('y_score', y_scores)
print(roc_auc_score(y_true, y_scores))