データセットをトレーニングセットとテストセットに分割することは、機械学習モデルをトレーニングできるようにするための必須かつ基本的なタスクです。
モデルがオーバーフィットしているかどうかを判断するには、未知のデータ(バリデーションセット)でテストする必要がある。
もし、あるモデルが検証セットでうまくいかないと、実際のデータを扱ったときにパフォーマンスが悪くなります。
このような考え方から、クロスバリデーションは機械学習において最も重要な概念の1つであり、モデルの安定性を保証するものです。
クロスバリデーションとは、データセットから一部のデータを予約し、それをモデルのテストに使い(バリデーションセット)、予約したデータ以外の残りのデータをモデルの学習に使うという方法です。
今回は、sci-kit learnで提供されているクロスバリデーションを実装してみます。
K-Fold Cross-validationを実装してみます。
この記事もチェック:Pythonとsklearnを使って機械学習パイプラインを実装する方法
クロスバリデーションの直感
まず、なぜクロスバリデーションを使わなければならないかを見てみましょう。
- モデルの品質を最終的に決定するモデル評価に役立ちます。
- モデルがデータに対してうまく汎化しているかどうかを判断するのに重要です。
- モデルがオーバーフィットしているかアンダーフィットしているかを確認するため。
- 最後に、最も性能の良いモデルを選択することができます。
クロスバリデーションには多くの種類がある。
- 1つを除外するクロスバリデーション
- k-フォールドクロスバリデーション
- 層化kフォールドクロスバリデーショ ン
- 時系列クロスバリデーション
K-Fold クロスバリデーションの実装
データセットは「k」個のサブセットに分割され、k-1個のサブセットはモデルの学習に使用され、最後のサブセットはモデルをテストするための検証セットとして保持される。
そして、それぞれのフォールドにおけるモデルのスコアが平均化され、モデルの性能が評価される。
#Importing required libraries from sklearn.datasets import load_breast_cancer
import pandas as pd
from sklearn.model_selection import KFold
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
#Loading the dataset data = load_breast_cancer(as_frame = True )
df = data.frame
X = df.iloc[:,: - 1 ]
y = df.iloc[:, - 1 ]
#Implementing cross validation k = 5
kf = KFold(n_splits = k, random_state = None )
model = LogisticRegression(solver = 'liblinear' )
acc_score = []
for train_index , test_index in kf.split(X):
X_train , X_test = X.iloc[train_index,:],X.iloc[test_index,:]
y_train , y_test = y[train_index] , y[test_index]
model.fit(X_train,y_train)
pred_values = model.predict(X_test)
acc = accuracy_score(pred_values , y_test)
acc_score.append(acc)
avg_acc_score = sum (acc_score) / k
print ( 'accuracy of each fold - {}' . format (acc_score))
print ( 'Avg accuracy : {}' . format (avg_acc_score))
|
scikit learnを用いたK-foldクロスバリデーション
accuracy of each fold - [0.9122807017543859, 0.9473684210526315, 0.9736842105263158, 0.9736842105263158, 0.9557522123893806] Avg accuracy : 0.952553951249806 |
from sklearn.datasets import load_breast_cancer
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
data = load_breast_cancer(as_frame = True )
df = data.frame
X = df.iloc[:,: - 1 ]
y = df.iloc[:, - 1 ]
k = 5
kf = model_selection.KFold(n_splits = k, random_state = None )
model = LogisticRegression(solver = 'liblinear' )
result = cross_val_score(model , X, y, cv = kf)
print ( "Avg accuracy: {}" . format (result.mean()))
|
上記のコードでは、5倍のクロスバリデーションを実装しています。
sklearn.model_selectionモジュールはKFoldクラスを提供し、クロスバリデーションの実装を容易にします。
KFoldクラスには split
メソッドがあり、入力引数としてクロスバリデーションを行うデータセットが必要です。
我々は、モデルとしてロジスティック回帰を用いた二値分類を行い、5-Foldクロスバリデーションを用いてクロスバリデーションを行った。
モデルの平均精度は約95.25%でした。
Sklearn KFoldのドキュメントはこちらでご確認ください。
この記事もチェック:Pythonとsklearnによる電子メールスパム分類の実装を自作する方法
Cross Validation Using cross_val∕score()
上記のコードは sklearn.model_selection
モジュールの cross_val_score
クラスメソッドを使って短縮することができます。
Avg accuracy: 0.952553951249806 |
どちらのコードも結果は同じです。
cross_val_score` クラスは Model, Dataset, Labels, cross-validation method を入力引数として必要とします。
ここまでで、クロスバリデーションについてご理解いただけたかと思います。
クロスバリデーションの実用上の重要な意味は、モデルの学習とテストを異なるフォールドのデータでk回行うため、より多くの計算機資源が必要になることを意味します。
まとめ
この記事では、クロスバリデーションとその動作の背後にあるいくつかの直感を得ようとしました。
最もよく使われる K-Fold クロスバリデーションを sklearn を使って実装してみました。