計算交叉驗證的指標
使用交叉驗證最簡單的方法是在估計器和數據集上調用 cross_val_score
輔助函數。
下面的示例展示了如何通過分割數據,擬合模型和計算連續 5 次的分數(每次不同分割)來估計 linear kernel 支持向量機在 iris 數據集上的精度:
>>> from sklearn.model_selection import cross_val_score >>> clf = svm.SVC(kernel='linear', C=1) >>> scores = cross_val_score(clf, iris.data, iris.target, cv=5) >>> scores array([0.96..., 1. ..., 0.96..., 0.96..., 1. ])
評分估計的平均得分和 95% 置信區間由此給出:
>>> print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2)) Accuracy: 0.98 (+/- 0.03)
默認情況下,每個 CV 迭代計算的分數是估計器的 score
方法。可以通過使用 scoring 參數來改變計算方式如下:
>>> from sklearn import metrics >>> scores = cross_val_score( ... clf, iris.data, iris.target, cv=5, scoring='f1_macro') >>> scores array([0.96..., 1. ..., 0.96..., 0.96..., 1. ])
詳情請參閱 scoring 參數: 定義模型評估規則 。 在 Iris 數據集的情形下,樣本在各個目標類別之間是平衡的,因此准確度和 F1-score 幾乎相等。
當 cv
參數是一個整數時, cross_val_score
默認使用 KFold
或 StratifiedKFold
策略,后者會在估計器派生自 ClassifierMixin
時使用。
也可以通過傳入一個交叉驗證迭代器來使用其他交叉驗證策略,比如:
>>> from sklearn.model_selection import ShuffleSplit >>> n_samples = iris.data.shape[0] >>> cv = ShuffleSplit(n_splits=5, test_size=0.3, random_state=0) >>> cross_val_score(clf, iris.data, iris.target, cv=cv) array([0.977..., 0.977..., 1. ..., 0.955..., 1. ])
另外一種可選方案是使用一個可迭代生成器作為索引數組產生(train, test) 划分,比如:
>>> def custom_cv_2folds(X): ... n = X.shape[0] ... i = 1 ... while i <= 2: ... idx = np.arange(n * (i - 1) / 2, n * i / 2, dtype=int) ... yield idx, idx ... i += 1 ... >>> custom_cv = custom_cv_2folds(iris.data) >>> cross_val_score(clf, iris.data, iris.target, cv=custom_cv) array([1. , 0.973...])
保留數據的數據轉換
正如在訓練集中保留的數據上測試一個 predictor (預測器)是很重要的一樣,預處理(如標准化,特征選擇等)和
類似的 data transformations 也應該從訓練集中學習,並應用於預測數據以進行預測:
>> from sklearn import preprocessing >> X_train, X_test, y_train, y_test = train_test_split( ... iris.data, iris.target, test_size=0.4, random_state=0) >> scaler = preprocessing.StandardScaler().fit(X_train) >> X_train_transformed = scaler.transform(X_train) >> clf = svm.SVC(C=1).fit(X_train_transformed, y_train) >> X_test_transformed = scaler.transform(X_test) >> clf.score(X_test_transformed, y_test) 0.9333...
Pipeline
可以更容易地組合估計器,在交叉驗證下使用如下:
>> from sklearn.pipeline import make_pipeline >> clf = make_pipeline(preprocessing.StandardScaler(), svm.SVC(C=1)) >> cross_val_score(clf, iris.data, iris.target, cv=cv) ... array([ 0.97..., 0.93..., 0.95...])
1. cross_validate 函數和多度量評估
cross_validate
函數與 cross_val_score
在下面的兩個方面有些不同 -
- 它允許指定多個指標進行評估.
- 除了測試得分之外,它還會返回一個包含訓練得分,擬合次數, score-times (得分次數)的一個字典。 It returns a dict containing training scores, fit-times and score-times in addition to the test score.
對於單個度量評估,其中 scoring 參數是一個字符串,可以調用或 None , keys 將是 - ['test_score', 'fit_time', 'score_time']
而對於多度量評估,返回值是一個帶有以下的 keys 的字典 - ['test_<scorer1_name>', 'test_<scorer2_name>', 'test_<scorer...>', 'fit_time', 'score_time']
return_train_score
默認設置為 True
。 它增加了所有 scorers(得分器) 的訓練得分 keys 。如果不需要訓練 scores ,則應將其明確設置為 False
。
你還可以通過設置return_estimator=True
來保留在所有訓練集上擬合好的估計器。
可以將多個測度指標指定為list,tuple或者是預定義評分器(predefined scorer)的名字的集合
>>> from sklearn.model_selection import cross_validate >>> from sklearn.metrics import recall_score >>> scoring = ['precision_macro', 'recall_macro'] >>> clf = svm.SVC(kernel='linear', C=1, random_state=0) >>> scores = cross_validate(clf, iris.data, iris.target, scoring=scoring, ... cv=5) >>> sorted(scores.keys()) ['fit_time', 'score_time', 'test_precision_macro', 'test_recall_macro'] >>> scores['test_recall_macro'] array([0.96..., 1. ..., 0.96..., 0.96..., 1. ])
或作為一個字典 mapping 得分器名稱預定義或自定義的得分函數:
>>> from sklearn.metrics.scorer import make_scorer >>> scoring = {'prec_macro': 'precision_macro', ... 'rec_macro': make_scorer(recall_score, average='macro')} >>> scores = cross_validate(clf, iris.data, iris.target, scoring=scoring, ... cv=5, return_train_score=True) >>> sorted(scores.keys()) ['fit_time', 'score_time', 'test_prec_macro', 'test_rec_macro', 'train_prec_macro', 'train_rec_macro'] >>> scores['train_rec_macro'] array([0.97..., 0.97..., 0.99..., 0.98..., 0.98...])
這里是一個使用單一指標的 cross_validate
的示例:
>>> scores = cross_validate(clf, iris.data, iris.target, ... scoring='precision_macro', cv=5, ... return_estimator=True) >>> sorted(scores.keys()) ['estimator', 'fit_time', 'score_time', 'test_score']
2. 通過交叉驗證獲取預測
除了返回結果不同,函數 cross_val_predict
具有和 cross_val_score
相同的接口, 對於每一個輸入的元素,如果其在測試集合中,將會得到預測結果。交叉驗證策略會將可用的元素提交到測試集合有且僅有一次(否則會拋出一個異常)。
警告 :交叉預測可能使用不當
cross_val_predict
函數的結果可能會與cross_val_score
函數的結果不一樣,因為在這兩種方法中元素的分組方式不一樣。函數cross_val_score
在所有交叉驗證的折子上取平均。但是,函數cross_val_predict
只是簡單的返回由若干不同模型預測出的標簽或概率。因此,cross_val_predict
不是一種適當的泛化錯誤的度量。
函數cross_val_predict
比較適合做下列事兒:
- 從不同模型獲得的預測結果的可視化。
- 模型混合: 在集成方法中,當一個有監督估計量的預測被用來訓練另一個估計量時
可用的交叉驗證迭代器在下面的章節將提到。
示例
- Receiver Operating Characteristic (ROC) with cross validation,
- Recursive feature elimination with cross-validation,
- Parameter estimation using grid search with cross-validation,
- Sample pipeline for text feature extraction and evaluation,
- 繪制交叉驗證預測圖,
- Nested versus non-nested cross-validation.