二分类中的AUC到底怎么算

1,600 阅读3分钟

关于AUC的理解和计算方式

一日某大佬给了我出了个题,给了我一个表格,让我去手算一下AUC是多少,日常我都是模型直接输出(如下),真要手算一时半会还想不起来,所以今天咱深入了解下。

print(roc_auc_score(y_true,y_scores))

这里我把大佬所述绘制成表格

prob 正例 负例
0.8 5 4
0.5 1 2
0.3 2 2

下面分别从模型输出和手算两方面计算一下AUC

1 模型输出AUC的值

首先将表格翻译成我们训练时候数据的模样,正例是1,负例为0,
那么表格对应的数据为[1,1,1,1,1,0,0,0,0,1,0,0,1,1,0,0]
对应的概率为[0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.5,0.5,0.5,0.3,0.3,0.3,0.3]

先用我经常输出模型评价指标的代码跑一下结果:

from sklearn.metrics import roc_auc_score,accuracy_score,f1_score,precision_score,recall_score
import numpy as np
y_true=np.array([1,1,1,1,1,0,0,0,0,1,0,0,1,1,0,0])
y_scores=np.array([0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.8,0.5,0.5,0.5,0.3,0.3,0.3,0.3])
print("y_true is",y_true)
print("y_scores is",y_scores)
print("AUC is",roc_auc_score(y_true,y_scores))
y_pred = [int(item >= 0.5) for item in y_scores]
print (y_pred)
print (confusion_matrix(y_true, y_pred))
print (classification_report(y_true, y_pred))
print ("Accuracy : %.4f" % accuracy_score(y_true, y_pred))
print ('Recall: %.4f' % recall_score(y_true,y_pred))
print ('F1-score: %.4f' % f1_score(y_true,y_pred))
print ('Precesion: %.4f' % precision_score(y_true,y_pred))

输出结果如下

y_true is [1 1 1 1 1 0 0 0 0 1 0 0 1 1 0 0]
y_scores is [0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.5 0.5 0.5 0.3 0.3 0.3 0.3]
AUC is 0.546875
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
[[2 6]
 [2 6]]
              precision    recall  f1-score   support

           0       0.50      0.25      0.33         8
           1       0.50      0.75      0.60         8

    accuracy                           0.50        16
   macro avg       0.50      0.50      0.47        16
weighted avg       0.50      0.50      0.47        16

Accuracy : 0.5000
Recall: 0.7500
F1-score: 0.6000
Precesion: 0.5000

哦这个AUC=0.546875,且为啥用y_scores不用y_pred去算AUC呢,下面我们一一解答

首先:我们看一下本案例的混淆矩阵是多少

True_1 True_0
pre_1 6 (TP) 6 (FP)
pre_0 2 (FN) 2 (TN)
TPR(真阳率)=TP/(TP+FN)=6/(6+2)=3/4
FPR(假阳率)=FP/(FP+TN)=6/(6+2)=3/4

2 概率学定义计算AUC

其次,我们从概率学的那个定义去计算AUC:随机给定一个正例或者负例,判定正例为正比判定负例为正要高的概率,证明见链接2,有如下公式:

依据这个公式,结合正负例和得分,我们把顺序从新排列下
[1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0]
[0.8,0.8,0.8,0.8,0.8,0.5,0.3,0.3,0.8,0.8,0.8,0.8,0.5,0.5,0.3,0.3]
我们这里仔细回想下AUC概率上怎么算:随机给定一个正例或者负例,判定正例为正比判定负例为正要高的概率
敲黑板:随机给一个正例和负例:
->有8个正例和负例,两两组和,所以M*N=64
对于第1个正例来说,它的得分是0.8,9-16都是负例,有4个0.8,2个0.5,2个0.3
所以是4*0.5(相同0.5)+2*1+2*1=6
同理第2,3,4,5正例也是如此;
对于第6个正例,它的得分是0.5,9-16都是负例,有4个0.8,2个0.5,2个0.3
所以是0*4+2*0.5+2*1=3
同理求得第7,8对应的I分别是1和1
所以按照公式
AUC=(6*5+3+1+1)/64=35/64=0.546875

3 按照得分排序rank计算

随机给定一个正例或者负例,判定正例为正比判定负例为正要高的概率

我们按照概率值由低到高排序,相同的概率正样本在前负样本在后进行排名(递增的序列)
那么,如果有M个正样本和N个负样本,
如果rank最大的正样本为rank_1,那么他前面就有M-1个正样本,
他前面就会有rank_1-1-(M-1)=rank_1-M个负样本
rank第二大的正样本为rank_2,那么他前面就有M-2个正样本,
就会有rank_2-1-(M-2)=rank_2-(M-1)个负样本
...
直到最小的正样本rank_M,他前面0个正样本,有rank_M-1个负样本
把这些加起来
rank_1+rank+2+..rank_M-(M+M-1+M-2+...1)--等差数列

将此公式运用到本例:

lable prob rank
1 0.3 1
1 0.3 2
0 0.3 3
0 0.3 4
1 0.5 5
0 0.5 6
0 0.5 7
1 0.8 8
1 0.8 9
1 0.8 10
1 0.8 11
1 0.8 12
0 0.8 13
0 0.8 14
0 0.8 15
0 0.8 16

同分数要算均值且只算正例,相同的prob正例都要计算

最终几种方法的计算结果一致

🎉

参考: blog.csdn.net/qq_22238533… www.alexejgossmann.com/auc/