受試者工作特征曲線(receiver operating characteristic curve,簡稱ROC曲線)些阅,是比較兩個分類模型好壞的可視化工具
ROC曲線的作用:
1.較容易地查出任意界限值時的對類別的識別能力
2.選擇最佳的診斷界限值。ROC曲線越靠近左上角,試驗的準(zhǔn)確性就越高。最靠近左上角的ROC曲線的點是錯誤最少的最好閾值,其假陽性和假陰性的總數(shù)最少崎场。
3.兩種或兩種以上不同診斷試驗對算法性能的比較。在對同一種算法的兩種或兩種以上診斷方法進行比較時遂蛀,可將各試驗的ROC曲線繪制到同一坐標(biāo)中照雁,以直觀地鑒別優(yōu)劣,靠近左上角的ROC曲線所代表的受試者工作最準(zhǔn)確。亦可通過分別計算各個試驗的ROC曲線下的面積(AUC)進行比較饺蚊,哪一種試驗的AUC最大,則哪一種試驗的診斷價值最佳悬嗓。
集才華與美麗于一身的ROC曲線到底是什么污呼?
ROC曲線是根據(jù)一系列不同的二分類方式(分界值或決定閾),以真陽性率TPR(靈敏度)為縱坐標(biāo)包竹,假陽性率FPR(1-特異度)為橫坐標(biāo)繪制的曲線燕酷。
那么TPR和FPR都是什么意思?先看下混淆矩陣
這樣可以一目了然的看出正確分類和錯誤分類的樣本數(shù)量周瞎,所以
準(zhǔn)確率precision=(TP+TN)/(P+N)
但是在實際應(yīng)用中苗缩,我們感興趣的類往往只占少數(shù),所以在test集存在類不平衡的情況下声诸,準(zhǔn)確率對于我們的模型意義很小酱讶,eg:test中續(xù)費90,流失10彼乌,即使你把所有的樣本預(yù)測為續(xù)費泻肯,準(zhǔn)確率依然為90%,但對于我們感興趣的流失用戶而言慰照,這個模型沒有什么意義
所以灶挟,現(xiàn)實中我們更在乎的其實是召回率,即靈敏度毒租,當(dāng)然我們一般關(guān)注較高的是我們感興趣類的召回率
recall =TP/(TP+FN)=TP/P
F度量則對準(zhǔn)確率和召回率做一個權(quán)衡
F=(1+a2)*precision*recall/(a*precision+recall)
a2是a的平方稚铣,一般默認(rèn)a= 1
說了這么多看似跟ROC沒有相關(guān)的概念,但其實理解了上面的公式才能更好的理解ROC的作用墅垮,這里是美麗的分割線惕医,下面是優(yōu)美的ROC曲線
定義:
TPR = TP/P? 即召回率公式
FPR = FP/N? 即1-specificity
ROC曲線是以FPR為橫坐標(biāo),以TPR為縱坐標(biāo)噩斟,以概率為閾值來度量模型正確識別正實例的比例與模型錯誤的把負(fù)實例識別成正實例的比例之間的權(quán)衡曹锨,TPR的增加必定以FPR的增加為代價,ROC曲線下方的面積是模型準(zhǔn)確率的度量
所以根據(jù)ROC曲線定義可知剃允,繪制ROC要求模型必須能返回監(jiān)測元組的類預(yù)測概率沛简,根據(jù)概率對元組排序和定秩,并使正概率較大的在頂部斥废,負(fù)概率較大的在底部進行畫圖
ROC曲線:根據(jù)數(shù)據(jù)實例畫圖
備注:實例
隨機猜測的曲線是默認(rèn)正負(fù)都按照0.5概率平均分類時的ROC曲線椒楣,那么離隨機猜測曲線較遠(yuǎn)的點就是最好的概率選擇閾值,該圖中的凸包旁邊點對應(yīng)的概率就是我們所要選擇的概率牡肉,即根據(jù)ROC凸點選擇概率閾值和根據(jù)凸點判斷兩個模型好壞的由來
Python代碼實現(xiàn):
fromsklearn.metricsimportroc_curve
#roc_curve輸出為tpr捧灰、fpr假正和真正概率,且第二個參數(shù)一定要是概率估計或者置信度
fpr,tpr,thresholds = roc_curve(test[:,3],tree.predict_proba(test[:,:3])[:,1],pos_label=1)
#pos_labels設(shè)置的為感興趣方的標(biāo)簽
#predict_probs前面輸出的是0的概率,后面輸出的是1的概率毛俏,如果不清楚可以只用predict
#查看結(jié)果與概率的對應(yīng)情況
#一般吧流失設(shè)置為1炭庙,續(xù)費設(shè)置為0,感興趣的設(shè)置為1
plt.plot(fpr,tpr,linewidth=2,label="ROC")
plt.xlabel("false presitive rate")
plt.ylabel("true presitive rate")
plt.ylim(0,1.05)
plt.xlim(0,1,05)
plt.legend(loc=4)#圖例的位置
plt.show()