1. 程式人生 > >機器學習:模型性能評估與參數調優

機器學習:模型性能評估與參數調優

rom 集中 進行 groups 然而 val k-fold 證明 strong

模型性能評估的常用指標

真陽性(True Positive,TP):指被分類器正確分類的正例數據

真陰性(True Negative,TN):指被分類器正確分類的負例數據

假陽性(False Positive,FP):被錯誤地標記為正例數據的負例數據

假陰性(False Negative,FN):被錯誤地標記為負例數據的正例數據

精確率=TP/(TP+FP),TP+FP是模型預測的正樣本總數,精確率衡量的是準確性;

召回率=TP/(TP+FN),TP+FN是真實的正樣本總數,召回率衡量的是覆蓋率;

F1=(2*精確率*召回率)/(精確率+召回率),F1值是精確率和召回率的綜合評估

ROC曲線是常用的二分類場景的模型評估算法曲線

曲線的橫軸是FP值,縱軸是TP值

曲線越接近於左上角就說明模型的效果越好

ROC更多是通過曲線的光滑程度以及曲線的斜率來獲取模型內的信息

AUC值表示ROC曲線與橫軸圍起來的面積

AUC值越大表示模型的效果越好,AUC介於0到1之間,通常大於0.5;若大於0.9則證明模型性能不錯

使用k折交叉驗證評估模型性能

1. holdout交叉驗證

方法:將原始數據隨機分為訓練集、驗證集兩部分,利用訓練集訓練分類器,然後利用驗證集驗證分類器性能

優點:處理簡單,只需隨機把原始數據分為兩組即可

缺點:

1)驗證集分類準確率對原始數據的劃分方法是敏感的,模型及參數缺乏魯棒性。

2)該方法只用了部分數據進行模型的訓練,無法充分利用完整樣本的數據,易出現欠擬合的情況。

2. k-fold交叉驗證

訓練集被不重復地劃分(均分)為k份,將每個子集分別做一次驗證集,其余的K-1組子集作為訓練集,由此得到K個模型,這K個模型的分類準確率的平均數作為此K-CV下分類器的性能指標。

優點

1)對數據劃分方法的敏感性較低,同時模型性能的評估基於k個子模型性能的均值,這使得模型性能的評估具有較小的偏差,準確性較高。

2)K-fold CV的計算成本適中

缺點: K的選取是一個Bias和Variance的trade-off。

代碼示例:

from sklearn.model_selection import KFold

X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])

y = np.array([1, 2, 3, 4])

kf = KFold(n_splits=2)

train,test=kf.split(X)

print(‘train:‘,train)

print(‘test:‘,test)

out

train: (array([2, 3]), array([0, 1]))

test: (array([0, 1]), array([2, 3]))

3. 留一交叉驗證(sklearn.model_selection.LeaveOneOutLOO

留一交叉驗證是K折交叉驗證的一個特例,此時K等於數據集樣本數N,即每次只有一個樣本用於測試,其余的N-1個樣本作為訓練集,所以LOO-CV會得到N個模型,這N個模型最終的驗證集的分類準確率的平均數作為此下LOO-CV分類器的性能指標.當數據集較小時,可用LOO-CV。

優點:

1)它不受數據劃分方法的影響,因為每一個數據都單獨的做過測試集

2)幾乎用到了所有的數據,保證了模型的bias更小

缺點:計算成本高,因為需要建立的模型數量與原始數據樣本數量相同

Stratified k-fold(分層k折交叉驗證)

在分層k折交叉驗證中,訓練集被分成k份,每一份的類別比例盡可能相等。舉例:若預測結果只有0、1兩類,那麽每一份訓練集中的預測結果為0和1的樣本數是盡可能相等的。

代碼實現:

from sklearn.model_selection import StratifiedKFold

import numpy as np

X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]])

y = np.array([0, 1, 0, 1, 0, 1])

skf = StratifiedKFold(n_splits=2,random_state=0)

train,test=skf.split(X, y)

print(‘train:‘,train)

print(‘test:‘,test)

輸出

train: (array([4, 5]), array([0, 1, 2, 3]))

test: (array([0, 1, 2, 3]), array([4, 5]))

#索引4、5對應的預測值分別為0、1(0、1各占比50%);

#索引0、1、2、3對應的預測值分別為0、1、0、1(0、1各占比50%)

from sklearn.model_selection import cross_val_score

cross_val_score(estimator, X, y=None, groups=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)

cv : 整數、交叉驗證生成器或叠代器;

取值為None時, 默認3折交叉驗證;

取值為integer時, 若模型為分類器且y為二值或多值變量時則選擇StratifiedKFold,在其他情況下為Kfold交叉驗證。

代碼示例:

>>> from sklearn import datasets, linear_model

>>> from sklearn.model_selection import cross_val_score

>>> diabetes = datasets.load_diabetes()

>>> X = diabetes.data[:150]

>>> y = diabetes.target[:150]

>>> lasso = linear_model.Lasso()

>>> print(cross_val_score(lasso, X, y))

[ 0.33150734 0.08022311 0.03531764]

數據集分割原則

交叉驗證在,原始數據集分割為訓練集與測試集,必須遵守兩個要點:

訓練集中樣本數量必須夠多,一般至少大於總樣本數的 50%。

兩組子集必須從完整集合中均勻取樣。

其中第 2 點特別重要,均勻取樣的目的是希望減少 訓練集/測試集 與完整集合之間的偏差(bias),但卻也不易做到。一般的作法是隨機取樣,當樣本數量足夠時,便可達到均勻取樣的效果。然而隨機也正是此作法的盲點,也是經常是可以在數據上做手腳的地方。舉例來說,當辨識率不理想時,便重新取樣一組訓練集 與測試集,直到測試集的辨識率滿意為止,但嚴格來說便算是作弊。

機器學習:模型性能評估與參數調優