【scikit-learn】モデルの選択: estimatorとハイパーパラメータ-2【Python】

本ページでは以下のページを要約するとともに、個人的な解説も記載しています。独特な解釈をしている部分があるので、誤りなどの指摘は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()

以下の画像のコードはこちら