Ccmmutty logo
Commutty IT
3 min read

クロスバリデーション: 推定値のパフォーマンスの評価

https://cdn.magicode.io/media/notebox/366ca163-9c5b-417e-b30a-fb68c68d0fca.jpeg
学習モデルの良し悪しは、予測関数のパラメーター自体を学習し、学習したものと同じデータでテストしたのでは判断することはできません。今見たサンプルのラベルを繰り返すだけのモデルは、100%正解なスコアを持ちますが、良いモデルができて、良い予測ができたとは言えません。この状況はオーバーフィッティングと呼ばれます。オーバーフィッティングを回避するために、教師あり機械学習実験を実行する場合に、利用可能なデータの一部をテストセットとして別のデータとして分けておき、利用するのが一般的な方法です。
scikit-learnでは、トレーニングセットとテストセットをtrain_test_split関数を使うことで簡単に分割することができます。ここでは、アイリスデータセットを使用して、線形回帰モデルを例に分割方法を紹介します。
python
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import svm

X, y = datasets.load_iris(return_X_y=True)
X.shape, y.shape

((150, 4), (150,))
まずは、テストデータの40%を保持しながら、トレーニングセットをすばやくサンプリングしてみます。
python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=0)

print("トレーニングデータ:",X_train.shape, y_train.shape)
print("テストデータ   :",X_test.shape, y_test.shape)

トレーニングデータ: (90, 4) (90,) テストデータ   : (60, 4) (60,)
元のデータ150からトレーニングデータが90、テストデータが60になっており、40%で分割されていることが確認できます。
この分割データを使って、SVCで評価すると0.967%で予想できました。
python
clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
clf.score(X_test, y_test)

0.9666666666666667
今の例では、データをトレーニングとテストの2つに分割しました。この分割方法にも課題はあります。ランダムに分割しているため、トレーニングとテストそれぞれにデータの中に、データの特徴を表現するような重要な情報が片方のデータセットに偏ってしまうことが考えられます。その際には、トレーニングができてもテストのデータでは十分な予測ができなかったり、その逆が起きたりするのです。
この問題を解決するために、交差検証(クロスバリデーション)と呼ばれる手法を用います。次の図のように、トレーニングデータを複数に分割(ここでは5つ)して、その中で4つをトレーニング、残りをテストデータとして使用して検証します。
このような工夫により、トレーニングデータ内に発生する可能性があったデータの偏りを減らすことができます。cross_val_scoreを用いることでデータを自動的に分割してくれます。2つのデータに分けた時は96.7%と1つのスコアが出力されましたが、今回は分割した分の5つのスコアがリストで出力されます。
python
from sklearn.model_selection import cross_val_score

clf = svm.SVC(kernel='linear', C=1, random_state=42)
scores = cross_val_score(clf, X, y, cv=5)
scores
5つの出力結果から、平均と標準偏差を計算します。
python
print("%0.2f accuracy with a standard deviation of %0.2f" % (scores.mean(), scores.std()))
結果は0.98 ± 0.02 %となり、クロスバリデーションを行なった場合の方が良いものとなりました。
交差検証の実装自体は非常に簡単にできることが分かりましたが、注意も必要です。
交差検証はデータの特性に合わせて使用する必要があります。データの順番やデータが特定のグループに別れているべきものであるのに、無理やり分割してしまっては学習が適切に行えない場合も考えられるためです。ですが、交差検証を利用することで気づくことができていなかったデータの偏りや検証方法の再点検に有効な場合もあります。
モデルの良し悪しを判断する際には、検証方法も合わせて考えてみるのも大切です。
本記事はscit-learn 1.0.2ドキュメント「3.1. Cross-validation: evaluating estimator performance」を翻訳したのち解釈・修正した記事です。
機械学習初学者にも分かりやすいように内容を変更しています。
詳細を確認したい方は、ぜひ原文を読んでみてください。
引用元: https://scikit-learn.org/stable/modules/cross_validation.html#group-k-fold

Discussion

コメントにはログインが必要です。