訓練機器學習模型的關鍵一步是要評估模型的泛化能力。如果我們訓練好模型后,還是用訓練集取評估模型的性能,這顯然是不符合邏輯的。一個模型如果性能不好,要么是因為模型過於復雜導致過擬合(高方差),要么是模型過於簡單導致導致欠擬合(高偏差)。可是用什么方法評價模型的性能呢?這就是這一節要解決的問題,你會學習到兩種交叉驗證計數,holdout交叉驗證和k折交叉驗證, 來評估模型的泛化能力。
holdout method
評估模型泛化能力的典型方法是holdout交叉驗證(holdout cross validation)。holdout方法很簡單,我們只需要將原始數據集分割為訓練集和測試集,前者用於訓練模型,后者用於評估模型的性能。
不過,在訓練模型這一步,我們非常關心如何選擇參數來提高模型的預測能力,而選擇參數這一步被稱為模型選擇(model selection,譯者注:不少資料將選擇何種模型算法稱為模型選擇),參數選擇是非常重要的,因為對於同一種機器學習算法,如果選擇不同的參數(超參數),模型的性能會有很大差別。
如果在模型選擇的過程中,我們始終用測試集來評價模型性能,這實際上也將測試集變相地轉為了訓練集,這時候選擇的最優模型很可能是過擬合的。
更好的holdout方法是將原始訓練集分為三部分:訓練集、驗證集和測試集。訓練機用於訓練不同的模型,驗證集用於模型選擇。而測試集由於在訓練模型和模型選擇這兩步都沒有用到,對於模型來說是未知數據,因此可以用於評估模型的泛化能力。下圖展示了holdout方法的步驟:
當然holdout方法也有明顯的缺點,它對數據分割的方式很敏感,如果原始數據集分割不當,這包括訓練集、驗證集和測試集的樣本數比例,以及分割后數據的分布情況是否和原始數據集分布情況相同等等。所以,不同的分割方式可能得到不同的最優模型參數。
下一節,我們會學習到一種魯棒性更好的模型評估方法,k折交叉沿則,即重復k次holdout方法提高魯棒性。
k折交叉驗證
k折交叉驗證的過程,第一步我們使用不重復抽樣將原始數據隨機分為k份,第二步 k-1份數據用於模型訓練,剩下那一份數據用於測試模型。然后重復第二步k次,我們就得到了k個模型和他的評估結果(譯者注:為了減小由於數據分割引入的誤差,通常k折交叉驗證要隨機使用不同的划分方法重復p次,常見的有10次10折交叉驗證)。
然后我們計算k折交叉驗證結果的平均值作為參數/模型的性能評估。使用k折交叉驗證來尋找最優參數要比holdout方法更穩定。一旦我們找到最優參數,要使用這組參數在原始數據集上訓練模型作為最終的模型。
k折交叉驗證使用不重復采樣,優點是每個樣本只會在訓練集或測試中出現一次,這樣得到的模型評估結果有更低的方法。
下圖演示了10折交叉驗證:
至於k折中的k到底設定為多少,這個又是一個調參的過程,當然了,這一步很少有人會調參,一般都是用10.但是如果你的數據集特別小,我們當然希望訓練集大一點,這時候就要設定大一點的k值,因為k越大,訓練集在整個原始訓練集的占比就越多。但是呢,k也不能太大,一則是導致訓練模型個數過多,二則是k很大的情況下,各個訓練集相差不多,導致高方差。要是你的數據集很大,那就把k設定的小一點咯,比如5.
其實呢,在將原始數據集划分為k部分的過程中,有很多不同的采樣方法,比如針對非平衡數據的分層采樣。分層采樣就是在每一份子集中都保持原始數據集的類別比例。比如原始數據集正類:負類=3:1,這個比例也要保持在各個子集中才行。sklearn中實現了分層k折交叉驗證哦:
sklearn就是這么方便,此外,更人性化的是sklearn還實現了一個直接得到交叉驗證評估結果的方法cross_val_score(內部同樣是分層k折交叉驗證):
cross_val_score方法還支持並行計算。
Note 交叉驗證是如何評估泛化能力的方差,這個問題超出了本書的范圍,如果你感興趣,可以閱讀 Analysis of Variance of Cross-validation Estimators of the Generalized Error. Journal of Machine Learning Research, 6:1127-1168, 2005
Python機器學習中文版目錄(http://www.aibbt.com/a/20787.html)
轉載請注明出處,Python機器學習(http://www.aibbt.com/a/pythonmachinelearning/)