本ページでは以下のページを要約するとともに、個人的な解説も記載しています。独特な解釈をしている部分があるので、誤りなどの指摘はtwitterまでお願いします。
参考ページ
Model selection: choosing estimators and their parameters — scikit-learn 1.1.2 documentation
https://scikit-learn.org/stable/tutorial/statistical_inference/model_selection.html
閲覧日:2022年10月20日
交差検証
交差検証を簡単に実装できるようscikit-learnには交差検証を行うためのクラスが用意されています。
KFold(n_splits=)
にてオブジェクトを生成します。n_splits
は幾つに分割するかを設定します。
静止したオブジェクトは.split
メソッドにて分割します。
実際に実行したコードが次になります。
新たな変数を生成するのではなく、KFold
ではリストのインデックを生成します。
from sklearn.model_selection import KFold, cross_val_score
X = ["a", "a", "a", "b", "b", "c", "c", "c", "c", "c"]
k_fold = KFold(n_splits=5)
for train_indices, test_indices in k_fold.split(X):
print('Train: %s | test: %s' % (train_indices, test_indices))
#Train: [2 3 4 5 6 7 8 9] | test: [0 1]
#Train: [0 1 4 5 6 7 8 9] | test: [2 3]
#Train: [0 1 2 3 6 7 8 9] | test: [4 5]
#Train: [0 1 2 3 4 5 8 9] | test: [6 7]
#Train: [0 1 2 3 4 5 6 7] | test: [8 9]
内包表記を使用すると、以下のように容易に交差検証を実行できます。
#svc = svm.SVC(C=1, kernel='linear')
[svc.fit(X_digits[train], y_digits[train]).score(X_digits[test], y_digits[test]) for train, test in k_fold.split(X_digits)]
#[0.963..., 0.922..., 0.963..., 0.963..., 0.930...]
cross_val_score
を使用することで、データの分割、学習、それぞれのデータセットにおけるスコアの算出が一度でできます。
使用例が以下のコードです。
cross_val_score(svc, X_digits, y_digits, cv=k_fold, n_jobs=-1)
#array([0.96388889, 0.92222222, 0.9637883 , 0.9637883 , 0.93036212])
cv
は分割数で、今回はk_fold
で事前に5つに分割すると指定していました。int型でも指定できます。
n_jobs=-1
はCPUのコアを全て使用して計算することを意味します。例えば4コアのCPUであれば、最大値が4になります。
また、scoring
にて別のスコアの計算方法を指定することも可能です。
以下のコードでは適合率を採用しています。
cross_val_score(svc, X_digits, y_digits, cv=k_fold,scoring='precision_macro')
#array([0.96578289, 0.92708922, 0.96681476, 0.96362897, 0.93192644])
交差検証の際のデータ分割方法
上のコードではKFold
を使用してデータの分割を行いました。しかし、scikit-learnには他のデータの分割の方法も用意されています。
関数 | 説明 |
---|---|
KFold (n_splits, shuffle, random_state) | n_splits個にデータを等分し、テストデータを選出。 |
StratifiedKFold (n_splits, shuffle, random_state) | ラベルの比率が揃うようにテストデータを選出。 |
GroupKFold (n_splits) | 同じグループが異なるパターンに出現しないように分割 |
ShuffleSplit (n_splits, test_size, train_size, random_state) | 完全にランダムにテストデータを選出。重複する可能性あり。 |
StratifiedShuffleSplit | ランダムにクラスの割合が同じになるようにテストデータを選出。重複する可能性あり。 |
GroupShuffleSplit | 等分したグループからテストデータをランダムに選出。重複する可能性あり。 |
演習
アヤメのデータセットで、SVCで線形カーネルを使用し、交差検証のスコアを出してみましょう。
digits データセットで、SVC パラメーターの関数として線形カーネルを使用して推定量の交差検証スコアをプロットしますC(1 から 10 までの点の対数グリッドを使用します)。
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn import datasets, svm
X, y = datasets.load_digits(return_X_y=True)
svc = svm.SVC(kernel="linear")
C_s = np.logspace(-10, 0, 10)
scores = list()
scores_std = list()
以下の画像のコードはこちら。