機器學習 - 交叉驗證
在此頁面上,W3schools.com 與 紐約資料科學學院 合作,為我們的學生提供數字培訓內容。
交叉驗證
在調整模型時,我們的目標是提高模型在未見過資料上的整體效能。超引數調優可以顯著提高在測試集上的效能。然而,對測試集進行引數最佳化可能會導致資訊洩露,從而使模型在未見過的資料上表現更差。為了糾正這一點,我們可以執行交叉驗證。
為了更好地理解 CV,我們將對鳶尾花資料集執行不同的方法。首先,讓我們載入並分離資料。
來自 sklearn 的資料集
X, y = datasets.load_iris(return_X_y=True)
有許多交叉驗證的方法,我們將從 K 折交叉驗證開始。
K 折
模型所使用的訓練資料被分割成 k 個較小的子集,用於驗證模型。然後,模型在 k-1 折的訓練集上進行訓練。剩餘的一折被用作驗證集來評估模型。
由於我們將嘗試對不同的鳶尾花品種進行分類,我們需要匯入一個分類器模型。在本練習中,我們將使用 DecisionTreeClassifier
。我們還需要從 sklearn
匯入 CV 模組。
來自 sklearn.tree 匯入 DecisionTreeClassifier
from sklearn.model_selection import KFold, cross_val_score
資料載入完畢後,我們現在可以建立一個模型並進行擬合以進行評估。
clf = DecisionTreeClassifier(random_state=42)
現在讓我們評估我們的模型,看看它在每一折上的表現如何。
k_folds = KFold(n_splits = 5)
scores = cross_val_score(clf, X, y, cv = k_folds)
透過對所有折的分數取平均值,來了解 CV 的整體表現,這是一種好的實踐。
示例
執行 K 折 CV
來自 sklearn 的資料集
來自 sklearn.tree 匯入 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("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
執行示例 »
廣告
分層 K 折
在類別不平衡的情況下,我們需要一種方法來同時考慮訓練集和驗證集中的不平衡。為此,我們可以對目標類別進行分層,這意味著每個集合都將具有所有類別的相等比例。
示例
來自 sklearn 的資料集
來自 sklearn.tree 匯入 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("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
執行示例 »
雖然折的數量相同,但在確保類別分層後,平均 CV 分數比基本的 K 折有所提高。
留一法 (LOO)
與 K 折交叉驗證選擇訓練資料集中分割的數量不同,LeaveOneOut 使用 1 個觀測值進行驗證,n-1 個觀測值進行訓練。這種方法是一種窮舉技術。
示例
執行 LOO CV
來自 sklearn 的資料集
來自 sklearn.tree 匯入 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("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
執行示例 »
我們可以看到,執行的交叉驗證分數的數量等於資料集中觀測值的數量。在這種情況下,鳶尾花資料集中有 150 個觀測值。
平均 CV 分數為 94%。
留 P 法 (LPO)
Leave-P-Out 只是 Leave-One-Out 概念的一個細微差別,即我們可以選擇 P 的數量來用於我們的驗證集。
示例
執行 LPO CV
來自 sklearn 的資料集
來自 sklearn.tree 匯入 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("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
執行示例 »
正如我們所見,這是一種窮舉方法,即使 P=2,計算出的分數也比 Leave-One-Out 多得多,但它實現了大致相同的平均 CV 分數。
Shuffle Split
與 KFold
不同,ShuffleSplit
會排除一部分資料,這些資料不會用於訓練或驗證集。為此,我們必須決定訓練集和測試集的大小,以及拆分次數。
示例
執行 Shuffle Split CV
來自 sklearn 的資料集
來自 sklearn.tree 匯入 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("Cross Validation Scores: ", scores)
print("Average CV Score: ", scores.mean())
print("Number of CV Scores used in Average: ", len(scores))
執行示例 »
結束語
這些只是可以應用於模型的一些 CV 方法。還有許多其他的交叉驗證類,大多數模型都有自己的類。請查閱 sklearn 的交叉驗證以獲取更多 CV 選項。