Roc曲線和PR曲線的理解及簡單的代碼實現
1.引言
Roc曲線和PR曲線常被用來在二分類問題中評估一個分類器的性能,所以在機器學習中搞清楚兩種曲線的原理及其區別與實現是非常基礎也是非常重要的。
2.幾個度量的介紹與理解
首先我們必須要了解混淆矩陣:表示模型將樣本分類的結果的矩陣
我們可以簡單的舉個例子:1000個標本,有100個正樣本,其中40真實正確,60個真實錯誤(二分法中預測正確指真實結果爲正例預測結果爲正例,真實結果爲反例預測結果爲反例)
真實結果爲正例 | 真實結果爲反例 | |
---|---|---|
預測結果爲正例§ | TP:40 | FP:60 |
預測結果爲反例(N) | FN:400 | TN:500 |
在Roc曲線和PR曲線中有四個重要的度量:精確率(查準率),召回率(查全率),真正例率,假正例率。
精確率(precison):
召回率(recall):
真正例率(tpr):
假正例率(fpr):
3.PR曲線的理解
召回率(recall): 理解爲在所有的真實正例中,被正確預測的佔比
精確度(precision):理解爲在所有的預測正例中(包括正確預測得出正例和錯誤預測得出正例),預測正確的比例
若一個學習器的P-R曲線被另一個學習器的曲線圍住的話,則後者的性能優於前者。當存在交叉時,可以計算曲線圍住面積,平衡點(BEP,精確度=召回度)是一種度量方式。但BEP過於簡化,所以我們通常將兩個度量合併在一起得到F1.(這裏個人覺得F1與圖像關聯不大,只是一個定義,有誤請指正)
我們可以理解將F1公式中的P當做R,可以發現當F1大,BEP相應的也大。
且PR曲線越靠右上方代表模型效果越好
接下來我們用簡單的實例來說明PR曲線
首先我們先說明一下繪製PR曲線時的幾個步驟。
- 我們將會有真實的標籤(例如貓狗大戰中,貓爲1,狗爲0)
- 當我們訓練模型後會出現一個置信度(預測概率)
- 將置信度與標籤一一對應從高到低排序
- 我們需要設置閾值(與精確度和召回率息息相關),我們將大於閾值的置信度做爲正樣本(及可以理解爲我們預測的正確的數據)
- 然後將每一次閾值所劃分出的混淆矩陣計算精確率和召回率
- 繪圖
以下數據和接下來代碼數據相同(置信度已由高到低排序)
這裏我們把標籤爲1當做實際正確,標籤爲0當做實際錯誤
標籤data_labels | 置信度confidence_scores |
---|---|
1 | 0.9 |
1 | 0.78 |
0 | 0.6 |
1 | 0.46 |
0 | 0.4 |
0 | 0.37 |
1 | 0.2 |
1 | 0.16 |
在嚴謹的情況下我們一般閾值都是先設爲1,然後逐步下降,但是我們用sklearn.metrics(Sklearn.metrics模塊的功能是提供評估模型效果的指標函數,包括混淆矩陣、準確率、精確率、召回率、F值、ROC曲線、AUC、PR曲線等等。)來繪製PR曲線時,閾值是通過置信度從大到小取(這裏數據取8次)。
我們取當閾值爲0.6時的情況來講解。
當閾值爲0.6時,我們可以得到的正樣本(其餘爲負樣本)應該是置信度大於等於0.6的數據,爲
標籤data_labels | 置信度confidence_scores |
---|---|
1 | 0.9 |
1 | 0.78 |
0 | 0.6 |
這裏的正樣本可以理解爲我們預測爲正確的樣本有3個,但是其中真正正確的只有2個,所以我們的精確率precision=2/3。召回率recall我們可以理解爲,在所有真正正確的樣本中(這裏有5個樣本,就是標籤爲1的樣本)我們預測的正樣本中預測正確的樣本的比例(正樣本中標籤爲1的樣本)所以,我們可以計算出recall=2/5.
總結:PR曲線因爲對樣本比例敏感,因此能夠看出分類器隨着樣本比例變化的效果,而實際中的數據又是不平衡的,這樣有助於瞭解分類器實際的效果和作用,也能夠以此進行模型的改進。PR曲線的召回率不斷上升,而精確率以略微震盪的方式呈下降趨勢。
4.Roc曲線的理解
真正率(true positive rate,TPR)或靈敏度(sensitivity),定義爲被模型正確預測的正樣本的比例
真負率(true negative rate,TFR)或特指度(specificity),定義爲被模型正確預測的負樣本的比例
Roc曲線繪圖過程與PR曲線類似,就是x軸,y軸的度量發生變化
這裏我們沿用上面的數據,例子
標籤data_labels | 置信度confidence_scores |
---|---|
1 | 0.9 |
1 | 0.78 |
0 | 0.6 |
1 | 0.46 |
0 | 0.4 |
0 | 0.37 |
1 | 0.2 |
1 | 0.16 |
我們取閾值爲0.46的情況進行分析
置信度大於0.46的樣本爲正樣本(即我們預測爲正確的樣本),爲
標籤data_labels | 置信度confidence_scores |
---|---|
1 | 0.9 |
1 | 0.78 |
0 | 0.6 |
1 | 0.46 |
真正率我們可以理解爲正樣本中我們預測正確的樣本中(4個)真正正確的有3個(即正樣本標籤爲1的樣本)與真正正確的所有樣本(所有樣本標籤爲1的樣本)的比值,所以TPR=3/5
真假率可以理解爲預測正確的樣本中(4個)真正錯誤的有1個(即正樣本中標籤爲0的樣本)與真正錯誤的所有樣本(所有樣本標籤爲0的樣本)的比值,所以FPR=1/3
AUC(Area Under Curve)即指曲線下面積佔總方格的比例。有時不同分類算法的ROC曲線存在交叉,因此很多時候用AUC值作爲算法好壞的評判標準。面積越大,表示分類性能越好。(理想化的AUC爲1)
當隨機挑選一個正樣本以及一個負樣本,當前的分類算法根據計算得到的分數將這個正樣本排在負樣本前面的概率就是AUC值。所以,AUC的值越大,當前的分類算法越有可能將正樣本排在負樣本值前面,既能夠更好的分類。
在ROC空間,ROC曲線越凸向左上方向效果越好。
5.簡要代碼繪製兩種曲線
因爲只是理解ROC曲線和PR曲線的含義,所以我們這裏沒有用到大量的模型數據,只是簡單的自己構造了一些標籤和置信度,所以數據量很小,曲線並不平滑,標準的ROC曲線和PR曲線如上面兩張圖。現在附上代碼
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve,roc_curve
plt.figure()
plt.title('PR Curve')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.grid()
#只是理解兩種曲線的含義,所以數據簡單的構造
confidence_scores = np.array([0.9,0.46,0.78,0.37,0.6,0.4,0.2,0.16])
confidence_scores=sorted(confidence_scores,reverse=True)#置信度從大到小排列
print(confidence_scores)
data_labels = np.array([1,1,0,1,0,0 ,1,1])#置信度所對應的標籤
#精確率,召回率,閾值
precision,recall,thresholds = precision_recall_curve(data_labels,confidence_scores)
print(precision)
print(recall)
print(thresholds)
plt.plot(recall,precision)
plt.show()
#真正率,假正率
fpr, tpr, thresholds = roc_curve(data_labels, confidence_scores)
#print(fpr)
#print(tpr)
plt.figure()
plt.grid()
plt.title('Roc Curve')
plt.xlabel('FPR')
plt.ylabel('TPR')
from sklearn.metrics import auc
auc=auc(fpr, tpr)#AUC計算
plt.plot(fpr,tpr,label='roc_curve(AUC=%0.2f)'%auc)
plt.legend()
plt.show()
如果想看更詳細的代碼,https://blog.csdn.net/jcfszxc/article/details/102829505
以上是作者對PR曲線及ROC曲線的簡要理解,做爲學習筆記,若有理解錯誤的地方,歡迎大家提出!