脚注:以下内容仅是闲暇时遇到问题的总结,便于日后查看。如有不对地方,还请及时指正。
1. AUC定义
定义
AUC(Area Under Curve)主要作用是衡量学习器优劣的一种性能指标,其被定义为ROC曲线下与坐标轴围成的面积。
那这里为什么不用ROC曲线直接作为衡量学习器优劣的指标呢?其实是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好(因为它只是个曲线,不易拿来对比),而AUC作为一个数值,数值越大代表分类器效果越好,易量化。
ROC曲线
ROC曲线全称为受试者工作特征曲线 (receiver operating characteristic curve),它是根据一系列不同的二分类方式(分界值或决定阈),以真阳性率(TPR)为纵坐标,假阳性率(FPR)为横坐标绘制的曲线。
(1)名词定义
- 真阳性率[TPR]: 正确预测为正例个数/所有正例个数
T P R = T P T P + F N TPR = \frac{TP}{TP+FN} TPR=TP+FNTP - 假阳性率[FPR] : 错误预测为正例个数/所有负例个数
T P R = F P T N + F P TPR = \frac{FP}{TN+FP} TPR=TN+FPFP
(2)几何解释
ROC曲线的形成,就是将确定正负样例标签的阈值
α
\alpha
α从0->1按照一定步长取一遍,分别在每个阈值点上计算出(TPR, FPR),进而可形成一条曲线。这里其实就暗示了后面计算AUC的一种方式,几何方式求曲线下的面积。
如上图可以看到,我们的理想点(0,1)。如果这条曲线往理想点靠近,即曲线弯曲成都是要往左上角靠近的,它的曲线下面积越大。
思考: 理想状态点出现,即意味着我们学习器中所有正样本预测分 > 负样本预测分,当阈值
α
∈
(
m
a
x
(
负
样
本
得
分
)
,
m
i
n
(
正
样
本
得
分
)
)
\alpha \in (max(负样本得分), min(正样本得分))
α∈(max(负样本得分),min(正样本得分)),曲线必然可以抵达理想点;换句话说,只要当我们预测出来
m
e
r
i
t
=
#
{
s
a
m
p
l
e
P
a
i
r
:
s
a
t
i
s
f
y
(
正
样
本
得
分
>
负
样
本
得
分
)
}
merit = \#\{samplePair: satisfy(正样本得分>负样本得分)\}
merit=#{samplePair:satisfy(正样本得分>负样本得分)}merit数值越大,越是表明当前获得的学习器效果好.
2. AUC计算
因为AUC计算方法目前主要看到有三种,下面主要是摘抄常用的两种方法:
(1) 方法一 :直接计算pair对
首先用学习器预测出每个样本的分类预测分 p i ^ \hat{p_i} pi^, 对 { p i ^ , i = 1 , 2 , 3 , … , n } \{\hat{p_i}, i=1,2,3,\dots,n\} {pi^,i=1,2,3,…,n}升序排列,获得其对应排序分为: { r i , i = 1 , 2 , 3 , … , n } \{r_i, i=1,2,3,\dots,n\} {ri,i=1,2,3,…,n}备注: n = M + N , 其 中 M 为 正 样 本 个 数 , N 为 负 样 本 个 数 . n = M + N, 其中M为正样本个数,N为负样本个数. n=M+N,其中M为正样本个数,N为负样本个数.
则: A U C = Σ s a m p l e i ∈ p o s i t i v e S a m p l e r i − M ∗ ( M + 1 ) 2 M ∗ N AUC = \frac{\Sigma_{sample_i \in positiveSample}r_i - \frac{M*(M+1)}{2}}{M*N} AUC=M∗NΣsamplei∈positiveSampleri−2M∗(M+1)备注:这里的计算方法其实就是在计算上述所说的merit数值大小.
(2) 方法二 :求ROC曲线下的面积
计算脚本见下方(借鉴同事脚本),当时这里我还真想了下,具体是如何计算的梯形面积的?下面提出几个注意的点:
首先,这段代码较好的是减少了一次排序,试想如果数据量非常大的时候,排序是非常耗时的方式,这是个比较精妙的地方。
其次,这里的bucket_size可以设计的足够大,回想大学学积分那会,我们总希望梯形分割越多越好,越是能逼近真实曲线下的面积(上限为样本数,再大无意)。
最后,为什么计算梯形面积是从bucket号从大到小?其实这样才能使得我们计算的梯形面积是从横轴的左向右。回头看一下上面手稿图,我们的(0,0)点实际上是
t
h
r
e
a
d
h
o
l
d
=
1
threadhold=1
threadhold=1, 也即阈值是非常大的,而编码序号大的bucket意味着高threashold。
附上脚本如下:
def cal_auc(label_list, p_list, bucket_size):
bucket_list = {}
for idx, pi in enumerate(p_list):
if bucket_list.get(int(pi*bucket_size), {}) == {}:
bucket_list[int(pi*bucket_size)] = {}
bucket_list[int(pi*bucket_size)][0] = 1-label_list[idx]
bucket_list[int(pi*bucket_size)][1] = label_list[idx]
else:
bucket_list[int(pi*bucket_size)][label_list[idx]] += 1
area = 0
fp = 0
tp = 0
for i in range(bucket_size , -1, -1):
if bucket_list.get(i,{})=={}:
continue
newfp = fp + bucket_list[i][0]
newtp = tp + bucket_list[i][1]
area += (newfp -fp) * (tp + newtp) / 2.0
fp = newfp
tp = newtp
auc = area / ( fp * tp )
return " ".join(["%s"%auc, "%s"%( tp + fp) ])
3. AUC为何对正负样例不均衡的数据集评价有效?
在很多排序场景下,尤其是当前许多数据集正负样例都不太均衡;或者说因训练集过大,可能会对数据进行负采样等操作。这擦操作的前提是建立在AUC值不会受到正负样本比例的影响。看过很多博客也都在讨论:为什么AUC不会受正负样例不平衡的影响?为什么排序喜欢选择AUC作为评判指标。
一方面,从AUC定义来解释,它是比较“正样本预测分 & 负样本预分”数值相对大小关系。如若数据比例不同,模型预测分预测值绝对大小会因此而改变,但是相同分类器对于正负样本的区分能力是一定的。
另一方面,有人拿出实践证明:不采样数据集( 不对负样本采样),对比进行负采样数据集。计算出来的AUC不同,发现负样本越多(即不采样)的数据集AUC数值越高。
下面我们对一个Random分类器,从AUC计算公式角度推导下:AUC是否受样本不均衡影响。
从上面的推导来看的话,貌似不管是正负样本比例是多少,确实好像不会影响到AUC的变化。那么讨论区童鞋说到的为什么负样本增多,AUC还变好了呢?
我之前实践过这个事情,现象也如其所说。思考了下:
首先,在图像分类中,都会采用各种花式数据增强。包括现在一些APP排序也开始这么做,主要是去解决一些debias的问题。这么做的背景是:增加样本的丰富性,让模型见更多的“世面”,以便学习的更好。
其次,我们对数据集进行采样的时候,本身就是比较高难度的事情,采样如何做到公平是非常trick的。现在也有很多文章也在讨论这个话题。