機器學習:模型性能評估與參數調優
模型性能評估的常用指標
真陽性(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.LeaveOneOut,LOO)
留一交叉驗證是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),但卻也不易做到。一般的作法是隨機取樣,當樣本數量足夠時,便可達到均勻取樣的效果。然而隨機也正是此作法的盲點,也是經常是可以在數據上做手腳的地方。舉例來說,當辨識率不理想時,便重新取樣一組訓練集 與測試集,直到測試集的辨識率滿意為止,但嚴格來說便算是作弊。
機器學習:模型性能評估與參數調優