機器學習之ROC和AUC(python程式碼)
1.什麼是ROC:
ROC曲線:接收者操作特徵曲線(receiver operating characteristic curve),是反映敏感性和特異性連續變數的綜合指標,roc曲線上每個點反映著對同一訊號刺激的感受性。
2.如果學習ROC,首先必須知道什麼:
TPR的英文全稱為:True Positive Rate
FPR的英文全稱為:False Positive Rate
中文解釋為:
TPR(真正例率):真實值是正例,且預測為正例的比例
FPR(假正例率):真實值為負例,
例如此圖:
此圖分為四部分:
A部分:真實為正例,預測為正例
B部分:真實為正例,預測為負例
C部分:真實為負例,預測為正例
D部分:真實為負例,預測為負例
ROC曲線就是以TPR為Y軸,以FPR為X軸,然後以一個對不同的預測值進行分類.
當取不同閾值時會得到不同的TPR和FPR,對應於ROC曲線上的一個點。
那麼ROC曲線就反映了FPR與TPR之間動態關係的情況。
通俗地來說,即在TPR隨著FPR遞增的情況下,誰增長得更快,快多少的問題。
TPR增長得越快,曲線越往上曲,反映了模型的分類效能就越好。
當正負樣本不平衡時,這種模型評價方式比起一般的精確度評價方式 的好處尤其顯著。
說完ROC,說一下AUC。
AUC (Area Under Curve) 被定義為ROC曲線下的面積,顯然這個面積的數值不會大於1。
又由於ROC曲線一般都處於y=x這條直線的上方,所以AUC的取值範圍一般在0.5和1之間。
使用AUC值作為評價標準是因為很多時候ROC曲線並不能清晰的說明哪個分類器的效果更好,而作為一個數值,對應AUC更大的分類器效果更好。
從AUC判斷分類器(預測模型)優劣的標準:
- AUC = 1,是完美分類器,採用這個預測模型時,存在至少一個閾值能得出完美預測。絕大多數預測的場合,不存在完美分類器。
- 0.5 < AUC < 1,
- AUC = 0.5,跟隨機猜測一樣(例:丟銅板),模型沒有預測價值。
- AUC < 0.5,比隨機猜測還差;但只要總是反預測而行,就優於隨機猜測。
為什麼使用ROC和AUC?
既然已經這麼多評價標準,為什麼還要使用ROC和AUC呢?因為ROC曲線有個很好的特性:當測試集中的正負樣本的分佈變化的時候,ROC曲線能夠保持不變。 在實際的資料集中經常會出現類不平衡(class imbalance)現象,即負樣本比正樣本多很多(或者相反),而且測試資料中的正負樣本的分佈也可能隨著時間變化。 繪製ROC曲線程式碼如下:#繪製ROC曲線函式
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve,auc
from sklearn.model_selection import StratifiedKFold
def drawROC(classifier,X,y):
#X:訓練集/測試集
#y:訓練集標籤/測試集標籤
print(X.shape)
print(y.shape)
# 畫平均ROC曲線的兩個引數
mean_tpr= 0.0 # 用來記錄畫平均ROC曲線的資訊
mean_fpr= np.linspace(0,1,100)
cnt = 0
cv = StratifiedKFold(n_splits=6) #匯入該模型,後面將資料劃分6份
for i,(train,test) in enumerate(cv.split(X,y)): #利用模型劃分資料集和目標變數 為一一對應的下標
cnt +=1
probas_ = classifier.fit(X[train],y[train]).predict_proba(X[test]) # 訓練模型後預測每條樣本得到兩種結果的概率
fpr,tpr,thresholds = roc_curve(y[test],probas_[:,1]) # 該函式得到偽正例、真正例、閾值,這裡只使用前兩個
mean_tpr+= np.interp(mean_fpr,fpr,tpr) # 插值函式interp(x座標,每次x增加距離,y座標) 累計每次迴圈的總值後面求平均值
mean_tpr[0] = 0.0 # 將第一個真正例=0 以0為起點
roc_auc = auc(fpr,tpr) # 求auc面積
plt.plot(fpr,tpr,lw=1,label='ROC fold {0:.2f} (area = {1:.2f})'.format(i,roc_auc)) # 畫出當前分割資料的ROC曲線
plt.plot([0,1],[0,1],'--',color=(0.6,0.6,0.6),label='Luck') # 畫對角線
mean_tpr/= cnt # 求陣列的平均值
mean_tpr[-1] = 1.0 # 座標最後一個點為(1,1) 以1為終點
mean_auc = auc(mean_fpr,mean_tpr)
plt.plot(mean_fpr,mean_tpr,'k--',label='Mean ROC (area = {0:.2f})'.format(mean_auc),lw=2)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate') # 可以使用中文,但需要匯入一些庫即字型
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
#呼叫
train_Y[train_Y == 2] = 0
print(train_Y)
drawROC(clf,train_X[:,:],train_Y[:])
繪圖效果: