雑記: モデルをアンサンブルしたい話(その1―カステラ本7.3節、8.7節)

私の誤りは私に帰属します。お気付きの点がありましたらお手数ですがご指摘いただけますと幸いです。
テキスト(カステラ本)関連記事まとめ(解釈を含む;文字の定義は記事内を参照)
  • 手元の訓練データでモデルを学習しある未知のデータ x_0 に対する2乗誤差を小さくしたいとする。手元の訓練データも x_0 上の真の値も確率的なので、誤差 f(x_0) + \varepsilon - \hat{f}(x_0) は確率変数であり、以下の3つの和で表せる。
    1. x_0 上の真の値がぶれる分(真の値のノイズ成分): \varepsilon
    2. 訓練データのぶれによりモデル予測値が期待値に満たない分:  E\bigl[ \hat{f}(x_0)\bigr] - \hat{f}(x_0)
    3. モデル予測値が期待値であったとしても真の値に満たない分:  f(x_0) - E\bigl[ \hat{f}(x_0)\bigr](これは確率的でない)
  • 上の 1., 2., 3. の和の2乗を小さくしたい。が、確率的な成分があると議論しにくいので確率的な成分について期待値をとることにする。と、クロスタームは消え、1., 2., 3. の2乗の期待値の和だけが残る。このうち 1. の2乗はモデル側で小さくできないので、モデル側で小さくしうる項として 2. の2乗の期待値と 3. の2乗が残る。この前者をバリアンス、後者をバイアスの2乗とよぶ。
  • よって、期待2乗誤差を小さくするにはバリアンスとバイアスを小さくすればよいが、典型的なモデルで両者はトレードオフの関係にあり、一方を小さくすれば他方が大きくなるとわかる(具体的にはリッジ線形回帰など)。よって、手元の訓練データでモデルを学習する分にはこれらのバランスを取るように適当に正則化などするしかない。
  • ここで仮にもし、並行世界(この世界とは異なる訓練データが得られた世界)たちの自分から学習済みのモデルを取り寄せることができるなら、集めたモデルたちの出力の平均を取って新たなモデルとすることでバリアンスを抑えることができる(※ 複数のモデルの出力の平均を新たな出力にできる場合)。
  • しかし、並行世界たちの自分から学習済みのモデルを取り寄せることはできない。
  • そこで、手元で仮想的な並行世界たちをつくり、そこで学習したモデルたちを平均することが考えれる。特に、訓練データからブートストラップ標本たちを生成することによりそれを達成する手法はバギング(bagging: bootstrap aggregating)といわれる。
キャラクターの原作とは無関係です。
f:id:cookie-box:20180305231302p:plain:w60

そういえば、カステラ本の7章でとばした箇所にあった、「バイアスと分散のトレードオフ」って何?

f:id:cookie-box:20180305232608p:plain:w60

以下の問題を考えてみてください。どうなりますか?

  • ある世界では、気温 X の日のアイスクリームの売り上げ YY = f(X) + \varepsilon になるとします。
    • f(\cdot) は決定的な関数で、\varepsilon は確率的な誤差で、{\rm E}(\varepsilon)=0, \; {\rm Var}(\varepsilon)=\sigma^2 とします。
  • さて、この世界で、ある日の気温が x_0 でした。この日の売り上げを予測モデル \hat{f}(\cdot) による予測値 \hat{f}(x_0) で予測したときの期待2乗誤差はいくらでしょうか? なお、予測モデル \hat{f}(\cdot) の確率的な成分は \varepsilon と独立とします。

f:id:cookie-box:20180305231302p:plain:w60

何その世界…ともかく、気温が x_0 の日の真の売り上げは f(x_0) + \varepsilon だよな。それで、いま確率的なのは、\varepsilon と…\hat{f}(x_0) もなのか。とりあえずこれらについての期待値を単に  E [ \cdot ] とかくと、期待2乗誤差は、

\begin{split} E \Bigl[ \bigl( f(x_0) + \varepsilon - \hat{f}(x_0) \bigr)^2 \Bigr] &=  E \Bigl[ f(x_0)^2 + \varepsilon^2 + \hat{f}(x_0)^2 + 2 f(x_0) \varepsilon - 2 f(x_0)\hat{f}(x_0) - 2 \hat{f}(x_0) \varepsilon \Bigr] \\ &= f(x_0)^2 + \sigma^2 + E \Bigl[ \hat{f}(x_0)^2 \Bigr] - 2 f(x_0) E \Bigl[ \hat{f}(x_0) \Bigr]\end{split}

こうなるよな。f(x_0) は確率的じゃないし、独立な確率変数の積の期待値は期待値の積だし。

f:id:cookie-box:20180305232608p:plain:w60

はい、間違っていませんが、それだと解釈しづらいですよね。「真の値の2乗とノイズの分散と予測値の2乗の期待値から真の値と予測値の期待値の積を引いたものです」といわれても。なのでこうしましょう。

\begin{split} E \Bigl[ \bigl( f(x_0) + \varepsilon - \hat{f}(x_0) \bigr)^2 \Bigr] &= f(x_0)^2 + \sigma^2 + E \Bigl[ \hat{f}(x_0)^2 \Bigr] - 2 f(x_0) E \Bigl[ \hat{f}(x_0) \Bigr] \! - \! E \Bigl[ \hat{f}(x_0) \Bigr]^2 \! \! \! \! + \!  E \Bigl[ \hat{f}(x_0) \Bigr]^2 \! \! \\ &= f(x_0)^2 + \sigma^2 + V \Bigl[ \hat{f}(x_0)^2 \Bigr] - 2 f(x_0) E \Bigl[ \hat{f}(x_0) \Bigr] \! + \! E \Bigl[ \hat{f}(x_0) \Bigr]^2 \\ &= \biggl\{f(x_0) -  E \Bigl[ \hat{f}(x_0) \Bigr] \biggr\}^2 + V \Bigl[ \hat{f}(x_0)^2 \Bigr] + \sigma^2 \\ &= E \Bigl[ f(x_0) - \hat{f}(x_0) \Bigr]^2 + V \Bigl[ \hat{f}(x_0)^2 \Bigr] + \sigma^2 \end{split}

こうすると「誤差の期待値(バイアス)の2乗と、予測値の分散(バリアンス)と、ノイズの分散の和」となりますよね。最初から予測値を期待値からのずれにしておけば一発ですけどね(以下)。

\begin{split} E \biggl[ \Bigl( f(x_0) + \varepsilon - \hat{f}(x_0) + E \Bigl[ \hat{f}(x_0) \Bigr] - E \Bigl[ \hat{f}(x_0) \Bigr] \Bigr)^2 \biggr] &= \biggl\{f(x_0) -  E \Bigl[ \hat{f}(x_0) \Bigr] \biggr\}^2 + V \Bigl[ \hat{f}(x_0)^2 \Bigr] + \sigma^2 \\ &= E \Bigl[ f(x_0) - \hat{f}(x_0) \Bigr]^2 + V \Bigl[ \hat{f}(x_0)^2 \Bigr] + \sigma^2  \end{split}

何にせよ、2乗誤差を下図のように区分けして各マスの期待値をとっているだけです。

f:id:cookie-box:20201228135133p:plain:w500

f:id:cookie-box:20180305231302p:plain:w60

俺に計算させた意味! あと図がごちゃごちゃしすぎ!! そもそもさ、期待2乗誤差が「誤差の期待値(バイアス)の2乗と、予測値の分散(バリアンス)と、ノイズの分散の和」だったら何なの? 何かうれしいの?

f:id:cookie-box:20180305232608p:plain:w60

「期待2乗誤差を小さくしたいなら、バイアスとバリアンスが小さいモデルにすべきである」といえるでしょう。ノイズはコントロールできませんから。

f:id:cookie-box:20180305231302p:plain:w60

ああそういうことか。「ある点に対する誤差の期待値も小さいし、予測値自体もぶれないモデル」にすべきってことなんだな…って、いまいちどうすればいいかわからないんだけど?

f:id:cookie-box:20180305232608p:plain:w60

実際にバイアスやバリアンスを小さくするにはどうすればいいのだろうと考えてみましょう。一般的な傾向として、トレードオフがありそうなことに気付くでしょう。

  • まず、バイアス=誤差の期待値を小さくするためには、手元の訓練データ上での誤差を徹底的に小さくするべきです。モデルをいくら複雑にしてもです。だって、精度を上げる余地があるのに手加減してしまったら、その分の誤差を詰められませんから。
  • しかし、バリアンス=予測値のぶれを小さくするには、手元の訓練データを徹底的に学ぶのは得策ではありません。なぜなら、訓練データはたまたま出たノイズを含みます。そのノイズまでしっかり学習してしまうようなモデルは、ノイズの出方によって予測値がぶれてしまいます。ぶれを抑えるには、あえて細かく学習させない工夫が要るでしょう。学習対象パラメータを制約してしまうのがその最たる例です。
実際、カステラ本の256~257ページに載っている、具体的なモデルでのトレードオフの例が以下の表の最初の3つです。k 近傍法では k の大小によってトレードオフが発生し、最小2乗線形回帰ではリッジ正則化をかける大きさ \lambda によってトレードオフが発生すると考えられます。k, \lambda を大きくするほどモデルが滑らかになり、小さくするほどモデルがでこぼこになるのが想像できると思います。また、以下の表の最後2つはウィキペディアにあった例です。
モデル \hat{f} バイアス(誤差の期待値) バリアンス(予測値の分散)
手元の訓練データから予測対象点 x_0 の最近傍 k 点を選び、それらの点の実績値の平均値を予測値とするモデル。 k を大きくするほど x_0 から離れた点が混ざってきてバイアスは大きくなる傾向にある。 k を大きくするほど多くの点の実績値の平均を取るのでバリアンスは小さくなる傾向にある。
手元の訓練データで最小2乗線形回帰したモデル。つまり、\hat{f}(x_0) = x_0^\top (X^\top X)^{-1} X^\top Y とする。横ベクトル h(x_0)=x_0^\top (X^\top X)^{-1} X^\top の各成分は、各データの実績値をどれだけの重みで取り込むべきかを意味する。 バイアスは「真のモデルと最良の線形近似との誤差の期待値」と「最良の線形近似といまの線形近似との誤差の期待値」に分解できる。後者は、何度も訓練データを取って学習したモデルの期待値をとれば、ゼロになる。 \|h(x_0)\|^2 \sigma^2 になる。
1つ上のモデルをリッジ正則化する。つまり、\hat{f}(x_0) = x_0^\top (X^\top X + \lambda I)^{-1} X^\top Y とする。 リッジ正則化したことにより「最良の線形近似といまの線形近似との誤差の期待値」はゼロにならなくなる。 h(x_0)逆行列の箇所に \lambda I が加わった分、バリアンスは小さくなる。
ニューラルネットワーク 例えば隠れ層のニューロン数を増やすとバイアスは小さくなる。 例えば隠れ層のニューロン数を増やすとバリアンスは大きくなる。
決定木。 例えば木を深くするとバイアスは小さくなる。 例えば木を深くするとバリアンスは大きくなる。

f:id:cookie-box:20180305231302p:plain:w60

確かにその表の例だと、バイアスを下げるとバリアンスが上がって、バリアンスを下げるとバイアスが上がる傾向がありそうだな。これがトレードオフか…でも、それだと結局「期待2乗誤差が小さくなるように適宜ハイパーパラメータを調節しましょう」ってことにならない? いまいちバイアスとバリアンスに分解した甲斐がないっていうか…。

f:id:cookie-box:20180305232608p:plain:w60

確かにそうですね。でも、例えば…ハヤトはここ1年の毎日の気温とアイスクリームの売り上げのデータをもとに、アイスクリーム売り上げ予測モデルを学習しました。そこにランプの精が現れていいました。「私は並行世界から来ました。並行世界のあなたが学習したモデルを差し上げます。並行世界の気温とアイスクリームの売り上げを生成する分布はこの世界と同じです。しかしこの世界と実現値はきっと異なるでしょう。予測に用いたモデルと学習方法はあなたと全く同じです」と。ちなみに同様のランプの精が計9人現れました。そしてハヤトは手元に自分が学習したモデル1つと、並行世界の自分が学習したモデル9つの、計10個のモデルを手に入れました。どうしますか?

f:id:cookie-box:20180305231302p:plain:w60

ええ…まあ突っ込みはさておき、同じモデルならバイアスもバリアンスも同じだからどれがよいモデルとかないよな。まあモデルが10個あるならなんか平均してみたくなるけど。

f:id:cookie-box:20180305232608p:plain:w60

ではモデルを平均しましょう。そうすると平均2乗誤差が小さくなることこそあれ、大きくなることはないとテキストの326~327ページにあります。訓練データを生成する分布を \mathcal{P} とし、この世界のハヤトが学習したモデルを \hat{f}^\ast(x) とし、それとあらゆる並行世界のハヤトたちが学習したモデルを平均したモデルを f_{\rm ag}(x) = E_{\mathcal{P}} \bigl[\hat{f}^\ast(x)\bigr] とします。E_{\mathcal{P}} \bigl[\cdot\bigr] は色々な訓練データを得ることについての期待値です(と思っています)。すると、ある (x,y) に対する2乗誤差の期待値について以下の不等式が成り立ちます(テキストでは y が確率変数であるようにかかれていますが、この議論はどちらかというとある y についてのものではないかと思っていますが、間違っていたらすみません)。

 \begin{split} E_{\mathcal{P}} \Bigl[ \bigl( y - \hat{f}^\ast(x) \bigr)^2 \Bigr] &= E_{\mathcal{P}} \Bigl[ \bigl( y- f_{\rm ag}(x) + f_{\rm ag}(x) -\hat{f}^\ast(x)  \bigr)^2 \Bigr] \\ &= E_{\mathcal{P}} \Bigl[ \bigl( y - f_{\rm ag}(x)\bigr)^2 + \bigl( f_{\rm ag}(x) -\hat{f}^\ast(x)  \bigr)^2 + 2\bigl( y - f_{\rm ag}(x)\bigr) \bigl( f_{\rm ag}(x) -\hat{f}^\ast(x)  \bigr) \Bigr] \\ &= \bigl( y - f_{\rm ag}(x)\bigr)^2 + E_{\mathcal{P}} \Bigl[ \bigl( f_{\rm ag}(x) -\hat{f}^\ast(x)  \bigr)^2 \Bigr]  \\ &= \bigl( y - f_{\rm ag}(x)\bigr)^2 + V_{\mathcal{P}} \Bigl[ \hat{f}^\ast(x) \Bigr] \\ &\geqq \bigl( y - f_{\rm ag}(x)\bigr)^2 \end{split}

つまり、1つのモデルの2乗誤差の期待値より、平均したモデルの2乗誤差の方が小さいか同じになります――モデルのバリアンスの分だけ。まあいまは \mathcal{P} から生成されるあらゆる訓練データについて学習したモデルが手元にあるわけではなく、ある10セットの訓練データで学習したモデルが手元にあるだけですが、訓練データの出方の経験分布を \mathcal{P} と考えれば話は同じはずです。

f:id:cookie-box:20180305231302p:plain:w60

本当だ…あれでも、その論理だといつでも複数のモデルを平均した方がいいの? 誤差を小さくしたかったら何でもいいから助っ人のモデルたちを用意すればいいってこと??

f:id:cookie-box:20180305232608p:plain:w60

ではありません。バイアスも平均されるわけですから、助っ人のモデルによってバリアンスが抑えられる以上にバイアスが増加したら意味がないです。何でもいいから寄せ集めればいいということにはなりません。

f:id:cookie-box:20180305231302p:plain:w60

ああ確かに…いまは10個のモデルのバイアスの期待値が同じだから、10個のモデルを平均してもバイアスが増える心配はなかったのか。

f:id:cookie-box:20180305232608p:plain:w60

それに、いまは回帰モデルで2乗誤差を損失とする場合でしたが、損失が異なる場合や、分類が目的の場合もありますよね。例えば個々のモデルが 0 か 1 を出力するような2値分類モデルであって、不正解率を損失とする場合、モデルをどうマージすればいいでしょうか。

f:id:cookie-box:20180305231302p:plain:w60

えっ、うーん、個々のモデルが 0 か 1 を出しているなら、10個のモデルの出力を平均したらきっと 0.3 とか 0.6 とかになるよな。でも、正解か不正解をみたいなら最終的には 0 か 1 かを出さないといけないから…閾値を決めて、0.5 未満なら 0、0.5 以上なら 1 にするとか? ぴったり 0.5 はどう扱うべきか迷うけど…。

f:id:cookie-box:20180305232608p:plain:w60

要は多数決ですね。しかしこの場合、マージすることが誤差を小さくすることにつながると限りません。テキスト327ページにある例ですが、あるデータの正解が 1 とします。そして、個々のモデルがこのデータに正しく 1 と出力できる確率が 0.4 とします。個々のモデルの正解率の期待値が 0.4 ということです。しかし、あらゆるモデルの多数決をとると必ず 0 を出力してしまいますね。4割のモデルが1、6割のモデルが0と判定するので。なので、多数決によって正解率がかえって 0 になってしまうのです。個々のモデルの正解率の期待値が 0.6 なら多数決によって正解率が 1 になるんですが。多数決を取る場合、多数派がよい予測をしていなければならないんです。こうかいてみると当然ですが。

f:id:cookie-box:20180305231302p:plain:w60

なら、バイアスを小さくする方に振ってバリアンスはモデルの平均で抑えにいくのがいいってことなのか…って、いや、現実には並行世界からランプの精こないじゃん!

f:id:cookie-box:20180305232608p:plain:w60

いかにも。なので、並行世界を自分でつくるしかありません。それがブートストラップ標本です。ブートストラップ標本とは、N 個のデータから N 個のデータを復元抽出(抽出したサンプルを元に戻して次のサンプルを抽出していく)することを B 回繰り返して B セットの標本を得たものです(301ページ;正確にはノンパラメトリックブートストラップですが)。

f:id:cookie-box:20180305231302p:plain:w60

え、うーん、そんなんでいいの? 確かに標本を複数用意できるけど、なんか自作自演みたいな…。

(その2があれば)つづく