交叉驗證是用來評估機器學習方法的有效性的統計學方法,可以使用有限的樣本數量來評估模型對於驗證集或測試集數據的效果。
k折交叉驗證
參數表示,將給定的樣本數據分割成組。時,稱爲10折交叉驗證。
流程如下:
- 將數據集隨機打亂。Shuffle the dataset randomly.
- 將數據集隨機分割爲組。
- 對於每一個組,進行如下操作:
- 將這一個組的數據當做測試集
- 剩餘的個組的數據當做訓練集
- 使用測試集訓練模型,並在測試集上進行評測
- 保留評測的分數,拋棄模型
- 使用次評測分數的平均值來總結模型的性能,有時也會統計次評測分數的方差。
總結:每一個樣本都做了一次測試集,做了次訓練集。
k值的確定
值必須仔細確定。不合適的值會導致不能準確評估模型的性能,會得出high variance或high bias的結果。There is a bias-variance trade-off associated with the choice of k in k-fold cross-validation
選擇值的幾點策略:
- 數據的代表性:值必須使得每一組訓練集和測試集中的樣本數量都足夠大,使其在統計學意義上可以代表更廣泛的數據。
- :這是一個經過廣泛的實驗得到的一個經驗值。所得的結果會有較低的偏差和適量的方差 (low bias and modest variance)
- :其中是樣本的數量。這樣一來,使得一個樣本作爲測試集,其他樣本作爲訓練集。因此也被稱作 leave-one-out 交叉驗證 (LOOCV)。
總結:沒有固定值,不過通常取值5或10。隨着值的增大,訓練集的大小和採樣子集之間的差異變小,對模型評估的偏差也會減小。總是一個較優的選擇。
實例
給定一個樣本數據集如下:
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
選定,則樣本分爲3組,每組2個數據。
Fold1: [0.5, 0.2]
Fold2: [0.1, 0.3]
Fold3: [0.4, 0.6]
接下來訓練三個模型,並使用對應的測試集進行評測。
Model1: Trained on Fold1 + Fold2, Tested on Fold3
Model2: Trained on Fold2 + Fold3, Tested on Fold1
Model3: Trained on Fold1 + Fold3, Tested on Fold2
使用scikit-learn進行交叉驗證
使用KFold類:
kfold = KFold(3, True, 1)
其中:3表示,True表示隨機打亂數據集,1是隨機數的種子seed。
接下來使用split函數將樣本進行分組:
# enumerate splits
for train, test in kfold.split(data):
print('train: %s, test: %s' % (data[train], data[test]))
其中的train和test都是原始數據在data數組中的索引值。
完整的代碼如下:
# scikit-learn k-fold cross-validation
from numpy import array
from sklearn.model_selection import KFold
# data sample
data = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
# prepare cross validation
kfold = KFold(3, True, 1)
# enumerate splits
for train, test in kfold.split(data):
print('train: %s, test: %s' % (data[train], data[test]))
輸出結果爲:
# enumerate splits
train: [0.1 0.4 0.5 0.6], test: [0.2 0.3]
train: [0.2 0.3 0.4 0.6], test: [0.1 0.5]
train: [0.1 0.2 0.3 0.5], test: [0.4 0.6]
參考鏈接:
https://machinelearningmastery.com/k-fold-cross-validation/