交叉驗證(Cross-validation, CV)
Python code
交叉驗證在機器學習上通常是用來驗證「你設計出來模型」的好壞。
前提:
1. 數據庫(database)沒有先切割好「訓練資料(Training data)」和「測試資料(Testing data)」
或是
2. 你要從「訓練資料(Training data)」找到一組最合適參數出來,比如SVM的懲罰參數(Penalty parameter),就可以從訓練資料(Training data)做交叉驗證找出來,而不是從「測試資料(Testing data)」得到參數。
機器學習最忌諱把「測試資料(Testing data)」偷偷拿進到模型內訓練或是找參數。在做模型performance評估時,要記住一件事情「測試資料(Testing data)」絕對不能進到模型內訓練或是找參數。
PS: 但Active learning和某些semi-supervise learning方法會額外抽一些資料,但是不會跟模型說這些資料的答案(Ground Truth),出來讓模型更好。
一般在說交叉驗證通常會分成 (這邊不翻中文,因為沒聽過有人這些方法說中文的,所以也翻不出合適的)
1. Resubstitution
2. Holdout CV
3. Leave-one-out CV
4. K-fold CV
以下我會用圖例說明這些方法:
假設有一組數據,共20筆資料(兩個類別)
12筆綠色的資料{G1,G2,…,G12}
8筆淡紅色的資料{R1,R2,…,R8}
1. Resubstitution
可以稱為自我一致性評估法,是用相同的資料進行訓練和測試。這種方法會觸碰到我剛提到的機器學習最忌諱的事情,所以這個方法通常只用在從訓練資料集找參數用,執行起來會比較快,但不太會用在驗證模型的優劣。
2. Holdout CV
Holdout是指從資料集中隨機取得p%資料當作「訓練資料(Training data)」和剩下的(1-p)%當做「測試資料(Testing data)」。最後的結果(Predication results)在和測試資料的真實答案(ground truth)進行成效比對(Performance Comparison)。
Note: 這個隨機不是不考慮資料的類別,也就是說Holdout是從每一類都取p%資料當作「訓練資料(Training data)」,從每一類剩下的(1-p)%當做「測試資料(Testing data)」,如圖所示。
3. Leave-one-out CV:
每次都將每一筆資料都視為「測試資料(Testing data)」,剩下的做為「訓練資料(Training data)」,如此重複進行直到每一筆都被當做「測試資料(Testing data)」為止,如圖所示。最後的結果(Predication results)在和真實答案(ground truth)進行成效比對(Performance Comparison)。
4. K-fold CV
K-fold是比較常用的交叉驗證方法。做法是將資料隨機平均分成k個集合,然後將某一個集合當做「測試資料(Testing data)」,剩下的k-1個集合做為「訓練資料(Training data)」,如此重複進行直到每一個集合都被當做「測試資料(Testing data)」為止。最後的結果(Predication results)在和真實答案(ground truth)進行成效比對(Performance Comparison)。
Note: 這個隨機分k個集合也是要考慮資料的類別,也就是說K-fold是從每一類都隨機分割成k個集合,如圖所示。
使用心得
通常我們在用K-fold CV或是Holdout CV來驗證模型時,不會只執行一次當做最後的結果,原因是有可能再抽樣的時候沒有抽得很公平(這是有可能會發生的)。所以我們通常會重複執行n次,一般我是試100次,看這n次的performance最後的平均和標準差,最後會去report這個平均值當做模型的performance。而標準差用來表示模型的穩定程度,如果標準差太大代表模型的穩定度不夠好,在做generalized model的時候這個方法可能就不太合適。