ウェブサイト検索

K-Foldクロスバリデーションを理解する:ステップバイステップガイド


📖 はじめに

機械学習モデルがデータについて学習すると、しばしば訓練データではうまく機能しますが、見たことのないデータやテストデータでは性能が落ちます。これはモデルの過学習として知られています。モデルの過学習は、モデルが訓練データに密着しすぎるときに発生し、アンダーフィッティングはモデルが訓練データでさえうまく機能しないときに発生します。

クロスバリデーションは、機械学習モデルが未見のデータに対しても良好に一般化されることを保証する技術の一つです。以下のように機能します:

  1. データをフォールドに分割する: 任意のデータセットは、複数のサブセットに分割され、これを「フォールド」と呼びます。
  2. トレーニングと検証のサイクル: モデルはデータのサブセットでトレーニングされ、一つのフォールドが検証に使用されます。このプロセスは繰り返され、毎回異なるフォールドが使用されます。
  3. 平均結果:各検証ステップからのパフォーマンス指標は、モデルの有効性に関するより信頼性の高い推定を提供するために平均化されます。

画像ソース

📌 前提条件

機械学習の基本知識 - モデルのトレーニング、評価指標、オーバーフィッティングの理解。
Pythonプログラミングスキル - Pythonやscikit-learn、numpy、pandasのようなライブラリに精通していること。
データセットの準備 - モデルのトレーニングのためにクリーンアップされ、前処理されたデータセット。
Scikit-Learnのインストール - まだインストールされていない場合は、pip install scikit-learnを使ってインストールする。
モデルのパフォーマンス指標の理解 - タスクに応じて、精度、適合率、再現率、RMSEなどの知識。

🚀 一般的なクロスバリデーション手法

  • K-Fold クロスバリデーション: データセットは k 個の等しい部分に分割され、モデルは k 回トレーニングされ、毎回異なるフォールドがバリデーションセットとして使用されます。
  • 層化K分割: この方法は、各フォールドが分類問題において同じ割合のクラスを維持することを保証します。ターゲット変数のデータが不均衡である場合、つまりターゲット変数がカテゴリカルな列であり、クラスが均等に分布していない場合にしばしば使用されます。
  • ローレート法(Leave-One-Out, LOO): この方法では、残りのデータで学習しながら、1つのインスタンスのみを検証に使用し、すべてのインスタンスに対して繰り返します。
  • 時系列交差検証: 逐次データに使用され、トレーニングデータが検証データに先行することを保証します。

クロスバリデーションは、最良のモデルとハイパーパラメータを選択し、過学習を防ぐのに役立ちます。

このガイドでは、次のことを探ります。

  • K-Foldクロスバリデーションとは何か
  • 従来のトレイン・テスト分割との比較
  • scikit-learnを使用したステップバイステップの実装
  • 層化K分割法、グループK分割法、ネストされたK分割法のような高度な変種
  • 不均衡なデータセットの扱い

🤔 K-フォールド交差検証とは何ですか?

K-分割交差検証は、データセットをK個の同サイズのフォールドに分割することで機械学習モデルを評価するために使用される再サンプリング技術です。モデルはK-1個のフォールドで訓練され、残りのフォールドで検証され、このプロセスをK回繰り返します。最終的なパフォーマンススコアは、すべてのイテレーションの平均です。

なぜK-フォールド交差検証を使用するのか?

  • 単一のトレイン-テスト分割とは異なり、K-Foldは複数の分割を使用して、パフォーマンス推定の分散を減らします。したがって、モデルは未見のデータセットについて予測を行う能力が向上します。
  • 各データポイントはトレーニングと検証に使用され、利用可能なデータを最大化し、より堅牢なパフォーマンス評価につながります。
  • モデルは異なるデータセグメントにわたって複数回検証されるため、過学習を検出し、軽減するのに役立ちます。これにより、モデルは特定のトレーニングサンプルを記憶することなく、新しいデータに対してうまく一般化することが保証されます。
  • 複数のフォールドにわたって結果を平均することで、K分割交差検証はモデルの真の性能のより信頼できる推定を提供し、バイアスと分散を減少させます。
  • K-Fold クロスバリデーションは、単一のトレインテストスプリットに対して過学習することなく、最適なハイパーパラメータを見つけるために、グリッドサーチやランダムサーチと組み合わせてよく使用されます。

🔍 Kフォールドとトレインテストスプリット

アスペクトKフォールド交差検証トレインテスト分割
データ活用データは複数のフォールドに分割されており、各データポイントが異なる反復にわたってトレーニングセットとバリデーションセットの両方の一部になる機会を持つことが保証されています。データを固定された部分に分割して、トレーニングとテストを行います。
バイアス-バリアンストレードオフそれは、モデルが見えないデータで複数回訓練されることで分散を減少させるため、最適なバイアス-分散トレードオフが達成されます。プレーンなトレインテスト分割では、高い分散の可能性があります。これは、モデルがトレーニングデータにしっかりと適合する一方で、テストデータを理解できないことが多いためです。
過剰適合のリスク異なるフォールドでモデルがテストされるため、過学習のリスクが低い。訓練とテストの分割が代表的でない場合、過剰適合のリスクが高くなります。
パフォーマンス評価より信頼性が高く一般化されたパフォーマンスの推定を提供します。性能は単一のトレインテスト分割に依存しており、バイアスがかかる可能性があります。

🏁 PythonでK-フォールド交差検証を実装する

<code>scikit-learn</code>を使用してK-Fold交差検証を実装しましょう。

ステップ1: 依存関係のインポート

まず、必要なライブラリをインポートすることから始めます。

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import KFold, cross_val_score, train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn import linear_model, tree, ensemble

ステップ 2: タイタニックデータセットを読み込み、探索する

このデモでは、非常に有名なタイタニックデータセットを使用します。これは、k-フォールド交差検証をどのように行うかを理解するのに役立ちます。

df = pd.read_csv("https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv")
print(df.head(3))
print(df.info())
  PassengerId  Survived  Pclass  \
0            1         0       3   
1            2         1       1   
2            3         1       3   

                                                Name     Sex   Age  SibSp  \
0                            Braund, Mr. Owen Harris    male  22.0      1   
1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   
2                             Heikkinen, Miss. Laina  female  26.0      0   

   Parch            Ticket     Fare Cabin Embarked  
0      0         A/5 21171   7.2500   NaN        S  
1      0          PC 17599  71.2833   C85        C  
2      0  STON/O2. 3101282   7.9250   NaN        S  
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   PassengerId  891 non-null    int64  
 1   Survived     891 non-null    int64  
 2   Pclass       891 non-null    int64  
 3   Name         891 non-null    object 
 4   Sex          891 non-null    object 
 5   Age          714 non-null    float64
 6   SibSp        891 non-null    int64  
 7   Parch        891 non-null    int64  
 8   Ticket       891 non-null    object 
 9   Fare         891 non-null    float64
 10  Cabin        204 non-null    object 
 11  Embarked     889 non-null    object 
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
None

ステップ3: データ前処理

今、モデルを構築する前にデータ処理と特徴エンジニアリングを始めることは素晴らしい習慣です。

df = df[['Survived', 'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare']]  # Select relevant features
df.dropna(inplace=True)  # Remove missing values

Encode categorical variable
label_encoder = LabelEncoder()
df['Sex'] = label_encoder.fit_transform(df['Sex'])

Split features and target
X = df.drop(columns=['Survived'])
y = df['Survived']
df.shape

(714, 7)

ステップ4:Kフォールド分割を定義する

kf = KFold(n_splits=5, shuffle=True, random_state=42)

ここでは、n_splits=5を指定し、データが5つのフォールドに分割されることを意味します。shuffle=Trueはランダム性を保証します。

ステップ5:モデルのトレーニングと評価

model = RandomForestClassifier(n_estimators=100, random_state=42)
scores = cross_val_score(model, X, y, cv=kf, scoring='accuracy')
print(f'Cross-validation accuracy scores: {scores}')
print(f'Average Accuracy: {np.mean(scores):.4f}')

クロスバリデーションの精度スコア: [0.77622378 0.8041958 0.79020979 0.88111888 0.80985915] 平均精度: 0.8123

score = cross_val_score(tree.DecisionTreeClassifier(random_state= 42), X, y, cv= kf, scoring="accuracy")  
print(f'Scores for each fold are: {score}')  
print(f'Average score: {"{:.2f}".format(score.mean())}')

各フォールドのスコアは: [0.72727273 0.79020979 0.76923077 0.81818182 0.8028169] 平均スコア: 0.78

⚡ 高度なクロスバリデーション技術

1. 階層的Kフォールド(不均衡データセット用)

不均衡クラスのデータセットに対して、ストラティファイドKフォールドは、各フォールドが全データセットと同じクラス分布を持つことを保証します。このクラスの分布は、不均衡分類問題に最適な選択です。

from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=skf, scoring='accuracy')
print(f'Average Accuracy (Stratified K-Fold): {np.mean(scores):.4f}')

平均精度(層別K分割法):0.8124

2. 繰り返しK-foldクロスバリデーション

繰り返しK-Foldは、異なる分割でK-Foldを複数回実行して、さらなる分散の低減を図ります。これは通常、データが単純で、ロジスティック回帰などのモデルがデータセットに適合できる場合に行われます。

from sklearn.model_selection import RepeatedKFold
rkf = RepeatedKFold(n_splits=5, n_repeats=10, random_state=42)
scores = cross_val_score(model, X, y, cv=rkf, scoring='accuracy')
print(f'Average Accuracy (Repeated K-Fold): {np.mean(scores):.4f}')

平均精度(繰り返しKフォールド):0.8011

3. ネストされたKフォールド交差検証(ハイパーパラメータ調整用)

ネストされたK-フォールドは、外側のループで性能を評価しながら、内側のループ内でハイパーパラメータチューニングを実行し、過学習を減らします。

from sklearn.model_selection import GridSearchCV, cross_val_score
param_grid = {'n_estimators': [50, 100, 150], 'max_depth': [None, 10, 20]}
gs = GridSearchCV(model, param_grid, cv=5)
scores = cross_val_score(gs, X, y, cv=5)
print(f'Average Accuracy (Nested K-Fold): {np.mean(scores):.4f}')

4. グループKフォールド(非独立サンプル用)

データセットにグループがある場合(例:同じ患者からの複数の画像)、グループKフォールドは、同じグループのサンプルがトレーニングとバリデーションに分割されないことを保証します。これは階層的データに対して便利です。

from sklearn.model_selection import GroupKFold
gkf = GroupKFold(n_splits=5)
groups = np.random.randint(0, 5, size=len(y))
scores = cross_val_score(model, X, y, cv=gkf, groups=groups, scoring='accuracy')
print(f'Average Accuracy (Group K-Fold): {np.mean(scores):.4f}')

💡 よくある質問

PythonでKフォールド交差検証を実行する方法は?

scikit-learnのcross_val_score()を使用し、KFoldをcvパラメータとして指定します。

KフォールドとストラティファイドKフォールドの違いは何ですか?

Kフォールドはデータをランダムに分割しますが、層化Kフォールドは各フォールドでクラスのバランスを維持します。

正しい折りたたみの数を選ぶにはどうすればいいですか?

  • 5倍または10倍はほとんどの場合の標準です。
  • 高いフォールド(例:20)はバイアスを減らしますが、計算時間が増加します。

PythonのKFoldクラスは何をしますか?

データセットを訓練と検証のために n_splits フォールドに分割します。

🔚 結論

あなたが構築している機械学習モデルが、見たことのないデータを提供されたときに最高のパフォーマンスを発揮することを保証するために、クロスバリデーションはモデルを信頼できるものにする重要なステップとなります。-フォールドクロスバリデーションは、モデルがトレーニングデータに過剰適合しないことを確実にする最良の方法の一つであり、バイアスとバリアンスのトレードオフを維持します。データを異なるフォールドに分割し、各フェーズを通じてモデルを反復的にトレーニングおよび検証することで、未知のデータセットが提供されたときにモデルがどのようにパフォーマンスを発揮するかについてのより良い推定を提供します。

Pythonでは、scikit-learnのようなライブラリを使用することでK-Foldクロスバリデーションを簡単に実装できます。KFoldやStratifiedKFoldは、不均衡なデータセットを扱うために提供されています。K-Foldクロスバリデーションをワークフローに統合することで、ハイパーパラメータを効果的に調整し、自信を持ってモデルを比較し、実際のアプリケーションに向けた一般化を強化することができます。

回帰、分類、または深層学習モデルを構築する場合、この検証アプローチは機械学習パイプラインの重要な要素です。

参考文献

  • k-分割クロスバリデーションへの優しい入門
  • K-フォールドクロスバリデーションの包括的ガイド
  • K-Fold クロスバリデーション技術とその要点
  • KerasとTensorFlowを使用して従業員の定着を予測する深層学習モデルを構築する方法

関連記事: