AUC兩種計算方式


1.通過ROC曲線面積計算AUC

AUC(Area Under Curve)被定義為ROC曲線下的面積。

ROC 曲線橫坐標:假正率=FPR=FP/N:  預測為負 and 實際為正 / 實際為負

ROC 曲線縱坐標:真正率=TPR= TP/P :預測為正 and 實際為正 / 實際為正

 注意:有相同預估值時,需要等當前預估值作為閾值的所有 tp,fp 算完,再更新最終 auc

def calcAUC_byRocArea(label,pred):
    P = 0.0
    N = 0.0
    TP = 0.0
    FP = 0.0
    TPR = 0.0
    FPR = 0.0
    LAST_TRP = 0.0
    LAST_FPR = 0.0
    auc = 0.0
    for l in label:
        if l == 0:
            N+=1
        else:
            P+=1
    sample = zip(label,pred)
    sample_sorted = sorted(sample,key=lambda x: -x[1])


    for i,info in enumerate(sample_sorted):
        l,p = info
        if l == 1:
            TP+=1
        else:
            FP+=1
     
        if i !=0 and  i+1 < len(sample) and p == sample_sorted[i+1][1]:
            continue
        
        TPR = TP/P
        FPR = FP/N
        auc+=0.5*(TPR+LAST_TRP)*(FPR-LAST_FPR)
        LAST_FPR=FPR
        LAST_TRP=TPR

    return auc

  

 

 

 

2.通過計算概率計算AUC

AUC還有一種解釋就是任取一對正負樣本,正樣本的預測值大於負樣本的預測值的概率。

2.1 暴力 時間復雜度 o(n2)

(1)遍歷 label, 選出正樣本、負樣本。

(2)遍歷正負樣本 pair,記錄正樣本 pred> 負樣本 pred 的個數為 cnt

(3) auc = cnt / 正樣本個數* 負樣本個數。

 1 from sklearn.metrics import roc_auc_score
 2 import numpy as np
 3 
 4 def calcAUC_byProb(label,pred):
 5     pos_porb = []
 6     neg_prob = []
 7     for i in range(len(label)):
 8         if label[i] == 1:
 9             pos_porb.append(pred[i])
10         elif label[i] == 0:
11             neg_prob.append(pred[i])
12     cnt = 0.0
13     for p in pos_porb:
14         for n in neg_prob:
15             if (p>n):
16                 cnt+=1
17             elif(p == n):
18                 cnt+=0.5
19     return cnt / float(len(pos_porb)*len(neg_prob))
20 
21 y = np.array([1, 1, 1, 0,0])
22 pred = np.array([0.6,0.3, 0.5 ,0.2,0.4])
23 print("sklearn auc:",roc_auc_score(y, pred))
24 #print("my auc calc by area:", calcAUC_byRocArea(y, pred))
25 print("my auc calc by prob:", calcAUC_byProb(y, pred))

 

2.2 動態規划,時間復雜度0(nlogn)

(1)按照預估值降序,組成 pair。

(2)遍歷pair, 如果 label==1,記錄正樣本個數 pos,

如果 label==0, 對於當前樣本來說,前面所有的正樣本個數pos就是 當前樣本與所有正樣本預估值大於當前負樣本預估值的個數。

(3)auc = pos / (pos *n-pos)

 1 def calcAUC_byProb(label,pred):
 2     sample = zip(label,pred)
 3     sample_sorted = sorted(sample,key=lambda x: -x[1])
 4     pos = 0
 5     cnt = 0
 6     last_pred = 0
 7     print(sample_sorted)
 8     for i in range(len(sample_sorted)):
 9         l,p = sample_sorted[i]
10         if l == 1:
11             pos+=1
12         elif l == 0:
13             cnt += pos
14             if (i!=0 and last_pred ==p):
15                 cnt-=0.5
16         last_pred = p
17     negs = len(label) - pos
18     print (cnt,pos,negs)
19     return float(cnt) / float(pos*negs)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM