【Excelで機械学習】重点サンプリングによる無限区間のモンテカルロ積分をExcelで試す

前回は、被積分関数自体からサンプリングして、無限区間のモンテカルロ積分をする方法をExcelで試してみました。

>> 【Excelで機械学習】被積分関数からサンプリングする無限区間のモンテカルロ積分をExcelで

 

積分結果は理論値と大体一致したのですが、10,000回のサンプリングのうち使われた値は僅か222しかありませんでした。

率にして2.2%です。

これは非常にムダで、こういうことを計算コストが高いと称します。

 

こういうムダが多くなるのは、非常に確率が低い(稀にしか起こらない)領域を積分しようとしているからです。

2%しか起きない領域のために、100%の領域からサンプリングしているのですから、ほとんどがムダになってしまうのも仕方がないことです。

 

このムダを削減する方法が重点サンプリングです。

積分しようとしている領域がたとえ小さい領域(確率が低い領域)でも、その領域を特定できれば、そこをカバーするような関数を自分で選べます。

そして、その関数がカバーする領域が小さければ小さいほど、効率良くサンプリングができるというわけです。

 

この新たに選ぶ関数が次式におけるq(x)です。

サンプリングしてくる新たな確率分布を自分で選んでくるため、提案分布といいます。

 

元の式をq(x)で割ってq(x)を掛けているだけなのでイコールで結べます。

そして、f(x)p(x)/q(x)をまとめて被積分関数と見なします。

こんなに簡単でいいの?

という感じですが、実際に試してみましょう。

 

前回と同じく、標準正規分布N(0,1)2から無限大までの積分値を求めてみます。

下のグラフで、赤で塗りつぶした部分の面積を求めるということです。

ここをカバーする提案分布としては、N(2,1)を選びます。

N(2,1)とは平均2、標準偏差1の正規分布(Normal distribution)のことです。

 

これでサンプリングする値の50%が有効活用されることになります。

前回は2.2%しか有効活用されなかったことを思うと、大きな効率化ですね。

 

Excelでは次のように計算できます。

 

手順は次の通りです。

  1. 提案分布q(x)としてN(2,1)の乱数をB列に生成する
  2. B列をC列に「値だけ貼り付け」する(乱数は逐次新しい値に更新されてしまうため、ここで一旦確定させる)
  3. xが2から無限大でp(x)=1、それ以外の区間ではp(x)=0となる関数式をD列に入力する
  4. f(x)p(x)/q(x)の式をE列に入力する。f(x)はN(0,1)、p(x)はD列を参照、q(x)はN(2,1)
  5. 10,000回試行するため、10,002行までコピペする
  6. 10,000回試行したf(x)p(x)/q(x)の結果の平均をE1セルに計算する

 

その結果、この10,000回の試行では積分値が0.0227になりました。

理論値が0.0228ですからほぼ一致しています。

 

でも正直いうと、これは出来の良い試行です。

試行により、積分値の結果はばらつきます。

そこで、どれくらいばらつくかを調べてみました。

 

10,000回の試行を1,000回行い、1,000個の結果を出し、その平均と標準偏差を調べました。

これを人手でやる時間はありませんので、マクロを使いました。

その結果は次の通りです。

 

平均=0.022803

標準偏差=0.00114

標準誤差=5%

 

平均は理論値通りで、5%くらいばらつくことが分かります。

 

参考のため、前回の重点サンプリングを使わないやり方でも、同様のテストを行いました。

結果は次の通りです。

 

平均=0.02279

標準偏差=0.00154

標準誤差=7%

 

平均はほぼ理論値通りですが、ばらつきはやや大きい7%でした。

重点サンプリングを使った方が、少し精度が上がることを確認できました。