1. 程式人生 > 其它 >機器學習之ROC和AUC(python程式碼)

機器學習之ROC和AUC(python程式碼)

1.什麼是ROC:

    ROC曲線:接收者操作特徵曲線(receiver operating characteristic curve)是反映敏感性和特異性連續變數的綜合指標roc曲線上每個點反映著對同一訊號刺激的感受性。

2.如果學習ROC首先必須知道什麼:

         要學習ROC曲線首先得知道什麼是TPR什麼是FPR。

          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[:])

繪圖效果: