7.10 クロスバリデーション - 限られたデータを最大限に活用する

モデルの「汎化性能」── つまり、まだ見たことのないデータに対してどれくらいうまく予測できるか ── を知りたい。 でも、テスト用に大量のデータを確保する余裕がない。

そんなとき、手持ちのデータを「使い回す」賢い方法がある。それがクロスバリデーション(交差検証)だ。

訓練データをいくつかの「折り目(フォールド)」に分け、一部をテスト、残りを訓練に使う。 この役割を順番に回していくことで、すべてのデータが一度はテストに使われる。

データを無駄なく活用しながら、汎化性能を推定する ── これがクロスバリデーションの核心だ。

データが足りないというジレンマ

機械学習で最も悩ましい問題の一つ:「データが足りない」。

理想を言えば、訓練用とテスト用に別々の大量データがほしい。でも現実には、データは有限だ。 テストに使えばその分だけ訓練データが減る。訓練に全部使えばテストができない。

データを訓練とテストに分ける際のトレードオフ

このジレンマを解決するのが「クロスバリデーション」だ。 同じデータを訓練にもテストにも使う ── ただし、同時にではなく、役割を「交代」させながら。

K分割クロスバリデーションの基本

クロスバリデーションの最も一般的な形式が「K分割クロスバリデーション」だ。

アイデアはシンプル:

  1. データをK個の等しいサイズの「フォールド」に分ける
  2. 1つのフォールドをテスト用、残りK-1個を訓練用にする
  3. モデルを訓練し、テスト用フォールドで誤差を計算
  4. テスト用フォールドを変えて、これをK回繰り返す
  5. K個の誤差の平均を取る
K=5のフォールド分割と役割の交代

こうすることで、すべてのデータポイントが一度だけテストに使われる。 データを無駄にせず、かつ「見たことのないデータ」への性能を推定できる。

なぜK=5やK=10なのか

Kの値はどう選ぶべきか?実務では K=5K=10 がよく使われる。なぜだろう?

ここで、7.1-7.2章で学んだ「バイアス」と「バリアンス」の概念を思い出そう。

K=2, K=5, K=10, K=nの比較

Kが小さいとき(例:K=2)

Kが大きいとき(例:K=n、全データ点数と同じ)

K=5やK=10は、このバイアス・バリアンス・計算コストのバランスが良い。 経験的に、これらの値が多くの状況で安定した結果を与えることが知られている。

数式で見るクロスバリデーション

各データ点での誤差を計算し、それを平均する。このシンプルなアイデアを式で書くと:

$$\text{CV}(\hat{f}) = \frac{1}{N} \sum_{i=1}^{N} L(y_i, \hat{f}^{-\kappa(i)}(x_i))$$

この式を分解してみよう:

つまり、「各データ点を、そのデータを見ていないモデルで予測し、その誤差を平均する」という意味だ。

Leave-One-Out クロスバリデーション

Kをデータ数Nと同じにした特別なケースが「Leave-One-Out クロスバリデーション(LOOCV)」だ。 名前の通り、「1つだけ残して除外する」という意味。

各反復で1つのデータ点だけをテストに使い、残りN-1個で訓練する。 これをN回繰り返す。

1点ずつ除外してテストする様子

LOOCVの利点

LOOCVの欠点

数式と計算のショートカット

$$\text{CV}_{(N)} = \frac{1}{N} \sum_{i=1}^{N} L(y_i, \hat{f}^{-i}(x_i))$$

これはK分割CVの特殊ケース(K=N)だ。$\hat{f}^{-i}$ は「i番目のデータを除いて訓練したモデル」を意味する。

うれしいことに、線形モデルには計算のショートカットがある。 実際に各データを除いて再訓練しなくても、1回のフィッティングで計算できる:

$$\text{CV}_{(N)} = \frac{1}{N} \sum_{i=1}^{N} \left( \frac{y_i - \hat{f}(x_i)}{1 - S_{ii}} \right)^2$$

この式の $S_{ii}$ は、フィット値 $\hat{y} = Sy$ を計算するときの行列Sの対角成分。 i番目のデータがフィットにどれだけ影響しているかを表す。 影響が大きいデータほど、除外したときの誤差が大きくなる ── これを補正しているのがこの公式だ。

クロスバリデーションの正しい使い方

クロスバリデーションは強力だが、使い方を間違えると大きな落とし穴がある

最も危険なのは「データ漏洩(Data Leakage)」だ。 特徴量の選択や前処理を、クロスバリデーションの外側で行ってしまうと、テストフォールドの情報が訓練に漏れてしまう。

たとえば、こんな間違いをしがちだ:

  1. まずデータ全体を見て、予測に役立ちそうな変数を選ぶ
  2. その後でK分割CVを行う

この手順だと、変数選択の時点でテストデータを「見て」しまっている。 CVの誤差推定は実際より良く見えてしまう(楽観的すぎる推定)。

正しい手順と間違った手順の対比

正しい方法

前処理もモデルの一部と考え、フォールドごとに一から実行する必要がある。

クロスバリデーションでモデルを選ぶ

クロスバリデーションの最も重要な用途の一つが「モデル選択」だ。

複数の候補モデル(例:異なる複雑さのモデル)があるとき、どれを選ぶべきか? 各モデルのCV誤差を計算し、最小のものを選ぶ。

ただし注意点がある。CV誤差にもばらつきがある。 フォールドの分け方によって結果が変わるため、「最小CV誤差のモデル」が本当にベストとは限らない。

複雑さに対するCV誤差のU字カーブと1SEルール

そこで使われるのが「1標準誤差ルール(1-SE rule)」だ。 標準誤差とは、CV誤差の「ばらつきの大きさ」を表す指標。これを使って:

  1. 最小CV誤差のモデルを見つける
  2. そのCV誤差 + 1標準誤差の範囲内で、最もシンプルなモデルを選ぶ

なぜシンプルさを優先するのか?同程度の性能なら、シンプルなモデルの方が過学習のリスクが低く、解釈もしやすい。 これは「オッカムの剃刀」の原理とも一致する。

ブートストラップとの比較

ここまでクロスバリデーションを見てきたが、汎化性能を推定する方法は他にもある。 比較のために「ブートストラップ」という別のアプローチを見てみよう。

ブートストラップの基本アイデアは「復元抽出」だ。 復元抽出とは、サンプルを引いた後、元に戻してからまた引くこと。つまり同じデータが何度も選ばれる可能性がある。

復元抽出によるブートストラップサンプリングの様子

B回のブートストラップサンプルを作り、各サンプルでモデルを訓練し、元データで評価する。

しかし、単純なブートストラップには問題がある。 N個のデータからN回復元抽出すると、選ばれないデータ点がどれくらいあるか? 確率論から計算すると、約37%のデータは一度も選ばれない。

つまり、評価時に使う元データの約37%は、訓練に使われていない「新しいデータ」として働く。 これは楽観的すぎる誤差推定を生んでしまう。

この問題を修正したのが「.632ブートストラップ」だ。

.632ブートストラップの公式

.632ブートストラップでは、訓練誤差と leave-one-out ブートストラップ誤差を組み合わせる:

$$\widehat{\text{Err}}^{(.632)} = 0.368 \cdot \overline{\text{err}} + 0.632 \cdot \widehat{\text{Err}}^{(1)}$$

この 0.368 と 0.632 はどこから来たのか?実は、先ほどの「約37%が選ばれない」という確率に対応している。 より正確には、1つのデータ点が選ばれない確率は $(1 - 1/N)^N \approx e^{-1} \approx 0.368$ だ。

この2つを重み付き平均することで、バランスの取れた推定を得る。

まとめ - データを賢く使う技術

クロスバリデーションは、限られたデータから汎化性能を推定するための強力なツールだ。

クロスバリデーションの全体像をまとめる

覚えておくべきポイント

  1. K分割CV:データをK個に分け、役割を交代させながら全データを活用
  2. K=5やK=10:バイアス、バリアンス、計算コストのバランスが良い
  3. LOOCV:バイアスは小さいが、バリアンスが大きく計算コストも高い
  4. データ漏洩に注意:前処理はフォールド内で行う
  5. 1標準誤差ルール:最小CV誤差だけでなく、シンプルさも考慮

テストデータが潤沢にあれば話は簡単だ。でも現実はそうではない。 クロスバリデーションは、その制約の中でできる限りの知恵を絞った方法だ。

データを「使い回す」という一見ずるそうなアイデアが、実は統計的に健全な推定を可能にする。 これが、機械学習の実務で欠かせない理由だ。