Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ トレイン・テスト分割とクロスバリデーション | セクション
Pythonによる分類

bookトレイン・テスト分割とクロスバリデーション

メニューを表示するにはスワイプしてください

前の章では、モデルを構築し新しい値を予測しました。しかし、モデルの性能やその予測が信頼できるかどうかはまだ分かりません。

訓練データとテストデータの分割

モデルの性能を測定するためには、モデルがまだ見ていないラベル付きデータのサブセットが必要です。そのため、すべてのラベル付きデータをランダムに訓練データテストデータに分割します。

これは、train_test_split()sklearn 関数を使って実現できます。

通常、モデルは**70〜90%**をトレーニングセット、**10〜30%**をテストセットとして分割。

Note
注意

データセットに数百万のインスタンスがある場合、テストには数千件だけで十分なことが多い。このような場合、テスト用データとして10%未満を確保することも可能。

次に、トレーニングセットでモデルを学習し、テストセットでその精度を評価。

123456789101112131415161718192021
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import train_test_split df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] # Splitting the data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) knn = KNeighborsClassifier(n_neighbors=3).fit(X_train_scaled, y_train) # Printing the accuracy on the test set print(knn.score(X_test_scaled, y_test))
copy

しかし、このアプローチにはいくつかの欠点があります:

  • すべての利用可能なデータを学習に使用していないため、モデルの精度向上の機会を逃しています。
  • モデルの精度をデータのごく一部(テストセット)で評価しているため、この精度スコアは小規模なデータセットでは信頼性が低くなる可能性があります。上記のコードを複数回実行し、新しいテストセットがサンプリングされるたびに精度がどのように変化するかを観察できます。

クロスバリデーション

クロスバリデーションは、過学習の問題に対処し、モデルが未知の新しいデータに対しても適切に汎化できるように設計されています。これは、モデルにとっての教室でのトレーニングのようなものであり、本番のテストに臨む前にバランスよく学習するのに役立ちます。

この手法では、データセット全体をシャッフルし、n 等分(folds)に分割します。その後、モデルはn回のイテレーションを行います。各イテレーションでは、n-1個のフォールドを学習に、残りの1つのフォールドを検証に使用します。これにより、すべてのデータが一度は検証に使われ、モデルの性能をより信頼性高く評価できます。

なお、クロスバリデーションはテストセットの代替ではありません。クロスバリデーションでモデルの選択やチューニングを行った後は、別のテストセットで評価し、実際の運用時の性能を偏りなく確認する必要があります。

Note
注意

分割数として一般的に選ばれるのは5です。この場合、1つの分割がテストセットとして使用され、残りの4つの分割がトレーニングに使用されます。

わずかに異なるサブセットで5つのモデルを学習します。各モデルについて、テストセットの正解率を計算します:

accuracy=predicted correctlypredicted correctly+predicted incorrectly\text{accuracy} = \frac{\text{predicted correctly}}{\text{predicted correctly} + \text{predicted incorrectly}}

これが完了したら、5つの正解率の平均を計算できます。これがクロスバリデーションの正解率となります:

accuracyavg=accuracy1+accuracy2+...+accuracy55\text{accuracy}_{avg} = \frac{\text{accuracy}_1+\text{accuracy}_2+...+\text{accuracy}_5}{5}

より信頼性が高い理由は、すべてのデータを使用して精度スコアを計算しているためです(5回のイテレーションで異なる方法で分割)。

モデルの性能が分かったので、全データセットを使って再学習することができます。

幸いなことに、sklearn には 交差検証 を用いたモデル評価のための cross_val_score() 関数が用意されており、自分で実装する必要はありません。

以下は、Star Wars 評価データセットで学習した k-NN モデルに対して 交差検証 を使用する例です。

12345678910111213141516171819
from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler import pandas as pd from sklearn.model_selection import cross_val_score df = pd.read_csv('https://codefinity-content-media.s3.eu-west-1.amazonaws.com/b71ff7ac-3932-41d2-a4d8-060e24b00129/starwars_binary.csv') X = df.drop('StarWars6', axis=1) y = df['StarWars6'] scaler = StandardScaler() X = scaler.fit_transform(X) knn = KNeighborsClassifier(n_neighbors=3) # Calculating the accuracy for each split scores = cross_val_score(knn, X, y, cv=5) print('Scores: ', scores) print('Average score:', scores.mean())
copy

分類でデフォルトで使用されるスコアは正解率(accuracy)

question mark

正しい記述をすべて選択。

すべての正しい答えを選択

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 1.  6

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 1.  6
some-alt