はじめに
初歩的な内容であるため,備忘録として簡単にMonte-Carlo積分と期待値に関してまとめる.
定義
まず,本記事において以下の定義を使用する.
- 関数 $f$ の定義域: $\mathcal{X} \subseteq \mathbb{R}^D$
- Riemann積分可能関数: $f: \mathcal{X} \rightarrow \mathbb{R}$
- 適当な確率密度関数: $p: \mathcal{X} \rightarrow \mathbb{R}_{\geq 0}$
期待値
まず,$f(x)$ の期待値計算は以下のように行われる.
$$
\int_{x \in \mathcal{X}} f(x) p(x) dx \approx \frac{1}{N} \sum_{i=1}^N f(x_i)
$$
ただし,$\{x_i\}_{i=1}^N \sim p(x)$ であるものとする.
Monte-Carlo 積分
上記の方法を利用する.
\begin{align}
\int_{x \in \mathcal{X}} f(x)dx &= \int_{x \in \mathcal{X}} \frac{f(x)}{p(x)} p(x) dx \\
&= \frac{1}{N} \sum_{i=1}^N \frac{f(x_i)}{p(x_i)}
\end{align}
このように $f(x)/p(x)$ というように変形し,$p(x)$ からのサンプリングで期待値を取る方法を重点サンプリングと呼ぶ.
検証
import numpy as np
lb, ub = -1, 3
x = np.random.random(10 ** 6) * (ub - lb) + lb
y = x ** 2
res = np.mean(y) / (1.0 / (ub - lb))
ans = 28 / 3
print(f"answer: {ans}, result: {res}, diff: {np.abs(ans - res)}")
>> answer: 9.333333333333334, result: 9.344802755374523, diff: 0.011469422041189503