PR曲線和ROC曲線概念及其區別

知識點

Precision=TP/(TP+FP)
Recall=TP/(總的正樣本)=TP/(TP+FN) # 這個時候的
TPR=TP/(TP+FN)=Recall # 真正例率
FPR=FP/(TN+FP) #
PR曲線
橫Recall,縱Precision
PR曲線的繪製
場景:有限樣本。
方法:固定分類閾值(比如0.5),對分類器的預測結果按照置信度進行降序排序,然後按此順序對樣例進行預測,每次可以計算出當前的查全率(Recall)和查準率(Precision),然後以此作圖,繪製出P-R曲線。(疑惑??:P-R曲線是按照固定的分類閾值,還是按照西瓜書所講,按照置信度降序的順序,逐個把樣本作爲正例進行預測??我做商湯的筆試題,是採取固定分類閾值的策略)
ROC曲線 橫FPR,縱TPR,理想的情況是TPR=1,FPR=0,一般來說,FPR增大,則TPR也會跟着增大。
ROC曲線的繪製:
場景:有限樣本。
方法:卡閾值,對學習器的預測結果排序,排在前面的是最可能爲正例的樣本,最後的是最不可能的樣本,然後計算不同閾值下的TPR和FPR值,繪製出曲線。
卡閾值作爲正負樣本的判定依據,閾值較高時,Precision比較大,閾值較低時,Recall較大。(推薦的話,想Precision較大,用戶希望排名靠前的推薦是自己想要的,刑偵的話希望Recall較大,不錯過一個犯人)
AUC:ROC曲線下面積。
PR和ROC曲線應用範圍:
1.當正負樣本比例差不多的時候,兩者區別不大。
2.PR曲線比ROC曲線更加關注正樣本,而ROC則兼顧了兩者。
3.AUC越大,反映出正樣本的預測結果更加靠前。(推薦的樣本更能符合用戶的喜好)
4.當正負樣本比例失調時,比如正樣本1個,負樣本100個,則ROC曲線變化不大,此時用PR曲線更加能反映出分類器性能的好壞。
5.PR曲線和ROC繪製的方法不一樣。

PR曲線和ROC曲線區別參考鏈接:
http://www.fullstackdevel.com/computer-tec/data-mining-machine-learning/501.html

附:商湯計算PR題

#-*-coding:utf-8-*-
def s4j5(a):
    a1=float(int(a*100))
    tag=a*100-a1
    if tag>=0.5:
        return((a1+1)/100)
    else:
        return(a1/100)

N = int(raw_input())
recall = 0.0
labelCon = []
totalPos = 0
for i in range(N):
    temp = [xx for xx in raw_input().strip().split()]
    target, confidence = int(temp[0]), float(temp[0])
    labelCon.append([target, confidence])
    if target==1:
        totalPos+=1
count = 0
posCount = 0
correctCount = 0
FP = 0
FN = 0
someRecallDict = {0.3:0,
            0.4:0,
            0.5:0,
            0.6:0,
            0.7:0,
            0.8:0,
            0.9:0}

someRecall = [0.3,0.4,0.5,0.6,0.7,0.8,0.9]
res = []
posId = 0
predictPos = 0
for target, confidence in labelCon:
    count+=1
    if confidence>=0.5:
        predictPos+=1 # 預測爲正類的樣本個數
    if target==0:
        if confidence>=0.5:
            FP+=1
    if target==1:
        posCount+=1
        if confidence>=0.5:
            correctCount+=1
        else:
            FN+=1
        recall = float(correctCount)/float(totalPos)
        if posId<=6:
            if recall==someRecall[posId] and someRecallDict[someRecall[posId]]==0:
                someRecallDict[someRecall[posId]]=1
                posId+=1
                precision = int(str(s4j5(float(correctCount)/float(predictPos))*100).split('.')[0])
                res.append(precision)

for i in res:
    print(i)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章