Cross-Validation
交差検証では、1つのデータセットをk個の分割に入れ替えながらモデルを学習・評価し、汎化性能を推定します。k分割の手順、バリエーション、リーク、コードを解説します。
交差検証では、同じデータセットを異なる分割で複数回学習・評価し、スコアをまとめることで、モデルが未見データでどの程度の性能を発揮するかを推定します。k分割交差検証では、データをk個の等しい部分(fold)に分割し、モデルが残りのk − 1個のfoldで学習する間、各foldを1回ずつ検証データとして使います。k個のスコアの平均が性能の推定値となり、スコアのばらつきからは、どのサンプルが検証セットに含まれたかによる推定値の変動を確認できます。1つのホールドアウト分割では信頼できるスコアを得るにはデータが少なすぎる場合、交差検証が標準的な評価方法になります。また、テストデータに触れずにアルゴリズムを比較し、ハイパーパラメーターを調整するためにも広く使われます。
k分割交差検証の仕組み#
データセットを1回シャッフルし、通常は5個または10個のfoldに分割します。k回の各ラウンドでは、新しいモデルを学習する際にk − 1個のfoldを使用し、残りのfoldでスコアを算出します。これにより、各サンプルは検証にちょうど1回、学習にk − 1回使われます。k個のスコアの平均を算出し、標準偏差とともに報告します。交差検証でモデルまたはハイパーパラメーターの設定を選んだ後、通常はその設定で学習データ全体を使って最終モデルを再学習します。1個抜き交差検証は、kがサンプル数と等しくなる極端なケースです。各ラウンドで学習に使えるデータが最も多くなりますが、サンプル数と同じ数のモデルを学習する必要があります。
交差検証スコアの読み方#
fold間のばらつきは、平均と同じくらい重要な情報です。以下のscikit-learnのスクリプトでは、付属の乳がんデータセットに対して5分割交差検証を実行します。
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
# 569 labeled tumor samples with 30 features each
X, y = load_breast_cancer(return_X_y=True)
# The scaler sits inside the pipeline, so each round fits it on that round's training folds only
model = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
# 5 stratified folds: each sample is validated exactly once
folds = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
scores = cross_val_score(model, X, y, cv=folds)
print("Fold accuracies:", scores.round(3))
print(f"Mean {scores.mean():.3f} +/- {scores.std():.3f}")5つのfoldごとの正解率は0.956から1.000の範囲で、平均は0.979、標準偏差は0.014です。単一の80/20分割では、この5つの値のいずれか1つが報告され、値の幅は4.4パーセントポイントになります。スケーラーをパイプライン内に配置することで、検証foldがデータ前処理の統計量に含まれないようにできます。データセット全体を先にスケーリングすると、各検証foldから学習データへデータリークが発生します。
交差検証の種類の選び方#
通常のk分割交差検証では、サンプルが互いに独立しており、入れ替え可能であると仮定します。そうでない場合、ランダム分割では情報が漏れたり、タスクを正しく反映しないfoldができたりします。
- 層化k分割: 各foldのクラス比率をデータセット全体と同じに保ちます。希少クラスがfoldから抜け落ちる可能性がある場合に重要です。
- グループk分割交差検証: 1人の患者、1本の動画、1つの調査地点など、同じグループの例を同じ分割にまとめることで、モデルが学習画像のほぼ重複データで検証されることを防ぎます。層化グループk分割交差検証では、この2つの制約を組み合わせます。
- 時系列分割: 過去のデータだけで学習し、その後の期間のデータで検証します。各ラウンドで学習期間を広げます。時系列データをシャッフルすると、モデルが未来の情報を見てしまうためです。
- ネストした交差検証: 各外側foldの内側で、ハイパーパラメーター調整用の交差検証ループを実行します。これにより、外側のスコアが、そのスコアを報告する同じfoldで調整したことによって過大評価されるのを防げます。
ディープラーニングにおける交差検証#
ディープネットワークをk回学習すると計算コストもk倍になるため、ImageNetやCOCOなどの大規模データセットでは、十分に安定したスコアを得られる固定の検証分割を1つ使用します。交差検証が有効なのは、数百枚から数千枚の画像で構成される小規模なビジョンデータセットです。このようなデータセットでは、1つの検証分割に各クラスのサンプルが数枚しか含まれないことがあります。UltralyticsのK分割交差検証ガイドでは、物体検出データセットをscikit-learnのKFoldで5つのfoldに分け、各foldの学習用・検証用画像リストとデータセットYAMLを作成し、各foldにつき1つのYOLO26モデルを学習します。物体検出の画像には通常複数のクラスが含まれるため、単一ラベルによる層化はできません。そのため、このガイドでは各foldのクラスごとに、検証ラベルと学習ラベルの比率も記録します。










