K折交叉验证
首先要講的就是k折交叉驗證的目的(即為什么要用k折交叉驗證?)
根本原因:數據有限,單一的把數據都用來做訓練模型,容易導致過擬合。(反過來,如果數據足夠多,完全可以不使用交叉驗證。)較小的k值會導致可用于建模的數據量太小,所以小數據集的交叉驗證結果需要格外注意,建議選擇較大的k值。k一般取2-10,在樣本數量不是很多的情況下,想要檢驗擬合一個完美的模型,最常見的方法就是K折交叉檢驗。
附代碼
用鳶尾花數據來展示k折驗證效果
# 導入鳶尾花數據集 from sklearn.datasets import load_iris from sklearn.model_selection import cross_val_score # 導入用于分類的svc分類器 from sklearn.svm import SVCiris = load_iris() x, y = iris.data, iris.targetsvc = SVC(kernel='linear') # cv 為迭代次數, 這里設置為5 scores = cross_val_score(svc, x, y, cv=5) # 5次,每次的結果 print("交叉驗證得分: %.4f %.4f %.4f %.4f %.4f" % (scores[0], scores[1], scores[2], scores[3], scores[4])) # 用得分均值作為最終得分 print("res: %.4f" % (scores.mean()))-
1.K-Fold 交叉驗證概念
在機器學習建模過程中,通行的做法通常是將數據分為訓練集和測試集。測試集是與訓練獨立的數據,完全不參與訓練,用于最終模型的評估。在訓練過程中,經常會出現過擬合的問題,就是模型可以很好的匹配訓練數據,卻不能很好在預測訓練集外的數據。如果此時就使用測試數據來調整模型參數,就相當于在訓練時已知部分測試數據的信息,會影響最終評估結果的準確性。通常的做法是在訓練數據再中分出一部分做為驗證(Validation)數據,用來評估模型的訓練效果。
驗證數據取自訓練數據,但不參與訓練,這樣可以相對客觀的評估模型對于訓練集之外數據的匹配程度。模型在驗證數據中的評估常用的是交叉驗證,又稱循環驗證。它將原始數據分成K組(K-Fold),將每個子集數據分別做一次驗證集,其余的K-1組子集數據作為訓練集,這樣會得到K個模型。這K個模型分別在驗證集中評估結果,最后的誤差MSE(Mean Squared Error)加和平均就得到交叉驗證誤差。交叉驗證有效利用了有限的數據,并且評估結果能夠盡可能接近模型在測試集上的表現,可以做為模型優化的指標使用。 -
2.舉例說明
下面舉一個具體的例子來說明K-Fold的過程,比如如下的數據
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
分為K=3組后
Fold1: [0.5, 0.2]
Fold2: [0.1, 0.3]
Fold3: [0.4, 0.6]
交叉驗證的時會使用如下三個模型,分別進行訓練和測試,每個測試集誤差MSE加和平均就得到了交叉驗證的總評分
Model1: Trained on Fold1 + Fold2, Tested on Fold3
Model2: Trained on Fold2 + Fold3, Tested on Fold1
Model3: Trained on Fold1 + Fold3, Tested on Fold2 -
3.應用講解
– 1、 將全部訓練集S分成k個不相交的子集,假設S中的訓練樣例個數為m,那么每一個子集有m/k個訓練樣例,相應的子集稱作{clip_image024}。
– 2、 每次從模型集合M中拿出來一個clip_image010[3],然后在訓練子集中選擇出k-1個 -
{clip_image026}(也就是每次只留下一個clip_image028),使用這k-1個子集訓練clip_image010[4]后,得到假設函數clip_image030。最后使用剩下的一份clip_image028[1]作測試,得到經驗錯誤clip_image032。
– 3、 由于我們每次留下一個clip_image028[2](j從1到k),因此會得到k個經驗錯誤,那么對于一個clip_image010[5],它的經驗錯誤是這k個經驗錯誤的平均。
– 4、 選出平均經驗錯誤率最小的clip_image010[6],然后使用全部的S再做一次訓練,得到最后的clip_image012[4]。 -
核心內容:
通過上述1,2,3步進行模型性能的測試,取平均值作為某個模型的性能指標
根據性能指標來挑選出最優模型,再進行上述第4步重新進行訓練,獲得最終模型
- 疑問解答:
1.為什么不直接拆分訓練集與數據集,來驗證模型性能,反而采用多次劃分的形式,豈不是太麻煩了?
我們為了防止在訓練過程中,出現過擬合的問題,通行的做法通常是將數據分為訓練集和測試集。測試集是與訓練獨立的數據,完全不參與訓練,用于最終模型的評估。這樣的直接劃分會導致一個問題就是測試集不會參與訓練,這樣在小的數據集上會浪費掉這部分數據,無法使模型達到最優(數據決定了程性能上限,模型與算法會逼近這個上限)。但是我們又不能劃分測試集,因為需要驗證網絡泛化性能。采用K-Fold 多次劃分的形式就可以利用全部數據集。最后采用平均的方法合理表示模型性能。
2.為什么還要進行所有數據集重新訓練,是否太浪費時間?
我們通過K-Fold 多次劃分的形式進行訓練是為了獲取某個模型的性能指標,單一K-Fold訓練的模型無法表示總體性能,但是我們可以通過K-Fold訓練的訓練記錄下來較為優異的超參數,然后再以最優模型最優參數進行重新訓練,將會取得更優結果。
3.何時使用K-Fold
我認為,數據總量較小時,其他方法無法繼續提升性能,可以嘗試K-Fold。其他情況就不太建議了,例如數據量很大,就沒必要更多訓練數據,同時訓練成本也要擴大K倍(主要指的訓練時間)。
總結
- 上一篇: 比特大陆算法移植过程(详细)
- 下一篇: 最新 --》》如何推销自己