交叉驗證的原理放在后面,先看函數。
設X是一個9*3的矩陣,即9個樣本,3個特征,y是一個9維列向量,即9個標簽。現在我要進行3折交叉驗證。
執行kFold = KFold(n_splits=3) :其中KFold是一個類,n_split=3表示,當執行KFold的split函數后,數據集被分成三份,兩份訓練集和一份驗證集。
執行index = kFold.split(X=X):index是一個生成器,每個元素是一個元組,元組里面有兩個元素,第一個是訓練集的索引,第二個是驗證集的索引。因為這里將9個樣本分成三份,所以index中有三個這樣的元組
之后便可以迭代index來獲得訓練集和驗證集的索引,從而獲得訓練集和測試集了
下面是代碼示例
1 import numpy as np 2 from sklearn.model_selection import KFold 3 4 a = np.arange(27).reshape(9, 3) 5 print(a) 6 b = np.arange(9).reshape(9, 1) 7 kfold = KFold(n_splits=3, shuffle=True) 8 index = kfold.split(X=a) 9 print(list(index)) 10 print(type(index)) 11 index = kfold.split(X=a, y=b) 12 for train_index, test_index in index: 13 print("-------------------------------------------------") 14 print(a[train_index]) #注意如果a是datafram類型就得用a.iloc[tain_index], 因為a[train_index]會被認為是訪問列 15 print(a[test_index])
運行結果如下:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
[12 13 14]
[15 16 17]
[18 19 20]
[21 22 23]
[24 25 26]]
[(array([0, 1, 3, 4, 5, 6]), array([2, 7, 8])), (array([1, 2, 3, 4, 7, 8]), array([0, 5, 6])), (array([0, 2, 5, 6, 7, 8]), array([1, 3, 4]))]
<class 'generator'>
-------------------------------------------------
[[ 6 7 8]
[ 9 10 11]
[12 13 14]
[18 19 20]
[21 22 23]
[24 25 26]]
[[ 0 1 2]
[ 3 4 5]
[15 16 17]]
-------------------------------------------------
[[ 0 1 2]
[ 3 4 5]
[ 9 10 11]
[15 16 17]
[21 22 23]
[24 25 26]]
[[ 6 7 8]
[12 13 14]
[18 19 20]]
-------------------------------------------------
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[12 13 14]
[15 16 17]
[18 19 20]]
[[ 9 10 11]
[21 22 23]
[24 25 26]]
Process finished with exit code 0
原理補充:
在機器學習建模過程中,通行的做法通常是將數據分為訓練集和測試集。測試集是與訓練獨立的數據,完全不參與訓練,用於最終模型的評估。在訓練過程中,經常會出現過擬合的問題,就是模型可以很好的匹配訓練數據,卻不能很好在預測訓練集外的數據。如果此時就使用測試數據來調整模型參數,就相當於在訓練時已知部分測試數據的信息,會影響最終評估結果的准確性。通常的做法是在訓練數據再中分出一部分做為驗證(Validation)數據,用來評估模型的訓練效果。
驗證數據取自訓練數據,但不參與訓練,這樣可以相對客觀的評估模型對於訓練集之外數據的匹配程度。模型在驗證數據中的評估常用的是交叉驗證,又稱循環驗證。它將原始數據分成K組(K-Fold),將每個子集數據分別做一次驗證集,其余的K-1組子集數據作為訓練集,這樣會得到K個模型。這K個模型分別在驗證集中評估結果,最后的誤差MSE(Mean Squared Error)加和平均就得到交叉驗證誤差。交叉驗證有效利用了有限的數據,並且評估結果能夠盡可能接近模型在測試集上的表現,可以做為模型優化的指標使用。