기계학습의 많은 문제들은 확률 분포를 명시적으로 대부분 모름
질량함수나 밀도함수를 알고 있으면 이산인 경우 summation OR 연속인 경우 integral
확률 분포를 모르는 경우에는 데이터를 이용해서 기대값을 계산해야함
→ Monte Carlo Sampling
확률 분포를 모르는 상황에서는 샘플링 방법을 알고 있다고 가정
즉, Sampling하는 방법을 알고 있다고 가정한다면 integral이나 summation 대신에 기대값을 계산
몬테카를로 샘플링 방법은 변수 유형(이산형, 연속형)에 상관없이 사용할 수 있음
$\mathbb{E}{x\text{\textasciitilde}P(x)}[f(x)] \approx \frac{1}{N} \sum^{N}{i=1} f(x^{(i)}), \quad x^{(i)} \stackrel{i.i.d}{\sim} P(x)$
Ex. $f(x)=e^{-x^2}$의 [-1, 1] 적분 값을 구하시오.
적분: $\int^1_{-1} e^{-x^2} dx$ $\approx 1.49364$
구간 [-1, 1]의 길이는 2이므로 적분 값을 2로 나누면 기대값을 계산하는 것과 같으므로 몬테카를로 방법을 사용할 수 있음
$\frac{1}{2}\int^1_{-1} e^{-x^2} dx \approx \frac{1}{N} \sum^N_{i=1} f(x^{(i)}), \quad x^{(i)} \stackrel{}{\sim} U(-1, 1)$
$\int^1_{-1} e^{-x^2} dx \approx \frac{2}{N} \sum^N_{i=1} f(x^{(i)}), \quad x^{(i)} \stackrel{}{\sim} U(-1, 1)$
몬테카를로 방법을 이용해서 구할 경우 $1.49387 \plusmn 0.00039$ 이므로 오차 범위 안에 참값이 존재
import numpy as np
def mc_int(fun, low, high, sample_size=100, repeat=10):
int_len = np.abs(high - low)
stat = []
for _ in range(repeat):
x = np.random.uniform(low=low, high=hgih, size=sample_size)
fun_x = fun(x)
int_val = int_len * np.mean(fun_x)
stat.append(int_val)
return np.mean(stat), np.std(stat)
def f_x(x):
return np.exp(-x**2)
print(mc_int(f_x, low=-1, high=1, sample_size=10000, repeat=100))
Sample size가 작으면 오차범위가 커짐
즉, 적절한 샘플링 개수가 있어야 적분을 구할 수 있음