交叉驗證
交叉驗證
在調(diào)整模型時,我們的目標(biāo)是提高模型在未見數(shù)據(jù)上的整體性能。超參數(shù)調(diào)整可以使測試集上的性能得到顯著提高。然而,針對測試集優(yōu)化參數(shù)會導(dǎo)致信息泄露,從而使模型在未見數(shù)據(jù)上的表現(xiàn)更差。為了糾正這一點,我們可以執(zhí)行交叉驗證。
為了更好地理解交叉驗證(CV),我們將在鳶尾花數(shù)據(jù)集上執(zhí)行不同的方法。首先,讓我們加載并分離數(shù)據(jù)。
from sklearn import datasets X, y = datasets.load_iris(return_X_y=True)
交叉驗證有很多方法,我們將從 k 折交叉驗證開始。
K 折
用于模型訓(xùn)練的數(shù)據(jù)被分割成 k 個較小的集合,用于驗證模型。然后,模型在 k-1 個訓(xùn)練集上進(jìn)行訓(xùn)練。剩余的折則用作驗證集來評估模型。
由于我們將嘗試對鳶尾花的不同物種進(jìn)行分類,我們需要導(dǎo)入一個分類器模型,在本練習(xí)中,我們將使用 DecisionTreeClassifier
。我們還需要從 sklearn
導(dǎo)入 CV 模塊。
from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import KFold, cross_val_score
加載數(shù)據(jù)后,我們現(xiàn)在可以創(chuàng)建并擬合一個模型進(jìn)行評估。
clf = DecisionTreeClassifier(random_state=42)
現(xiàn)在讓我們評估我們的模型,看看它在每個 k 折上的表現(xiàn)如何。
k_folds = KFold(n_splits = 5) scores = cross_val_score(clf, X, y, cv = k_folds)
查看所有折的平均得分也是一個好習(xí)慣,以了解 CV 的整體表現(xiàn)。
實例
運行 k 折 CV:
from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import KFold, cross_val_score X, y = datasets.load_iris(return_X_y=True) clf = DecisionTreeClassifier(random_state=42) k_folds = KFold(n_splits = 5) scores = cross_val_score(clf, X, y, cv = k_folds) print("交叉驗證得分:", scores) print("平均 CV 得分:", scores.mean()) print("用于平均的 CV 得分?jǐn)?shù)量:", len(scores))運行實例 ?
點擊 "運行實例" 按鈕查看在線實例
分層 K 折
在類別不平衡的情況下,我們需要在訓(xùn)練和驗證集中考慮這種不平衡。為此,我們可以對目標(biāo)類別進(jìn)行分層,這意味著兩組都將擁有所有類別的相同比例。
實例
from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import StratifiedKFold, cross_val_score X, y = datasets.load_iris(return_X_y=True) clf = DecisionTreeClassifier(random_state=42) sk_folds = StratifiedKFold(n_splits = 5) scores = cross_val_score(clf, X, y, cv = sk_folds) print("交叉驗證得分:", scores) print("平均 CV 得分:", scores.mean()) print("用于平均的 CV 得分?jǐn)?shù)量:", len(scores))運行實例 ?
點擊 "運行實例" 按鈕查看在線實例
雖然折的數(shù)量相同,但在確保分層類別時,平均 CV 得分從基本的 k 折增加。
留一法(Leave-One-Out, LOO)
與 k 折不同,留一法(LeaveOneOut
)使用 1 個觀測值進(jìn)行驗證,并使用 n-1 個觀測值進(jìn)行訓(xùn)練。這種方法是一種詳盡無遺的技術(shù)。
實例
運行 LOO CV:
from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import LeaveOneOut, cross_val_score X, y = datasets.load_iris(return_X_y=True) clf = DecisionTreeClassifier(random_state=42) loo = LeaveOneOut() scores = cross_val_score(clf, X, y, cv = loo) print("交叉驗證得分:", scores) print("平均 CV 得分:", scores.mean()) print("用于平均的 CV 得分?jǐn)?shù)量:", len(scores))運行實例 ?
點擊 "運行實例" 按鈕查看在線實例
我們可以觀察到,執(zhí)行的交叉驗證得分?jǐn)?shù)量與數(shù)據(jù)集中的觀測值數(shù)量相等。在這種情況下,鳶尾花數(shù)據(jù)集中有 150 個觀測值。
平均 CV 得分為 94%。
留 P 法(Leave-P-Out, LPO)
留 P 法有與留一法的一個細(xì)微差別,在于我們可以選擇在驗證集中使用的 p 的數(shù)量。
實例
運行 LPO CV:
from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import LeavePOut, cross_val_score X, y = datasets.load_iris(return_X_y=True) clf = DecisionTreeClassifier(random_state=42) lpo = LeavePOut(p=2) scores = cross_val_score(clf, X, y, cv = lpo) print("交叉驗證得分:", scores) print("平均 CV 得分:", scores.mean()) print("用于平均的 CV 得分?jǐn)?shù)量:", len(scores))運行實例 ?
點擊 "運行實例" 按鈕查看在線實例
正如我們所見,這是一個詳盡無遺的方法,即使 p = 2,也計算了比留一法更多的得分,但達(dá)到了大致相同的平均 CV 得分。
隨機(jī)拆分
與 KFold 不同,ShuffleSplit
留出一定百分比的數(shù)據(jù),不用于訓(xùn)練或驗證集。為此,我們必須決定訓(xùn)練和測試集的大小,以及拆分的數(shù)量。
實例
運行隨機(jī)拆分 CV:
from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import ShuffleSplit, cross_val_score X, y = datasets.load_iris(return_X_y=True) clf = DecisionTreeClassifier(random_state=42) ss = ShuffleSplit(train_size=0.6, test_size=0.3, n_splits = 5) scores = cross_val_score(clf, X, y, cv = ss) print("交叉驗證得分:", scores) print("平均 CV 得分:", scores.mean()) print("用于平均的 CV 得分?jǐn)?shù)量:", len(scores))運行實例 ?
點擊 "運行實例" 按鈕查看在線實例
結(jié)束說明
這些只是可以應(yīng)用于模型的幾種 CV 方法。還有更多交叉驗證類,大多數(shù)模型都有自己的類。請查看 sklearn
的交叉驗證以獲取更多 CV 選項。