1. 程式人生 > >機器學習-淺談模型評估的方法和指標

機器學習-淺談模型評估的方法和指標

以處理流程為骨架來學習方便依照框架的充實細節又不失概要(參考下圖機器學習處理流程的一個例項<<Python資料分析與挖掘實戰>>),今天就充實一下模型評估(模型評價)的部分吧.

圖-1-機器學習處理流程例項

本"故事"以<<Python資料分析與挖掘實戰>>中預測使用者是否竊漏電的例子來展開,自問自答,為什麼要評估和怎麼評估,具體的概念在下文有列出.

  • 分析目標是基於使用者每天的用電量為基本資料來預測使用者是否竊漏電.
  • 首先,通過資料分析總結得到三個指標,
  • 然後,分別選用神經網路決策樹來訓練得出預測模型。
  • 之後,對訓練資料的預測結果進行混淆矩陣(Confusion Matrix)
    運算
  • 最後,對測試資料進行預測並進行ROC(Receiver Operating Characteristic)評估,看哪個更優. 三個指標和資料樣例如下:

    圖-2-資料-model.xls樣例資料

電量趨勢下降指標: 如果電量趨勢不斷下降,則有竊電可能線損指標:供電線路損失的比例,考慮前後幾天的增長率如果大於1%則有竊電可能告警指標:電錶終端報警,如電壓缺相,電壓斷相等的次數

順便再次告誡自己:紙上得來淺,程式碼同行。以下程式碼用到了Python 的pandas(資料分析和處理), keras(神經網路), matplotlib(視覺化),sklearn(機器學習)包,對<<Python資料分析與挖掘實戰>>

中程式碼稍有修改。思路如下: 1 匯入資料 2 用訓練資料建立決策樹模型 3 對訓練資料用混淆矩陣評估決策樹模型的預測結果 4 用訓練資料建立神經網路模型 5 對訓練資料用混淆矩陣評估神經網路模型的預測結果 6 用學習得到的決策樹模型和神經網路模型跑測試資料來預測 7 用ROC曲線評估,選出更優的一個模型

程式碼包括cm_plot.pymodel.py如下,程式碼環境主要包括( Ubuntu 14.04.2 LTS, python2.7, keras 2.0.4, tensorflow 1.0.0),測試程式碼時在引入keras時報錯,後升級tensorflow,並指定其為keras的backend後跳出了坑:

# cm_plot.py 檔案,包括了混淆矩陣視覺化函式,
# 放置在python的site-packages 目錄,供呼叫
# 例如:~/anaconda2/lib/python2.7/site-packages
#-*- coding: utf-8 -*-
def cm_plot(y, yp):
  from sklearn.metrics import confusion_matrix #匯入混淆矩陣函式
  cm = confusion_matrix(y, yp) #混淆矩陣
  import matplotlib.pyplot as plt #匯入作相簿
  plt.matshow(cm, cmap=plt.cm.Greens) #畫混淆矩陣圖,配色風格使用cm.Greens,更多風格請參考官網。
  plt.colorbar() #顏色標籤
  for x in range(len(cm)): #資料標籤
    for y in range(len(cm)):
      plt.annotate(cm[x,y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
  plt.ylabel('True label') #座標軸標籤
  plt.xlabel('Predicted label') #座標軸標籤
  return plt
#-*- coding: utf-8 -*-
# model.py構建並評估CART決策樹和LM神經網路演算法
import pandas as pd #匯入資料分析庫
from random import shuffle #匯入隨機函式shuffle,用來打散資料
datafile = 'model.xls' #資料(如圖-2所示)
data = pd.read_excel(datafile) #讀取資料,資料的前三列是特徵,第四列是標籤,'1'表示竊漏電,'0'表示沒有竊漏電
data = data.as_matrix() #將表格轉換為矩陣
shuffle(data) #隨機打亂資料

# 把資料的80%用來訓練模型,20%做模型測試和評估,此處用到訓練集-驗證集二劃分
p = 0.8 #設定訓練資料比例,
train = data[:int(len(data)*p),:] #前80%為訓練集
test = data[int(len(data)*p):,:] #後20%為測試集

#構建CART決策樹模型
from sklearn.tree import DecisionTreeClassifier #匯入決策樹模型
treefile = 'tree.pkl' #模型輸出名字
tree = DecisionTreeClassifier() #建立決策樹模型
tree.fit(train[:,:3], train[:,3]) #訓練得出決策樹模型

#儲存模型
from sklearn.externals import joblib
joblib.dump(tree, treefile)

#用混淆矩陣視覺化函式畫圖
from cm_plot import * #匯入混淆矩陣視覺化函式
cm_plot(train[:,:3], tree.predict(train[:,:3])).show() #顯示混淆矩陣視覺化結果如下

圖-3-決策樹分類預測混淆矩陣

#構建LM神經網路模型
import os
os.environ['KERAS_BACKEND']='tensorflow'#先設定keras 採用tensorflow 作為Backend
from keras.models import Sequential #匯入神經網路初始化函式
from keras.layers.core import Dense, Activation #匯入神經網路層函式、啟用函式
netfile = 'net.model' #構建的神經網路模型儲存路徑
net = Sequential() #建立神經網路
net.add(Dense(input_dim = 3, output_dim = 10)) #新增輸入層(3節點)到隱藏層(10節點)的連線
net.add(Activation('relu')) #隱藏層使用relu啟用函式
net.add(Dense(input_dim = 10, output_dim = 1)) #新增隱藏層(10節點)到輸出層(1節點)的連線
net.add(Activation('sigmoid')) #輸出層使用sigmoid啟用函式
net.compile(loss = 'binary_crossentropy', optimizer = 'adam', class_mode = "binary") #編譯模型,使用adam方法求解
net.fit(train[:,:3], train[:,3], epochs=1000, batch_size=1) #訓練模型,迴圈1000次

#儲存模型
net.save_weights(netfile) 
predict_result = net.predict_classes(train[:,:3]).reshape(len(train)) #預測結果變形這裡要提醒的是,keras用predict給出預測概率

#用混淆矩陣視覺化函式畫圖
cm_plot(train[:,3], predict_result).show() #顯示混淆矩陣視覺化結果

圖-4-神經網路分類預測混淆矩陣

# 用ROC曲線選取較優模型,曲線越貼近左上,模型越優.
from sklearn.metrics import roc_curve #匯入ROC曲線函式
import matplotlib.pyplot as plt #匯入視覺化包
# 上面的圖是決策樹模型下用測試資料跑出的ROC曲線
plt.subplot(211)
fpr1, tpr1, thresholds1 = roc_curve(test[:,3], tree.predict_proba(test[:,:3])[:,1], pos_label=1)
plt.plot(fpr1, tpr1, linewidth=2, label = 'ROC of CART', color = 'green') #作出ROC曲線
plt.xlabel('False Positive Rate') #座標軸標籤
plt.ylabel('True Positive Rate') #座標軸標籤
plt.ylim(0,1.05) #邊界範圍
plt.xlim(0,1.05) #邊界範圍
plt.legend(loc=4) #圖例

# 下面的圖是神經網路模型下用測試資料跑出的ROC曲線
predict_result = net.predict(test[:,:3]).reshape(len(test))
plt.subplot(212)
fpr2, tpr2, thresholds2 = roc_curve(test[:,3], predict_result, pos_label=1)
plt.plot(fpr2, tpr2, linewidth=2, label = 'ROC of LM',color='red') #作出ROC曲線
plt.xlabel('False Positive Rate') #座標軸標籤
plt.ylabel('True Positive Rate') #座標軸標籤
plt.ylim(0,1.05) #邊界範圍
plt.xlim(0,1.05) #邊界範圍
plt.legend(loc=4) #圖例
plt.show() #顯示作圖結果

圖5-ROC曲線比較

從圖中比較LM神經網路較優,是騾子是馬,還是拉出來溜溜,當然還要看在實際資料中的表現嘍:-)通過例子咱們也總結一下,把相關的知識整理整理.

為什麼要評估模型?

一句話,想找到最有效的模型.模型的應用是迴圈迭代的過程,只有通過持續調整和調優才能適應線上資料和業務目標.這跟我們買鞋子有一比,鞋子是模型,左挑右選,好嗎,選了個合適的,可是這腳,它不斷有變化,怎麼辦,持續調唄. 選用模型開始都是假設資料的分佈是一定的,然而資料的分佈會隨著時間的移動而改變,這種現象稱為分佈漂移(Distribution Drift)。驗證指標可以對模型在不斷新生的資料集上進行效能跟蹤。當效能開始下降時,說明該模型已經無法擬合當前的資料了,因此需要對模型進行重新訓練了。 模型能夠擬合新的資料稱為模型的泛化能力。就像我們上面的例子,訓練模型時用的是歷史資料,可是資料是不停的產生跟新的,機器學習怎麼學,請看下一個問題.

怎麼檢驗和評估模型?

機器學習過程分為原型設計階段(Prototyping)與應用階段(Deployed), 其中有原型設計階段(Prototyping)離線評估應用階段(Deployed)線上評估(online evaluation).Prototyping階段是使用歷史資料訓練一個適合解決目標任務的一個或多個機器學習模型,並對模型進行驗證(Validation)與離線評估(Offline evaluation),然後通過評估指標選擇一個較好的模型。我們上面的例子就是Prototyping.Deployed階段是當模型達到設定的指標值時便將模型上線,投入生產,使用新生成的線上資料來對該模型進行線上評估(Online evaluation),線上測試不同於離線測試,有著不同的測試方法以及評價指標。最常見的便是A/B testing,它是一種統計假設檢驗方法。離線評估線上評估採用不同的評估指標,在對模型進行離線評估時是採用偏經驗誤差的方法,在線上評估時會採用業務指標,如裝置使用效率(OEE), 使用者點選率等. 通過檢驗和評估可能選擇單一模型,也能使用多個模型混合.那到底怎麼選呢?

評估過程中如何調優?

找到合適的鞋子是一個複雜的過程,還好,現在很多演算法都很好的打包成包依照不同的開發語言釋出出來,我們上面的例子就是一個很好的說明,也有各類軟體(SAS, SPSS, Rapidminer, Knime等),其實以上程式碼完全可以用詞類工具實現.機器學習模型建立過程是一個引數學習與調優的過程。對模型進行訓練,便是模型引數的學習更新過程,除了模型引數還有超引數(hyperparameters)。例如logistic迴歸中的特徵係數為模型引數,需要使用多少個特徵進行表徵,特徵的數目這個引數便是該模型的超引數。可以用格搜尋(grid search)隨機搜尋(random search)以及啟發式搜尋(smart search)等進行Hyperparameter tuning, 從超引數空間中尋找最優的值。

格搜尋(grid search) 格搜尋便是將超引數的取值範圍劃分成一個個格子,對每一個格子所對應的值進行評估,選擇評估結果最好的格子所對應的超引數值。例如,對於決策樹葉子節點個數這一超引數,可以將值劃分為這些格子:10, 20, 30, …, 100, …;

隨機搜尋(random search) 它是格搜尋的變種。相比於搜尋整個格空間,隨機搜尋只對隨機取樣的那些格進行計算,然後在這中間選擇一個最好的。因此隨機搜尋比格搜尋的代價低。

在離線評估階段從歷史資料據獲取資料集校驗模型的方法包括訓練集-驗證集二劃分校驗(Hold-out validation)交叉校驗(Cross-validation), 另一種方式是重取樣技術,如bootstrappingJackknife,此類方法可以充分利用現有資料資訊,一定程度減少過擬合。 ( 參考百度百科抽樣資料方式)

交叉驗證

圖-6-交叉校驗(Cross-validation)

評估指標 (Evaluation Matrics)是什麼?

評估指標是把"尺子",用來評判模型優劣水平的演算法,不同的機器學習模型有著不同的"尺子",同時同一種機器學習模型也可以用不同的尺子來評估,只是每個尺子的的著重點不同而已。對於分類(classification)、迴歸(regression)、排序(ranking)、聚類(clustering)、推薦(recommendation),很多指標可以對其進行評價,如精確率-召回率(precision-recall),可以用在分類、推薦、排序等中.以下是各類"尺子"的定義,用到時才看,僅供參考.

錯誤率,精度,誤差的基本概念:

錯誤率(error rate)= a個樣本分類錯誤/m個樣本   精度(accuracy)= 1 -錯誤率   誤差(error):學習器實際預測輸出與樣本的真是輸出之間的差異。   訓練誤差(training error):即經驗誤差。學習器在訓練集上的誤差。   泛化誤差(generalization error):學習器在新樣本上的誤差。 .

分類器評估指標

對於二分類問題,可將樣例根據其真實類別和分類器預測類別劃分為:真正例(True Positive,TP):真實類別為正例,預測類別為正例。假正例(False Positive,FP):真實類別為負例,預測類別為正例。假負例(False Negative,FN):真實類別為正例,預測類別為負例。真負例(True Negative,TN):真實類別為負例,預測類別為負例。 然後可以構建混淆矩陣(Confusion Matrix)如下表所示,就是我們例子中用到的。

圖-7-混淆矩陣(Confusion Matrix)

ROC AUC(Area Under ROC Curve): ROC 曲線和 AUC 常被用來評價一個二值分類器的優劣。若一個學習器的ROC曲線被另一個包住,後者的效能能優於前者;若交叉,判斷ROC曲線下的面積,即AUC.

ROC: 縱軸:真正例率 TPR;橫軸:假正例率FPR   

圖8-TPR & FPR

圖9-ROC & AUC

先看圖中的四個點和對角線: 第一個點,(0,1),即 FPR=0, TPR=1,這意味著 FN(false negative)=0,並且FP(false positive)=0。這意味著分類器很完美,因為它將所有的樣本都正確分類。 第二個點,(1,0),即 FPR=1,TPR=0,這個分類器是最糟糕的,因為它成功避開了所有的正確答案。 第三個點,(0,0),即 FPR=TPR=0,即 FP(false positive)=TP(true positive)=0,此時分類器將所有的樣本都預測為負樣本(negative)。 第四個點(1,1),分類器將所有的樣本都預測為正樣本。 對角線上的點表示分類器將一半的樣本猜測為正樣本,另外一半的樣本猜測為負樣本。因此,ROC 曲線越接近左上角,分類器的效能越好。

例如有如下 20 個樣本資料,Class 為真實分類,Score 為分類器預測此樣本為正例的概率。

圖10-ROC運算中的資料

  • 按 Score 從大到小排列依次將每個 Score 設定為閾值,
  • 然後這 20 個樣本的標籤會變化,當它的 score 大於或等於當前閾值時,則為正樣本,否則為負樣本。
  • 這樣對每個閾值,可以計算一組 FPR 和 TPR,此例一共可以得到 20 組。
  • 當閾值設定為 1 和 0 時, 可以得到 ROC 曲線上的 (0,0) 和 (1,1) 兩個點。

圖11-ROC曲線

AUC:

AUC考慮的是樣本預測的排序質量,因此它與排序誤差有緊密聯絡。給定 m+個正例,m-個反例,令D+和D-分別表示正、反例集合,則排序 ”損失”定義為:  

Lrank對應ROC曲線之上的面積:若一個正例在ROC曲線上標記為(x,y) ,則x恰是排序在期前的所有反例所佔比例,即假正例,因此:

準確率,又稱查準率(Precision,P):

召回率,又稱查全率(Recall,R):F1值:

F1的一般形式

Β>0度量了查全率對查準率的相對重要性;β=1退化為F1;β>1查全率有更大影響;β<1查準率有更大影響。

巨集平均(macro-average)微平均(micro-average)一般用在文字分類器, 如果只有一個二分類混淆矩陣,那麼用以上的指標就可以進行評價,但是當我們在n個二分類混淆矩陣上要綜合考察評價指標的時候就會用到巨集平均和微平均。

巨集平均(Macro-averaging): 是先對每一個類統計指標值,然後在對所有類求算術平均值。巨集平均指標相對微平均指標而言受小類別的影響更大。

微平均(Micro-averaging):是對資料集中的每一個例項不分類別進行統計建立全域性混淆矩陣,然後計算相應指標。

平均準確率(Average Per-class Accuracy):   為了應對每個類別下樣本的個數不一樣的情況,計算每個類別下的準確率,然後再計算它們的平均值。

對數損失函式(Log-loss):   在分類輸出中,若輸出不再是0-1,而是實數值,即屬於每個類別的概率,那麼可以使用Log-loss對分類結果進行評價。這個輸出概率表示該記錄所屬的其對應的類別的置信度。比如如果樣本本屬於類別0,但是分類器則輸出其屬於類別1的概率為0.51,那麼這種情況認為分類器出錯了。該概率接近了分類器的分類的邊界概率0.5。Log-loss是一個軟的分類準確率度量方法,使用概率來表示其所屬的類別的置信度。Log-loss具體的數學表示式為:

其中,yi是指第i個樣本所屬的真實類別0或者1,pi表示第i個樣本屬於類別1的概率,這樣上式中的兩個部分對於每個樣本只會選擇其一,因為有一個一定為0,當預測與實際類別完全匹配時,則兩個部分都是0,其中假定0log0=0。其實,從數學上來看,Log-loss的表示式是非常漂亮的。我們仔細觀察可以發現,其資訊理論中的交叉熵(Cross Entropy,即真實值與預測值的交叉熵),它與相對熵(Relative Entropy,也稱為KL距離或KL散度, Kullback–Leibler divergence.)也非常像。資訊熵是對事情的不確定性進行度量,不確定越大,熵越大。交叉熵包含了真實分佈的熵加上假設與真實分佈不同的分佈的不確定性。因此,log-loss是對額外噪聲(extra noise)的度量,這個噪聲是由於預測值域實際值不同而產生的。因此最小化交叉熵,便是最大化分類器的準確率。

迴歸模型評估指標

迴歸是對連續的實數值進行預測,即輸出值是連續的實數值,而分類中是離散值。對於迴歸模型的評價指標主要有以下幾種:RMSE(root mean square error,平方根誤差),其又被稱為RMSD(root mean square deviation),RMSE對異常點(outliers)較敏感,如果迴歸器對某個點的迴歸值很不理性,那麼它的誤差則較大,從而會對RMSE的值有較大影響,即平均值是非魯棒的。其定義如下:

Quantiles of Errors 為了改進RMSE的缺點,提高評價指標的魯棒性,使用誤差的分位數來代替,如中位數來代替平均數。假設100個數,最大的數再怎麼改變,中位數也不會變,因此其對異常點具有魯棒性。

作者:溫故知新的駱駝 連結:https://www.jianshu.com/p/498ea0d8017d 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。