ROC,AUC,PR,AP介紹及python繪制


這里介紹一下如題所述的四個概念以及相應的使用python繪制曲線:

參考博客:http://kubicode.me/2016/09/19/Machine%20Learning/AUC-Calculation-by-Python/?utm_source=tuicool&utm_medium=referral

一般我們在評判一個分類模型的好壞時,一般使用MAP值來衡量,MAP越接近1,模型效果越好;

更詳細的可參考:http://www.cnblogs.com/pinard/p/5993450.html

准確率pr就是找得對,召回率rc就是找得全。
大概就是你問問一個模型,這堆東西是不是某個類的時候,准確率就是 它說是,這東西就確實是的概率吧,召回率就是, 它說是,但它漏說了(1-召回率)這么多

(這里的P=FN+TP;N=TN+FP;而這里recall=tp rate;上述鏈接里的特異性其實就是fp rate)

AUC和AP分別是ROC和PR曲線下面積,map就是每個類的ap的平均值;python代碼(IDE是jupyter notebook):

#繪制二分類ROC曲線
import pylab as pl
%matplotlib inline
from math import log,exp,sqrt

evaluate_result = "D:/python_sth/1.txt"
db = []
pos , neg = 0 , 0
with open(evaluate_result , 'r') as fs:
    for line in fs:
        nonclk , clk , score = line.strip().split('\t')
        nonclk = int(nonclk)
        clk = int(clk)
        score = float(score)
        db.append([score , nonclk , clk])
        pos += clk
        neg += nonclk

db = sorted(db , key = lambda x:x[0] , reverse = True) #降序

#計算ROC坐標點
xy_arr = []
tp , fp = 0. , 0.
for i in range(len(db)):
    tp += db[i][2]
    fp += db[i][1]
    xy_arr.append([tp/neg , fp/pos])

#計算曲線下面積即AUC
auc = 0.
prev_x = 0
for x ,y in xy_arr:
    if x != prev_x:
        auc += (x - prev_x) * y
        prev_x = x
print "the auc is %s."%auc
x = [_v[0] for _v in xy_arr]
y = [_v[1] for _v in xy_arr]
pl.title("ROC curve of %s (AUC = %.4f)" % ('svm' , auc))
pl.ylabel("False Positive Rate")
pl.plot(x ,y)
pl.show()

 

結果:(注意:ROC曲線中縱坐標是TP,橫坐標是FP,下面的圖有誤!)

這里的.txt文件格式如:http://kubicode.me/img/AUC-Calculation-by-Python/evaluate_result.txt

形式為:

PS:該txt文件表示的意思是,比如對於第一行就是說:有一個樣本得分為0.86...,並被預測為負樣本;倒數第一行就是說,這么多測試樣本中,有一個樣本得分為0.45...,並被預測為正樣本;

注意:繪制ROC和PR曲線時都是設定不同的閾值來獲得對應的坐標,從而畫出曲線

代碼中:

  1. nonclick:未點擊的數據,可以看做負樣本的數量
  2. clk:點擊的數量,可以看做正樣本的數量
  3. score:預測的分數,以該分數為group進行正負樣本的預統計可以減少AUC的計算量
  4. 代碼中首先使用 
    db = sorted(db , key = lambda x:x[0] , reverse = True) 進行降序排序,然后將每一個從小到大的得分值作為閾值,每次得到一個fpr和tpr(因為最后得分大於閾值,就認為它是正樣本,所以若.txt中得分為某一個閾值時nonclk為非0的數,而clk是0,則認為nonclk的值大小的樣本是fp樣本),最后畫出曲線;

 對於PR曲線也一樣,只不過橫坐標換成,縱坐標換成,AP是其曲線下面積;

上面的python代碼針對二分類模型,但針對多分類模型時一樣,即對於每個類都將其看做正樣本,其他類看成負樣本來畫曲線,這樣有多少類就畫多少條相應的曲線,MAp值即為各類ap值的平均值;

 PR曲線的繪制:

這里我們用一張圖片作為例子,多張圖片道理一樣。假設一張圖片有N個需要檢測的目標,分別是object1,object2,object3共分為三類,使用檢測器得到了M個Bounding Box(BB),每個BB里包含BB所在的位置以及object1,object2,object3對應的分數confidence。
我把計算目標檢測評價指標歸為一下幾步:
1,對每一類i進行如下操作:
對M個BB中每一個BB,計算其與N個GroundTruth(GT)的IoU值,且取其中的最大值MaxIoU。設定一個閾值thresh,一般設置thresh為0.5。當MaxIoU < thresh的時候,記錄其類別i的分數confidencei以及fpi = 1,當MaxIoU>=thresh分為以下倆種情況:
當MaxIoU對應的GT類別為i的時候,記錄其類別i的分數以及tpi = 1。
當MaxIoU對應的GT類別不為i的時候,記錄其類別i的分數以及fpi = 1。
2,由步驟1我們可以得到3M個分數與tp/fp的元祖,形如(confidencei,tp或者fp),對這3M個元祖按照confidence進行排序(從大到小)。
3,按照順序1,2,3,4。。。M截取,計算每次截取所獲得的recall和precision
recall = tp/N
precision = tp/tp+fp
這樣得到M個recall和precision點,便畫出PR曲線了~
計算AP值

由上面得到了PR曲線,即得到了n個(P,R)坐標點,利用這些坐標點我們便可以計算出AP(average precision):

方法一:11點法,此處參考的是PASCAL  VOC  CHALLENGE的計算方法。首先設定一組閾值,[0, 0.1, 0.2, …, 1]。然后對於recall大於每一個閾值(比如recall>0.3),我們都會得到一個對應的最大precision。這樣,我們就計算出了11個precision。AP即為這11個precision的平均值。這種方法英文叫做11-point interpolated average precision。;

方法二:當然PASCAL VOC CHALLENGE自2010年后就換了另一種計算方法。新的計算方法假設這N個樣本中有M個正例,那么我們會得到M個recall值(1/M, 2/M, …, M/M),對於每個recall值r,我們可以計算出對應(r’ > r)的最大precision,然后對這M個precision值取平均即得到最后的AP值。

下面給出個例子方便更加形象的理解:

假設從測試集中共檢測出20個例子,而測試集中共有6個正例,則PR表如下:

 

相應的Precision-Recall曲線(這條曲線是單調遞減的)如下:

faster rcnn中計算map的代碼:https://github.com/rbgirshick/py-faster-rcnn/blob/master/lib/datasets/voc_eval.py    該代碼使用的是方法二。

我看網上關於如何使用該代碼並沒有做出解釋,我這里用voc中的幾張圖片計算了一下map(自己算法的測試結果,比如說對voc中的cat類,就新建一個cat.txt,其中存儲“圖片名 矩形框坐標”格式的信息),具體文件在鏈接:https://pan.baidu.com/s/1336g7ccc4gZ2EKNu9PNndQ 提取碼:57yd  中,大家有需要的可以按照這個里面的格式來操作該代碼計算map。

AUCMAP之間的聯系:

AUC主要考察模型對正樣本以及負樣本的覆蓋能力(即“找的全”),而MAP主要考察模型對正樣本的覆蓋能力以及識別能力(即對正樣本的“找的全”和“找的對”)


免責聲明!

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



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