在一般認知中,用模型對測試集進行分類預測,結果應該是X或者X'(也可以說是或者否)。根據混淆矩陣算出TP、FP、TN、FN,進一步算出TPR、FPR。一個測試集只會有一對TPR/FPR值,那么ROC曲線就只會有一個點,何談曲線之說?難道是用多個測試集得到多對TPR/FPR值,來繪制ROC曲線嗎?實則不然。
ROC曲線,一般適用於分類器輸出一個“概率值”,即這個樣本屬於某個類的概率是多少。在計算的時候會依次用所有樣本的概率值作為閾值, 用閥值和所有樣本的預測值進行比較,大於這個閾值的樣本預測為正類,小於這個閾值的樣本預測為負類。從而,對於每個閾值都能得到對應的TPR/FPR, 也就是ROC曲線上的一個點。樣本數量n=>閥值數量n=>點數量n(不考慮去重),最終構成ROC曲線。
計算示例
測試集7個樣本ABCDEFG的分類真實值:[0, 0, 0, 0, 1, 1, 1]
模型預測為1的概率分別是:[0.3, 0.2, 0.7, 0.5, 0.4, 0.9, 0.6]
1.以0.3為閥值,預測值[1, 0, 1, 1, 1, 1, 1]. TP、FP、TN、FN=3、3、1、0, TPR、FPR=3/3、3/4.
2.以0.2為閥值,預測值[1, 1, 1, 1, 1, 1, 1]. TP、FP、TN、FN=3、4、0、0, TPR、FPR=3/3、4/4.
3.以0.7為閥值,預測值[0, 0, 1, 0, 0, 1, 0]. TP、FP、TN、FN=1、1、3、2, TPR、FPR=1/3、1/4.
4.以0.5為閥值,預測值[0, 0, 1, 1, 0, 1, 1]. TP、FP、TN、FN=2、2、2、1, TPR、FPR=2/3、2/4.
5.以0.4為閥值,預測值[0, 0, 1, 1, 1, 1, 1]. TP、FP、TN、FN=3、2、2、0, TPR、FPR=3/3、2/4.
6.以0.9為閥值,預測值[0, 0, 0, 0, 0, 1, 0]. TP、FP、TN、FN=1、0、4、2, TPR、FPR=1/3、0/4.
7.以0.6為閥值,預測值[0, 0, 1, 0, 0, 1, 1]. TP、FP、TN、FN=2、1、3、1, TPR、FPR=2/3、1/4.
8.按照橫FPR縱TPR坐標從小到大排序坐標點:(0,0.33)(0.25,0.33)(0.25,0.67)(0.5,0.67)(0.5,1)(0.75,1)(1,1)
9.根據上述坐標點繪制曲線,計算曲線包圍的面積,即AUC的值
代碼示例
import numpy as np
from sklearn import metrics
import matplotlib.pyplot as plt
test_true = np.array([0, 0, 0, 0, 1, 1, 1])
test_pre = np.array([0.3, 0.2, 0.7, 0.5, 0.4, 0.9, 0.6])
fpr, tpr, thresholds = metrics.roc_curve(test_true, test_pre, pos_label=1)
print fpr
print tpr
print thresholds
plt.plot(fpr,tpr,marker = 'o')
plt.show()
auc = metrics.auc(fpr, tpr)
print auc
'''
值得關注的函數,注意pos_label的設置
fpr, tpr, thresholds=sklearn.metrics.roc_curve(y_true,y_score,pos_label=None)
pos_label : int or str, default=None,Label considered as positive and others are considered negative.
'''
關於閥值
最后說明一點,用每個概率結果作為閥值是計算ROC曲線的一個度量元素。沒有業務語義。不用過多思考。
但在實際項目中,如何用概率結果判斷業務分類,就需要思考閥值的具體設定了。不能想當然的用0.5一刀切,可以參考:
http://blog.sina.com.cn/s/blog_13a4bb3270102w1om.html