機器學習1:模型評估

機器學習有兩個非常重要的問題:

1.How well is my model doing?

如果我們已經訓練好了模型,該模型效果如何,用什麼方式來檢爲測?

2.How do we improve the model based on these metrics?

如何根據這些檢測指標改善模型。

如何合理,科學,有效的評估和改善模型,是所有機器學習算法通用問題,因此單獨總結以下

1.分離數據:

將數據分爲訓練集和測試集

t000

注意:\underline{永遠不要讓測試集進入訓練環境}

# Import statements 
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
import pandas as pd
import numpy as np

# Import the train test split
# http://scikit-learn.org/0.16/modules/generated/sklearn.cross_validation.train_test_split.html

# USE from sklearn.model_selection import train_test_split to avoid seeing deprecation warning.
from sklearn.model_selection import train_test_split
#from sklearn.cross_validation import train_test_split

# Read in the data.
data = np.asarray(pd.read_csv('data.csv', header=None))
# Assign the features to the variable X, and the labels to the variable y. 
X = data[:,0:2]
y = data[:,2]

# Use train test split to split your data 
# Use a test size of 25% and a random state of 42
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
# Instantiate your decision tree model
model = DecisionTreeClassifier()

# TODO: Fit the model to the training data.
model.fit(X_train, y_train)
# TODO: Make predictions on the test data
y_pred = model.predict(X_test)

# TODO: Calculate the accuracy and assign it to the variable acc on the test data.
acc = accuracy_score(y_test, y_pred)

print(acc)
0.9583333333333334

2.混淆矩陣(evaluation matrix)

比如醫療模型,檢測結果可以分爲四種境況;

真陽性:就診者患病,模型檢測爲陽性,認爲患病需要進一步檢測或治療;

真陰性:就診者未患病,模型檢測爲陰性,認爲患者健康,可以直接回家;

假陽性:就診者未患病,模型檢測爲陽性,認爲患病需要進一步檢測或治療;
注意此情況屬於誤診,進一步檢測會浪費醫療資源,但是可確保病人得到醫治;

假陰性:就診者患病,模型檢測爲陰性,認爲患者健康,可以直接回家;此情況屬於誤診,並且會讓患者失去治療機會;

類型1和類型2錯誤

有時在一些文檔中,你會看到把假陽性和假陰性稱爲類型1和類型2錯誤。這是定義:

類型1錯誤(第一類錯誤或假陽性):在醫學診斷例子中,這是我們誤診一個健康人爲病人

類型2錯誤(第二類錯誤或假陰性):在醫學診斷例子中,這是我們漏診一個病人爲健康人

畫成矩陣圖如下:

t001

而對於垃圾郵件分類模型:

t003

3.分類模型評估

3.1 準確率(accuracy)

評估模型效果的第一個指標,是準確率
accuracy=## accuracy = \frac{\#正確分類數量}{\#總分類數量}

比如上述醫療模型:

t004

垃圾郵件分類模型:

t005

用sklearn庫的模型可方便計算:

from sklearn.metrics import accuracy_score

accuracy_score(y_true, y_pred)

準確率不適用的情形

假設一個檢測信用卡欺詐模型,有大量真實交易數據,

有284335筆正常交易,472筆欺詐交易,現在嘗試設計一個準確率超過99%的模型。

假設所有交易都是正常的,其準確率:

t006

這個模型準確率非常高,但實際上沒有檢測出一例欺詐交易。而模型設計主要目標就是檢測出欺詐交易。

所以,不同類別的樣本比例非常不均衡時,佔比大的類別往往稱爲影響準確率的最主要因素

對於以上誤檢的兩種情況,假陽性和假陰性,哪種更糟糕呢:

醫療模型:

假陽性,即將健康人誤診爲病人,進一步檢測或治療,會浪費醫療資源;

假陰性,將病人誤診爲健康,這讓病人直接回家,錯過了治療機會;

這個模型的目標是找到所有病人,可以容忍部分將健康人誤診爲病人。相比,假陰性更嚴重。

垃圾郵件分類模型:

假陽性,將正常郵件誤檢爲垃圾郵件,會漏過一些重要郵件;

假陰性,即垃圾郵件誤檢爲正常郵件,這會浪費一定資源;

這個模型的目標是,刪除掉垃圾郵件,但是不能容忍誤刪,假陰性只會浪費點時間,但假陽性可能會錯過很重要郵件。

相比,假陽性更嚴重。

從醫療模型和垃圾郵件分類模型,可以看到不同模型,設計目標不同,對誤檢的容忍也不一樣。

3.2 精確率和召回率

精確率定義:

=##(#+#) 精確率 = \frac{\#真陽性}{\#所有檢測陽性樣本(\#真陽性+\#假陽性)}

按以上定義,醫療模型準確率:

t100

垃圾郵件檢測模型:

t101

對於醫療模型,我們可以忽略假陰性,追求更高的精度:

召回率定義:

=##(#+#) 召回率 = \frac{\#真陽性}{\#所有實際陽性樣本(\#真陽性 + \#假陰性)}

按以上定義,醫療模型召回率:

t102

垃圾郵件檢測模型:

t103

醫療模型,要儘量排除假陰性,需要更高的召回率,儘可能多的檢測出所有病人。

垃圾郵件模型,更在意的是避免假陽性,即刪除正常的郵件,需要更高的精確率。

3.3 F1得分

綜合精確率和召回率,統一成一個指標來表述模型效率,精確率的和召回率的調和平均值

t104

也叫F1 scroe

F1Score=2PrecisionRecallPrecision+RecallF1_{Score}=2⋅ \frac{Precision*Recall}{Precision+Recall}

調和平均值,總是處於Precision,Recall之間,偏向較小值,

t105

3.4 F-Beta得分

F1分數是將精確率和召回率取相同權重,假如需求要偏向某一方,精確率或召回率,可以用F-Beta得分

Fβ=(1+β2)PrecisionRecallβ2Precision+RecallF_{\beta}=(1+\beta^2)⋅ \frac{Precision*Recall}{\beta^2*Precision+Recall}

t106

F-β 得分的界限

β\beta越小,越偏重於精確率,反之偏向召回率,β\beta=1, 權重相同,也就是F1 分數。

β\beta=0
F0=(1+02)PrecisionRecall0Precision+Recall=PrecisionRecallRecall=Precision F_0=(1+0 ^2)⋅\frac{Precision⋅Recall}{0⋅Precision+Recall} = \frac{Precision⋅Recall}{Recall}=Precision

如果β\beta非常大,
Fβ=(1+β2)PrecisionRecallβ2Precision+RecallF_{\beta}=(1+\beta^2)⋅ \frac{Precision*Recall}{\beta^2*Precision+Recall}

Fβ=PrecisionRecallβ2(1+β2)Precision+Recall(1+β2) F_{\beta}=\frac{Precision*Recall}{\frac{\beta^2}{(1+\beta^2)}*Precision+\frac{Recall}{(1+\beta^2)}}

隨着β\beta變成無窮大,可以看出$ \frac{1}{1+\beta^2}$ 變成 0,並且 β21+β2\frac{\beta^2}{1+\beta^2} 變成1.

取極限,
limβFβ=PrecisionRecall1Precision+0Recall=Recall lim_{\beta→∞}F_{\beta}= \frac{Precision⋅Recall}{1⋅Precision+0⋅Recall}=Recall

因此,測出結論:β\beta界限是0和∞之間。

如果β=0\beta=0,得到精確率;

如果β=\beta=∞,得出召回率;

如果β=1\beta=1,則得出精確率和召回率的調和平均值。

3.5 ROC曲線

受試者工作特性曲線(receiver operating characteristic),簡稱ROC曲線。

ROC曲線的橫座標爲假陽性率(False Positive Rate, FPR);縱軸爲真陽性率(True Positive Rate, TPR),FPR和TPR的計算方法爲

FPR=FPN FPR = \frac{FP}{N}

TPR=TPP TPR = \frac{TP}{P}

上式中,P是真實正樣本數量,N是真實負樣本數量,TP是P個樣本中分類器預測正樣本數量,FP是N個負樣本中,分類器預測爲負樣本個數。

如何繪製ROC曲線

通過不斷移動分類器的"截斷點"來生成曲線上的一組關鍵點。

所謂截斷點,就是設置一個閾值,每個樣本預測爲陽性的概率,超過這個閾值,即判爲陽性,否則爲陰性。

每個截斷點,求相對應的FPR和TPR,以FPR爲橫軸,TPR爲縱軸,描出所有點,連成曲線。

如何計算AUC

AUC就是ROC曲線下的面積大小,該值可以量化的反映基於ROC曲線衡量出的模型性能。計算AUC,沿着橫軸求ROC曲線積分即可。

AUC越大,說明分類器可能把真正的正陽本排在前面,分類性能越好。

t200

AUC一般在0.5~1之間,如果小於0.5,只要把模型預測的概率反轉成1-p就可以得到一個更好的分類器。

ROC曲線相比P-R曲線有什麼特點

P-R曲線,是以召回率爲橫軸,精確率爲縱軸的曲線。

當正負樣本比例出現較大改變時,P-R曲線變化較大,而ROC曲線形狀基本不變。

t201.png(圖片在手機,後面補上)

這個特點讓ROC曲線能夠儘量降低不同測試集帶來的干擾,更加客觀地衡量模型本身的性能。

繪製roc代碼實現

def build_roc_auc(model, X_train, X_test, y_train, y_test):
    '''
    INPUT:
    model - an sklearn instantiated model
    X_train - the training data
    y_train - the training response values (must be categorical)
    X_test - the test data
    y_test - the test response values (must be categorical)
    OUTPUT:
    auc - returns auc as a float
    prints the roc curve
    '''
    import numpy as np
    import matplotlib.pyplot as plt
    from itertools import cycle
    from sklearn.metrics import roc_curve, auc, roc_auc_score
    from scipy import interp
    
    y_preds = model.fit(X_train, y_train).predict_proba(X_test)
    # Compute ROC curve and ROC area for each class
    fpr = dict()
    tpr = dict()
    roc_auc = dict()
    for i in range(len(y_test)):
        fpr[i], tpr[i], _ = roc_curve(y_test, y_preds[:, 1])
        roc_auc[i] = auc(fpr[i], tpr[i])

    # Compute micro-average ROC curve and ROC area
    fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_preds[:, 1].ravel())
    roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
    
    plt.plot(fpr[2], tpr[2], color='darkorange',
             lw=2, label='ROC curve (area = %0.2f)' % roc_auc[2])
    plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver operating characteristic example')
    plt.show()
    
    return roc_auc_score(y_test, np.round(y_preds[:, 1]))
    
    
# Finding roc and auc for the random forest model    
build_roc_auc(rf_mod, training_data, testing_data, y_train, y_test) 

4 迴歸模型評估

4.1平均絕對誤差

就是將樣本點到直線的距離絕對值的和;
t300

平均絕對誤差有個問題,絕對值函數是不可微分的,這不利於使用如梯度下降等方法。

爲解決這個問題,一般用均方誤差。

4.2均方誤差

在sklearn也很容易實現
t301

4.3 R2分數

通過將模型與最簡單的可能模型相比得出

t303

在sklearn的實現:

t304

5 小結

訓練和測試數據

首先, 每次都要把你的數據劃分爲訓練集和測試集,這很重要。先把模型在訓練集數據上擬合好,然後你就可以用測試集數據來評估模型性能。

評估分類

如果你正在訓練模型來預測分類(是否是垃圾郵件),比起預測具體數值(例如房價),有很多不同的評估方法來評估你的模型的性能。

當我們看分類指標時,這個主題的維基百科頁面非常精彩,但也有點難度。我經常用它來記憶各個指標做什麼。

具體來說,你看到了如何計算:

準確度

準確度通常用來比較模型,因爲它告訴我們正確分類的比例。

t500

通常準確度不應是你要優化的唯一指標。尤其是當你的數據存在類別不平衡情況時,只優化準確度可能會誤導你對模型真實性能的評估。考慮到這一點,我們介紹了一些其他指標。

精度

精度主要關注的是數據集中預測 爲“陽性”的數據。通過基於精度的優化,你將能確定與誤報假陽性相比,你是否在預測正例的工作上做的很好(減少誤報假陽性)。

t501

召回率

召回率主要關注數據集中的實際 “陽性”的數據。通過基於召回率的優化,你將能確定你是否在預測正例的工作上做的很好(減少漏報假陰性),而不必太考慮誤報假陽性。如果你想在實際 ‘負例’上執行類似召回率的計算,這叫做特異性(specificity)。

t503

F-Beta 分數

爲同時考察兩個指標(精度和召回率)的組合,有一些常用技術,如 F-Beta 分數(其中經常使用 F1 分數),以及 ROC 和 AUC。你可以看到 \betaβ 參數控制了精度在 F 分數中的權重,它允許同時考慮精度和召回率。最常見的 beta 值是1, 因爲這是精度和召回率的調和平均

t502

ROC 曲線 和 AUC

通過爲我們的分類指標設置不同的閾值,我們可以測量曲線下的面積(曲線稱爲 ROC 曲線)。與上面的其他指標類似,當 AUC 比較高(接近1)時,這表明我們的模型比指標接近 0 時要好。

t503

你可能最終會選擇基於這些指標中的任何一項進行優化。在實踐,我通常中使用 AUC 或 F1 分數。然而,要根據你的具體情況來選擇評估方法。

評估迴歸

你想評估你的模型在預測數值時的性能嗎?這種情況下,有三個常用的主要指標:平均絕對誤差,均方誤差,和 r2 值。

一個重要的注意事項:與優化均方誤差相比,優化平均絕對誤差可能會導致不同的“最優模型”。然而,與優化 R2 值相同,優化均方誤差將總是導致相同的“最優”模型。

同樣,如果你選擇具有最佳 R2 分數(最高)的模型,它也將是具有最低均方誤差(MSE)的模型。具體選擇哪個,要根據你覺的在給別人解釋時,哪個最方便。

平均絕對誤差 (MAE)

你看到的第一個指標是平均絕對誤差。當你要預測的數據遵循偏斜分佈時,這是一個很有用的指標。在這些情況下,對絕對值做優化特別有用,因爲與使用均方誤差一樣,異常值不會對試圖優化這個指標的模型有影響。這個技術的最佳值是中位值。當優化均方誤差的 R2 分數時,最佳值實際上是平均數。

t506

均方誤差 (MSE)

均方誤差是迴歸問題中最常用的優化指標。與 MAE 類似,你希望找到一個最小化此值的模型。這個指標可能會受到偏斜分佈和異常值的極大影響。當一個模型考慮用 MAE 而不是 MSE 做優化時,記住這一點很有用。在很多情況下,在 MSE 上進行優化更容易,因爲二次項可微。而絕對值是不可微的。這一因素使得該指標 (MSE) 更適合用於基於梯度的優化算法。

t507

R2 分數

最後,在查看回歸值時,R2 分數是另一個常用指標。優化一個模型,最小化 MSE 也將導致最高的 R2 分數。這是這個指標的一個方便特性。R2 分數通常被解釋爲模型捕獲的“變化量”。因此,你可以把 MSE 看作是所有點的平均值,而把 R2 分數看作是用模型捕獲的所有點的變化量。

t508

看待機器學習問題,類似與解決機器故障,需要一系列檢修工具,也需要一系列評估工具,經過評估選擇最適合的工具,修好故障車;

t600

對應到機器學習問題,檢修工具是各類算法比如邏輯迴歸,決策樹,神經網絡,隨機森林等,

評估工具對應模型複雜度、準確率、精確率、召回率、F1分數、學習曲線等。

我們要做的是,用這些指標來測試自己設計的模型,根據表現,選擇最優的模型來擬合數據;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章