ブートストラップ法 — データを引き直して誤差を測る

7.11 Bootstrap Methods

ここまで私たちは「モデルの誤差をどう見積もるか」を旅してきた。 AIC、BIC、クロスバリデーション——どれも一長一短だった。

ここで、ある不思議な発想に出会う。

「もしデータを取り直せたら? でも、お金も時間もない。 だったら、手元のデータから "取り直したフリ" をしよう

この一見いかさまのようなアイデアが、現代統計学の道具箱で最も鋭いナイフ 「ブートストラップ法(Bootstrap)」だ。

このチャプターでは、ブートストラップが なぜ「データを引き直す」ことで誤差を測れるのか、 単純に使うと楽観的すぎる罠にハマる理由、 そしてそれを救う .632 推定量.632+ 推定量 を、 見て、感じて、納得できるように追っていく。

もしデータを取り直せたら?

統計学にはひとつ、深い夢がある。

「もし同じ実験を100回繰り返せたら、推定値がどのくらいブレるか、誤差がどのくらいか、すぐに分かるのに」

たとえばあなたが手元のデータから「平均は5.3です」と答えたとする。 でも別の日にもう一度データを取れば「5.1」かもしれないし、「5.8」かもしれない。この揺らぎこそが「標準誤差」だ。

標準誤差は、推定値(平均値や回帰係数など)が「データを取り直したら、どれくらいブレるか」を表す目安だ。 これが小さければ推定は信頼でき、大きければ「もう少しデータがほしい」というシグナルになる。

問題は、私たちが現実にデータを取り直せないこと。実験はコストがかかる。患者には何度も採血できない。

ここで、ブラッドリー・エフロン(Bradley Efron)が1979年に提案した、ほとんど魔法のようなアイデアが登場する。

「手元の N 個のデータから、重複を許して N 個を引き直す。 これを何度も繰り返せば、まるでデータを取り直したかのように振る舞える」

英語で "pull yourself up by your bootstraps"(自分の靴ひもを引っ張って自分を持ち上げる)という慣用句がある。 不可能なはずなのにやってのける——この手法の名前はそこから来ている。

元データから復元抽出でブートストラップサンプルを作る様子
左の箱(元データ)から重複を許して何度もランダムに選び、複数のブートストラップサンプルを作る

アニメーションを見てほしい。左に5色の点(元データ)があり、 そこからランダムに5個を選んでは右の箱(ブートストラップサンプル)に入れる。重複ありで引くので、同じ色が2回以上選ばれることもある。 これを B 回繰り返す——それがブートストラップ法の全体像だ。

なぜそれで誤差が測れるのか — 経験分布関数の正体

「データを引き直したフリ」がなぜ機能するのか。 その鍵は 経験分布関数(empirical distribution function) $\hat{F}$ にある。

世の中に "真の分布" $F$ が存在し、 私たちはそこから $N$ 個のデータをサンプリングして手に入れた。 しかしその $F$ の中身は分からない。

ここで素朴な疑問。「データから分布を作るとしたら、どう作る?」 一番素直な答えは、観測した点の上に等しい重み $1/N$ をペタペタと置くこと。 これが経験分布関数 $\hat{F}$ だ。

$$\hat{F}(z) = \frac{1}{N}\sum_{i=1}^{N} \mathbb{1}\{z_i \le z\}$$

ここで $\mathbb{1}\{\cdot\}$指示関数:中の条件が成り立てば 1、そうでなければ 0 を返す。 だからこの式は「データ点 $z_i$ のうち $z$ 以下のものの割合」を表す。 各観測の位置で 1 段ずつ上がる、階段関数の高さの式だ。

真の分布Fと経験分布F-hatの関係を示すアニメーション
薄い青線が真の分布 F(滑らかな曲線)、赤い階段が経験分布 F-hat。データ点が増えるほど階段が曲線に近づく

$N$ が大きくなるにつれ、$\hat{F}$$F$ にどんどん近づく(大数の法則)。

ブートストラップの本質はこうだ:

真の分布 F からサンプリングするかわりに、経験分布 $\hat{F}$ からサンプリングする$\hat{F}$$F$ をうまく近似してさえいれば、 得られる挙動も $F$ から取り直したときと似たものになる。

$\hat{F}$ からのサンプリング——それは、元データから等確率で復元抽出することと同じだ。 壺の中に番号付きの玉を入れ、ひとつ取り出して記録し、また壺に戻す、を繰り返す。 戻すからこそ、同じ玉が何度も選ばれることがある。 これを $N$ 回繰り返して新しい $N$ 個のデータセットを作る。 これがブートストラップサンプルの正体だ。

アルゴリズム — B 回引いて統計量を眺める

具体的な手順はとてもシンプルだ。

  1. 訓練データ $Z = (z_1, \dots, z_N)$ から、復元抽出$N$ 個取り出して新しいデータセット $Z^{*1}$ を作る
  2. これを $B$ 回繰り返す(普通は $B = 100$$200$ など)
  3. 各ブートストラップサンプル $Z^{*b}$ で、興味ある統計量 $S(Z^{*b})$ を計算する(モデルを学習し直してもよい)
  4. 得られた $S(Z^{*1}), \dots, S(Z^{*B})$ばらつきを見れば、それが $S(Z)$ の標準誤差の推定になる
B回のブートストラップ統計量がヒストグラムとして集まっていくアニメーション
上から落ちてくる丸がブートストラップ統計量 S(Z*b)。集積するとヒストグラム(青)が育つ。赤線が平均、黄破線が±標準偏差

これだけ。難しい数学はいらない。 やっていることは「データを引き直して、毎回モデルを作って、その結果を眺める」だけだ。

まず $\bar{S}^{*}$ を「$B$ 個のブートストラップ統計量の平均」と定めておこう:

$$\bar{S}^{*} = \frac{1}{B}\sum_{b=1}^{B} S(Z^{*b})$$

これを使って分散は次のように見積もる:

$$\widehat{\mathrm{Var}}\bigl[S(Z)\bigr] = \frac{1}{B-1}\sum_{b=1}^{B}\bigl(S(Z^{*b}) - \bar{S}^{*}\bigr)^2$$

これがブートストラップで得られる 分散の推定量$S(Z^{*b})$ たちが平均からどれだけ離れているかを素直に計算しているだけだ。標準誤差$\sqrt{\widehat{\mathrm{Var}}}$ として、 信頼区間はヒストグラムの 2.5% と 97.5% 分位点として、すぐに取り出せる。

クロスバリデーションが「データを分けて」誤差を測るのに対し、 ブートストラップは「データを増やすフリをして」誤差の分布そのものを覗き込む。 これは、点推定では分からない信頼区間や標準誤差まで一発で出せる、強力なテクニックだ。

単純ブートストラップは "甘すぎる" — 訓練と評価の重複問題

予測誤差の推定に、ブートストラップをそのまま使うとどうなるか。

各ブートストラップサンプル $Z^{*b}$ でモデル $\hat{f}^{*b}$ を学習し、元の訓練データ $z_i = (x_i, y_i)$ で誤差を測る。式で書くとこうだ:

$$\widehat{\mathrm{Err}}_{\mathrm{boot}} = \frac{1}{B \cdot N}\sum_{b=1}^{B}\sum_{i=1}^{N} L\bigl(y_i, \hat{f}^{*b}(x_i)\bigr)$$

一見もっともらしい。だが、これは 楽観的すぎる 推定量だ。なぜか?

ここでひとつ、不思議な数字を紹介しよう。観測 $i$ がブートストラップサンプル $Z^{*b}$少なくとも1回は含まれる確率を考える。

1 回の抽選で観測 $i$選ばれない確率は $1 - 1/N$。 これを $N$ 回連続で繰り返して全部外れる確率は $(1-1/N)^N$。 だから「少なくとも 1 回は当たる」確率はその補集合:

$$\Pr\{i \in Z^{*b}\} = 1 - \Bigl(1 - \tfrac{1}{N}\Bigr)^{N}$$

$N$ が大きくなる極限を考えよう。指数関数の有名な性質 $(1 - 1/N)^N \to 1/e$ を使うと、

$$1 - \Bigl(1 - \tfrac{1}{N}\Bigr)^{N} \xrightarrow{N \to \infty} 1 - e^{-1} \approx 0.632$$

つまり、約 63.2% の確率で、観測 $i$ は訓練データの中にも入っている。 逆に言えば、約 36.8% の確率で「カバンの外」に残る。 この $0.632$ という数字は、ブートストラップ理論の至るところに顔を出すマジックナンバーだ。

訓練データとブートストラップサンプルの重複を示すベン図アニメーション
青円(ブートストラップサンプル Z*)と黄円(元データ Z)が重なると、63.2%が重複。赤い領域がカンニングゾーン

これは、テストでカンニングしているようなものだ。 「テスト問題」として使った $x_i$ が、モデルを学習させた箱の中にも入っている。 当然モデルは「あ、これ見たことある」と答えてしまう。誤差は実際より小さく見える。

たとえば、1-最近傍分類器で実験してみよう。 ラベルと予測子が完全に独立というナンセンスな問題(何の手がかりもない状況)では、真の誤差はコイン投げと同じ $0.5$ のはず。 ところが $\widehat{\mathrm{Err}}_{\mathrm{boot}}$ はシミュレーション上、約 $0.184$ という値を返してしまう。 完璧にだまされている。

Out-of-Bag — カバンに入らなかった子たちで採点する

ならば、カンニングできない子だけに採点させればいい

観測 $i$ について、ブートストラップサンプル $Z^{*b}$含まれなかったサンプルだけを使って予測誤差を計算する。 これを Leave-One-Out Bootstrap 推定量 と呼ぶ。

$$\widehat{\mathrm{Err}}^{(1)} = \frac{1}{N}\sum_{i=1}^{N} \frac{1}{|C^{-i}|}\sum_{b \in C^{-i}} L\bigl(y_i, \hat{f}^{*b}(x_i)\bigr)$$

ここで $C^{-i}$ は、観測 $i$含まないブートストラップサンプルのインデックス集合。$B$ が十分大きければ、$|C^{-i}|$ はおおむね $0.368 B$ 個($e^{-1}$ の割合)になる。$B$ が小さすぎるとそもそも $C^{-i}$ が空になる観測が出てしまうので、$B \ge 200$ くらいを目安に取る。

out-of-bag観測が袋の外に残る様子のアニメーション
楕円の「袋」が降りてきて点を内側に取り込む。袋に入らなかった赤い点(out-of-bag)が採点用として選ばれる

ブートストラップサンプル 1 個あたり、元データの約 $36.8\%$$= e^{-1}$)は含まれない。 これらの観測を out-of-bag(袋に入らなかった、OOB)と呼ぶ。ランダムフォレストでもおなじみの考え方だ。

「観測ごとに、それを学習に使わなかったモデルだけで予測誤差を測る」という発想は、Leave-One-Out クロスバリデーション(LOO-CV)にとてもよく似ている。 LOO-CV では「観測 $i$ を完全に除いて学習」するのに対し、ブートストラップ版では「観測 $i$ が偶然入らなかったサンプルだけ集めて平均」する。 兄弟関係にあるが、データの引き方が違うのがポイントだ。

ただし、これにも欠点がある。各ブートストラップサンプルは実質「元データの 63% くらいの異なる観測」しか含まないので、ふだんより小さなデータで学習していることになる。 学習曲線がまだ急な領域なら、モデルは本来より劣るので、誤差がやや大きめに出てしまう。

0.632 という不思議な数 — .632 推定量の登場

Leave-One-Out Bootstrap は やや悲観的。普通の訓練誤差 $\overline{\mathrm{err}}$明らかに楽観的

ならば、両者をいい塩梅で混ぜたらちょうど良くなるんじゃないか? これが .632 推定量 のアイデアだ。

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

なんと露骨な名前。だが、この $0.632$ には意味がある。 それは Section 4 で出てきた、ブートストラップサンプルに含まれる確率 $1 - e^{-1} \approx 0.632$ だ。

直感的にはこうだ:

2つの誤差推定値を重み付きで混ぜる天秤アニメーション
左の低いバー(訓練誤差、青)と右の高いバー(leave-one-out、赤)を天秤で混ぜると、ちょうどよい高さの黄色いバー(.632推定量)が生まれる

この確率による重み付けを素直に書き下したのが .632 推定量だ。 多くの場合、これは絶妙にちょうど良い推定値を返す。

でも .632 でもまだ騙される — 過学習との戦い

.632 推定量は強力だが、極端な過学習には弱い。

たとえば 1-最近傍分類器。これは「自分自身を一番近い点として返す」ので、訓練データ上では完璧に正解する$\overline{\mathrm{err}} = 0$。 一方、out-of-bag 評価では真の誤差 $0.5$ になる。

$$\widehat{\mathrm{Err}}^{(.632)} = 0.368 \times 0 + 0.632 \times 0.5 = 0.316$$

正解は $0.5$$0.316$ ではまだ楽観的だ。$\overline{\mathrm{err}} = 0$ の貢献が、過学習のせいで実態と乖離しているのに、これを律儀に $0.368$ の重みで混ぜてしまうのが問題。

そこで Efron と Tibshirani は 過学習の程度を測って、重みを動的に調整する ことを思いついた。 これが .632+ 推定量だ。

まず、データに完全にノイズしかない世界の誤差を考える。 ラベルと予測子が独立な場合の誤差を「情報なし誤差 $\hat{\gamma}$」と定義する。経験的に推定可能:

$$\hat{\gamma} = \frac{1}{N^2}\sum_{i=1}^{N}\sum_{i'=1}^{N} L\bigl(y_i, \hat{f}(x_{i'})\bigr)$$

この式を読み解こう。二重和 $\sum_i \sum_{i'}$全ペアの総当たりを意味する。 本来 $y_i$$x_i$ に対応するペアだが、ここでは $x_{i'}$ に予測させて誤差を測る——わざとペアを崩している。 つまり「もし $x$$y$ の対応がでたらめだったら、モデルはどれだけハズすか」を平均したもの。 これが情報がゼロのときに到達する誤差の天井だ。

次に、相対的過学習率 $\hat{R}$ を定義する:

$$\hat{R} = \frac{\widehat{\mathrm{Err}}^{(1)} - \overline{\mathrm{err}}}{\hat{\gamma} - \overline{\mathrm{err}}}$$

これを使って重みを調整する:

$$\widehat{\mathrm{Err}}^{(.632+)} = (1-\hat{w})\,\overline{\mathrm{err}} + \hat{w}\,\widehat{\mathrm{Err}}^{(1)}, \quad \hat{w} = \frac{0.632}{1 - 0.368\,\hat{R}}$$
過学習度R-hatに応じて重みw-hatが変化するスライダーアニメーション
スライダーを右に動かすと過学習度 R-hat が上昇。訓練誤差バー(青)が縮み、out-of-bag バー(赤)が伸び、重み w-hat が1に近づく。結果バー(緑)が最終的に out-of-bag と一致

過学習を検知して、自動的に out-of-bag 評価の比率を上げる——この賢さが .632+ の威力だ。 1-最近傍の例なら $\hat{R} = 1, \hat{w} = 1$ となり、$\widehat{\mathrm{Err}}^{(.632+)} = 0.5$ で正解にぴったり戻る。

ブートストラップとクロスバリデーション — それぞれの居場所

最後に、ブートストラップクロスバリデーションを並べて見よう。 どちらも「データを使い回して誤差を測る」という点では兄弟だが、性格は違う。

観点クロスバリデーションブートストラップ
データの使い方分割(重複なし)復元抽出(重複あり)
標準誤差・信頼区間難しい自然に出せる
計算量KB 回(B ≈ 100)
バイアス傾向K が小さいと悲観的単純版は楽観的、.632+で補正
クロスバリデーションとブートストラップのデータ使用方法の対比アニメーション
左:CVはデータを色分けブロックに分割し、各ブロックを順番にテストする。右:ブートストラップは復元抽出で毎回異なるサンプルを作る(未選択点がグレー)

ブートストラップが特に光るのは、推定値そのものの不確実性を測りたいとき。 たとえば「この回帰係数の 95% 信頼区間は?」「予測値のばらつきは?」——こうした問いに対し、 ブートストラップは分布まるごとを返してくれる。

一方、シンプルに「予測誤差はどのくらい?」を問うだけならクロスバリデーションのほうが解釈しやすい。

回帰係数の 信頼区間 が知りたい。あなたはどちらを選ぶ?」

CV は「分割して誤差を測る」だけなので、係数の分布までは出してくれない。 一方ブートストラップは、B 回モデルを引き直すたびに係数も B 個得られる。そのヒストグラムがそのまま信頼区間になる。答えは明らかだ。

逆に「単に予測誤差を測りたいだけ」なら、何度もモデルを学習するブートストラップは大げさだ。 10 分割 CV で十分なことが多い。道具は適材適所

まとめ

ブートストラップ法は、データを引き直すフリでモデルの誤差や信頼区間を測る、シンプルにして強力な手法だ。

次のチャプターでは、テスト誤差の条件付き vs 期待値の区別について、より深く踏み込んでいく。