機器學習sklearn(二十二): 模型評估(二)交叉驗證:評估估算器的表現(二)計算交叉驗證的指標


計算交叉驗證的指標

使用交叉驗證最簡單的方法是在估計器和數據集上調用 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比較適合做下列事兒:

  • 從不同模型獲得的預測結果的可視化。
  • 模型混合: 在集成方法中,當一個有監督估計量的預測被用來訓練另一個估計量時

可用的交叉驗證迭代器在下面的章節將提到。

示例

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM