auc
AUC(Area under curve)是機(jī)器學(xué)習(xí)常用的二分類評測手段。
AUC:一個(gè)正例,一個(gè)負(fù)例,預(yù)測為正的概率值比預(yù)測為負(fù)的概率值還要大的可能性。
所以根據(jù)定義:我們最直觀的有兩種計(jì)算AUC的方法
- 1:繪制ROC曲線,ROC曲線下面的面積就是AUC的
- 2:假設(shè)總共有(m+n)個(gè)樣本,其中正樣本m個(gè),負(fù)樣本n個(gè),總共有mn個(gè)樣本對,計(jì)數(shù),正樣本預(yù)測為正樣本的概率值大于負(fù)樣本預(yù)測為正樣本的概率值記為1,累加計(jì)數(shù),然后除以(mn)就是AUC的值
ROC
ROC曲線指受試者工作特征曲線 / 接收器操作特性曲線(receiver operating characteristic curve), 是反映敏感性和特異性連續(xù)變量的綜合指標(biāo),是用構(gòu)圖法揭示敏感性和特異性的相互關(guān)系,它通過將連續(xù)變量設(shè)定出多個(gè)不同的臨界值,從而計(jì)算出一系列敏感性和特異性,再以敏感性為縱坐標(biāo)、(1-特異性)為橫坐標(biāo)繪制成曲線,曲線下面積越大,診斷準(zhǔn)確性越高。
- 橫軸:負(fù)正類率(false postive rate FPR)特異度,劃分實(shí)例中所有負(fù)例占所有負(fù)例的比例;
- 縱軸:真正類率(true postive rate TPR)靈敏度,Sensitivity(正類覆蓋率)
- True negative(TN),稱為真負(fù)率,表明實(shí)際是負(fù)樣本預(yù)測成負(fù)樣本的樣本數(shù)
- False positive(FP),稱為假正率,表明實(shí)際是負(fù)樣本預(yù)測成正樣本的樣本數(shù)
- False negative(FN),稱為假負(fù)率,表明實(shí)際是正樣本預(yù)測成負(fù)樣本的樣本數(shù)
- True positive(TP),稱為真正率,表明實(shí)際是正樣本預(yù)測成正樣本的樣本數(shù)
auc直接含義是ROC曲線下的面積,如下圖:

AUC直觀地反映了ROC曲線表達(dá)的分類能力。
- AUC = 1,代表完美分類器
- 0.5 < AUC < 1,優(yōu)于隨機(jī)分類器
- 0 < AUC < 0.5,差于隨機(jī)分類器
AUC這個(gè)指標(biāo)有兩種解釋方法,一種是傳統(tǒng)的“曲線下面積”解釋,另一種是關(guān)于排序能力的解釋。其含義可以大概理解為:隨機(jī)給定一個(gè)正樣本和一個(gè)負(fù)樣本,分類器輸出該正樣本為正的那個(gè)概率值比分類器輸出該負(fù)樣本為正的那個(gè)概率值大的可能性。
ROC曲線怎么得來
假設(shè)采用邏輯回歸分類器,其給出針對每個(gè)實(shí)例為正類的概率,那么通過設(shè)定一個(gè)閾值如0.6,概率大于等于0.6的為正類,小于0.6的為負(fù)類。對應(yīng)的就可以算出一組(FPR,TPR),在平面中得到對應(yīng)坐標(biāo)點(diǎn)。隨著閾值的逐漸減小,越來越多的實(shí)例被劃分為正類,但是這些正類中同樣也摻雜著真正的負(fù)實(shí)例,即TPR和FPR會(huì)同時(shí)增大。閾值最大時(shí),對應(yīng)坐標(biāo)點(diǎn)為(0,0),閾值最小時(shí),對應(yīng)坐標(biāo)點(diǎn)(1,1)。
- step1:假設(shè)已經(jīng)得出一系列樣本被劃分為正類的概率,然后按照大小排序,下圖是一個(gè)示例,圖中共有20個(gè)測試樣本,“Class”一欄表示每個(gè)測試樣本真正的標(biāo)簽(p表示正樣本,n表示負(fù)樣本),“Score”表示每個(gè)測試樣本屬于正樣本的概率。
image.png -
step2:我們從高到低,依次將“Score”值作為閾值threshold,當(dāng)測試樣本屬于正樣本的概率大于或等于這個(gè)threshold時(shí),我們認(rèn)為它為正樣本,否則為負(fù)樣本。舉例來說,對于圖中的第4個(gè)樣本,其“Score”值為0.6,那么樣本1,2,3,4都被認(rèn)為是正樣本,因?yàn)樗鼈兊摹癝core”值都大于等于0.6,而其他樣本則都認(rèn)為是負(fù)樣本。每次選取一個(gè)不同的threshold,我們就可以得到一組FPR和TPR,即ROC曲線上的一點(diǎn)。這樣一來,我們一共得到了20組FPR和TPR的值,將它們畫在ROC曲線的結(jié)果如下圖:
image.png
隨著樣本數(shù)量增多,逐漸接近理想ROC曲線。
PR指標(biāo)

一個(gè)通俗解釋:

F1-SCORE

from sklearn.metrics import f1_score
y_pred = [0, 1, 1, 1, 2, 2]
y_true = [0, 1, 0, 2, 1, 1]
print(f1_score(y_true, y_pred, average='macro'))
print(f1_score(y_true, y_pred, average='weighted'))
auc計(jì)算方式比較
- 面積計(jì)算:矩形面積累加,計(jì)算復(fù)雜,基本不用。
- 統(tǒng)計(jì)正負(fù)樣本對PK情況:統(tǒng)計(jì)一下所有的 M×N(M為正類樣本的數(shù)目,N為負(fù)類樣本的數(shù)目)個(gè)正負(fù)樣本對中,有多少個(gè)組中的正樣本的score大于負(fù)樣本的score。當(dāng)二元組中正負(fù)樣本的 score相等的時(shí)候,按照0.5計(jì)算。然后除以MN。實(shí)現(xiàn)這個(gè)方法的復(fù)雜度為O(n^2)。實(shí)際也不會(huì)用。
-
rank求?。?/p>
image.png
降序rank--> 去掉(正,正)樣本對數(shù)--> 求取比例
- 按概率從高到矮排個(gè)降序, 對于正樣本中score最高的,排序?yàn)閞ank_n, 比它概率小的有M-1個(gè)正樣本(M為正樣本個(gè)數(shù)), (rank_n- M) 個(gè)負(fù)樣本。
- 正樣本概率第二高的, 排序?yàn)閞ank_n-1, 比它概率小的有M-2個(gè)正樣本,(rank_n-1 - M + 1) 個(gè) 負(fù)樣本。
- 以此類推正樣本中概率最小的, 排序?yàn)閞ank_1,比它概率小的有0個(gè)正樣本,rank_1 - 1 個(gè)負(fù)樣本。
- 總共有MxN個(gè)正負(fù)樣本對(N為負(fù)樣本個(gè)數(shù))。把所有比較中 正樣本概率大于負(fù)樣本概率 的例子都算上, 得到公式 (rank_n - M + rank_n-1 - M + 1 .... + rank_1 - 1) / (MxN) 就是正樣本概率大于負(fù)樣本概率的可能性了。 化簡后(因?yàn)楹竺媸莻€(gè)等差數(shù)列)得:

其實(shí)就是,按正樣本score降序排列情況下,負(fù)樣本pk失敗的數(shù)目總數(shù)占所有樣本對的比例。(網(wǎng)上說取M,M-1,……1比M-1,M-2,……1更簡便的,個(gè)人以為理解錯(cuò)了,其實(shí)不是去掉了比rank_i的score低的i-1個(gè)(正,正)樣本對,而是留下了失敗的(正,負(fù))樣本對)

知乎的解釋:https://www.zhihu.com/question/39840928
Wilcoxon-Mann-Witney Test:
python實(shí)現(xiàn)
def calAUC(prob,labels):
f = list(zip(prob,labels))
rank = [values2 for values1,values2 in sorted(f,key=lambda x:x[0])]
rankList = [i+1 for i in range(len(rank)) if rank[i]==1]
posNum = 0
negNum = 0
for i in range(len(labels)):
if(labels[i]==1):
posNum+=1
else:
negNum+=1
auc = 0
auc = (sum(rankList)- (posNum*(posNum+1))/2)/(posNum*negNum)
print(auc)
return auc
工具調(diào)用實(shí)現(xiàn)

import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
print(roc_auc_score(y_true,y_scores))
gauc
-
原理
auc反映的是整體樣本間的一個(gè)排序能力,而在計(jì)算廣告領(lǐng)域,我們實(shí)際要衡量的是不同用戶對不同廣告之間的排序能力, 實(shí)際更關(guān)注的是同一個(gè)用戶對不同廣告間的排序能力, group auc實(shí)際是計(jì)算每個(gè)用戶的auc,然后加權(quán)平均,最后得到group auc,這樣就能減少不同用戶間的排序結(jié)果不太好比較這一影響。group auc具體公式如下:
image.png
- python實(shí)現(xiàn)
def cal_group_auc(labels, preds, user_id_list):
"""Calculate group auc"""
print('*' * 50)
if len(user_id_list) != len(labels):
raise ValueError(
"impression id num should equal to the sample num," \
"impression id num is {0}".format(len(user_id_list)))
group_score = defaultdict(lambda: [])
group_truth = defaultdict(lambda: [])
for idx, truth in enumerate(labels):
user_id = user_id_list[idx]
score = preds[idx]
truth = labels[idx]
group_score[user_id].append(score)
group_truth[user_id].append(truth)
group_flag = defaultdict(lambda: False)
for user_id in set(user_id_list):
truths = group_truth[user_id]
flag = False
for i in range(len(truths) - 1):
if truths[i] != truths[i + 1]:
flag = True
break
group_flag[user_id] = flag
impression_total = 0
total_auc = 0
#
for user_id in group_flag:
if group_flag[user_id]:
auc = roc_auc_score(np.asarray(group_truth[user_id]), np.asarray(group_score[user_id]))
total_auc += auc * len(group_truth[user_id])
impression_total += len(group_truth[user_id])
group_auc = float(total_auc) / impression_total
group_auc = round(group_auc, 4)
return group_auc
參考:
https://blog.csdn.net/natsuka/article/details/78546645
https://blog.csdn.net/u013385925/article/details/80385873
https://zhuanlan.zhihu.com/p/35583721
https://blog.csdn.net/hnu2012/article/details/87892368



