K-Foldクロスバリデーションを理解する:ステップバイステップガイド
📖 はじめに<&47;strong>
機械学習モデルがデータについて学ぶとき、トレーニングデータではうまく機能することが多いですが、見たことのないデータやテストデータではパフォーマンスが低下します。これをモデルの過学習と呼びます。モデルの過学習は、モデルがトレーニングデータをうまく捉えるときに発生し、アンダーフィッティングは、モデルがトレーニングデータでさえうまく機能しないときに発生します。
クロスバリデーションは、機械学習モデルが未見のデータに対してもうまく一般化することを保証する技術の一つです。以下のように機能します:
- データをフォールドに分割する: 任意のデータセットは、複数のサブセット、すなわち「フォールド」に分割されます。
- トレーニングと検証サイクル:モデルはデータのサブセットでトレーニングされ、1つのフォールドが検証に使用されます。このプロセスは繰り返され、毎回異なるフォールドが使用されます。
- 結果の平均: 各検証ステップからのパフォーマンス指標は平均化され、モデルの効果をより信頼できる推定値として提供します。
画像の出所
📌 前提条件
機械学習の基本知識<&47;strong> – モデルのトレーニング、評価指標、過学習の理解。
Pythonプログラミングスキル<&47;strong> – Pythonおよびscikit-learn<&47;code>、numpy<&47;code>、pandas<&47;code>などのライブラリに精通していること。
データセットの準備<&47;strong> – モデルのトレーニングのためにクリーンで前処理されたデータセット。
Scikit-Learnのインストール<&47;strong> – まだインストールされていない場合は、pip install scikit-learn<&47;code>を使用してインストール。
モデルのパフォーマンス指標の理解<&47;strong> – タスクに応じた精度、適合率、再現率、RMSEなどの知識。
一般的なクロスバリデーション手法
- K-Foldクロスバリデーション:データセットはk等分され、モデルはk回訓練され、毎回異なるフォールドが検証セットとして使用されます。
- 層化K分割:<&47;strong> この方法は、各フォールドが分類問題において同じ割合のクラスを維持することを保証します。これは、ターゲット変数のデータが不均衡な場合、すなわちターゲット変数がカテゴリカル列であり、クラスが均等に分布していない場合にしばしば使用されます。
- Leave-One-Out (LOO): この方法は、残りのインスタンスでトレーニングしながら、検証のために1つのインスタンスのみを使用し、すべてのインスタンスに対して繰り返します。
- 時系列交差検証: 逐次データに使用され、トレーニングデータが検証データに先行することを保証します。
クロスバリデーションは、最適なモデルとハイパーパラメータを選択するのに役立ち、過剰適合を防ぎます。
このガイドでは、以下を探ります:
- K-Foldクロスバリデーションとは何か
- 従来のトレインテスト分割とどのように比較されるか
scikit-learn<
を使用した段階的な実装- 層化K分割法、グループK分割法、ネストされたK分割法のような高度なバリエーション
- 不均衡なデータセットの取り扱い
🤔 K-Foldクロスバリデーションとは何ですか?<&47;strong>
K分割交差検証は、データセットをK個の同じサイズのフォールドに分割することによって機械学習モデルを評価するために使用される再サンプリング手法です。モデルはK-1個のフォールドで訓練され、残りのフォールドで検証され、このプロセスをK回繰り返します。最終的なパフォーマンススコアはすべての反復の平均です。
なぜKフォールド交差検証を使用するのか?<&47;strong>
- 単一のトレイン・テスト分割とは異なり、K-Foldは複数の分割を使用し、パフォーマンス推定のばらつきを減少させます。したがって、モデルは未見のデータセットに対する予測能力が向上します。
- 各データポイントはトレーニングと検証に使用され、利用可能なデータを最大化し、より堅牢なパフォーマンス評価につながります。
- モデルは異なるデータセグメントで複数回検証されるため、過学習を検出し軽減するのに役立ちます。これにより、モデルは特定のトレーニングサンプルを記憶するのではなく、新しいデータに対してうまく一般化されることが保証されます。
- K-Foldクロスバリデーションは、複数のフォールドにわたって結果を平均化することで、モデルの真のパフォーマンスのより信頼性の高い推定を提供し、バイアスと分散を減少させます。
- K-Foldクロスバリデーションは、単一のトレインテスト分割に対して過剰適合することなく、最適なハイパーパラメータを見つけるために、グリッドサーチやランダムサーチと組み合わせてよく使用されます。
🔍 Kフォールドとトレインテストスプリット
アスペクト | K-フォールド交差検証 | トレインテスト分割 |
---|---|---|
データ活用 | データは複数のフォールドに分割され、各データポイントが異なる反復にわたってトレーニングセットと検証セットの両方の一部になる機会を持つことが保証されます。 | データをトレーニングとテストのために固定された部分に分割します。 |
バイアス-バリアンスのトレードオフ | モデルが未見のデータで複数回訓練されるため、分散が減少し、最適なバイアス-分散トレードオフが達成されます。 | 単純なトレイン・テスト分割では高い分散の可能性があります。これは、モデルがトレーニングデータをよく把握し、テストデータを理解できないことが多いために発生します。 |
過剰適合リスク | モデルが異なるフォールドでテストされるため、過学習のリスクは低い。 | トレイン・テストの分割が代表的でない場合、過剰適合のリスクが高まります。 |
パフォーマンス評価 | より信頼性が高く一般化されたパフォーマンスの推定を提供します。 | パフォーマンスは単一のトレイン-テスト分割に依存しており、バイアスがかかる可能性があります。 |
🏁 PythonでK-Foldクロスバリデーションを実装する
scikit-learn<&47;code>を使用してK-Foldクロスバリデーションを実装しましょう。
ステップ1: 依存関係をインポートする<&47;strong>
まず、必要なライブラリをインポートすることから始めます。
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:タイタニックデータセットを読み込み、探索する<&47;strong>
このデモでは、非常に有名なデータセットであるタイタニックデータセットを使用し、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:データ前処理<&47;strong>
モデルを構築する前に、データ処理と特徴エンジニアリングを始めることは素晴らしい実践です。
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フォールド分割を定義する<&47;strong>
kf = KFold(n_splits=5, shuffle=True, random_state=42)
ここでは、n_splits=5<&47;code>を指定し、データが5つのフォールドに分割されることを意味します。shuffle=True<&47;code>はランダム性を保証します。
ステップ5:モデルのトレーニングと評価<&47;strong>
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]<&47;strong>\n平均精度: 0.8123<&47;strong>
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]<&47;strong>\n平均スコア: 0.78<&47;strong>
⚡ 高度なクロスバリデーション技術<&47;strong>
1. ストラティファイドKフォールド(不均衡データセット用)<&47;strong>
クラスの不均衡なデータセットに対して、層化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<&47;strong>
2. 繰り返しK分割交差検証<&47;strong>
繰り返しK-Fold<&47;strong>は、異なる分割で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<&47;strong>
3. ネストされたK分割交差検証(ハイパーパラメータ調整用)<&47;strong>
ネストされた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フォールド(非独立サンプル用)<&47;strong>
データセットにグループ(例:同じ患者からの複数の画像)が含まれている場合、グループ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}')
💡 よくある質問<&47;strong>
PythonでK-Foldクロスバリデーションを実行する方法は?<&47;strong>
scikit-learn<&47;code>のcross_val_score()<&47;code>をKFold<&47;code>をcv<&47;code>パラメータとして使用します。
K-Foldと層化K-Foldの違いは何ですか?<&47;strong>
K-Foldはデータをランダムに分割しますが、Stratified K-Foldは各フォールドでクラスのバランスを維持します。
適切な折りたたみの数をどのように選びますか?<&47;strong>
- ほとんどの場合、5倍または10倍が標準です。
- 高い折りたたみ(例:20)はバイアスを減少させますが、計算時間は増加します。
PythonのKFold<&47;code>クラスは何をしますか?<&47;strong>
データセットをトレーニングと検証のためにn_splits<&47;code>のフォールドに分割します。
🔚 結論
あなたが構築している機械学習モデルが、見たことのないデータを提供されたときに最も良いパフォーマンスを発揮することを保証するために、クロスバリデーションはモデルを信頼できるものにするための重要なステップとなります。–フォールドクロスバリデーションは、モデルがトレーニングデータに過剰適合しないことを確認するための最良の方法の一つであり、バイアス-バリアンスのトレードオフを維持します。データを異なるフォールドに分割し、各フェーズを通じてモデルを反復的にトレーニングおよび検証することで、未知のデータセットが提供されたときのモデルのパフォーマンスをより良く推定できます。
Pythonでは、scikit-learn<&47;code>のようなライブラリを使用することでK-Foldクロスバリデーションを簡単に実装できます。これにより、KFold<&47;code>やStratifiedKFold<&47;code>を使用して不均衡なデータセットを処理できます。K-Foldクロスバリデーションをワークフローに統合することで、ハイパーパラメータを効果的に調整し、自信を持ってモデルを比較し、実世界のアプリケーションに対する一般化を向上させることができます。
回帰、分類、または深層学習モデルを構築する際、この検証アプローチは機械学習パイプラインの重要な要素です。
参考文献
- k分割交差検証への優しい導入
- K-フォールド交差検証の包括的ガイド
- K-Foldクロスバリデーション技術とその基本
- KerasとTensorFlowを使用して従業員の定着を予測するディープラーニングモデルの構築方法