11.6 Monte Carlo와 샘플링

실습 · 연습문제 2개

자기 정규화 importance sampling과 유효 표본 크기 effective-sample-size

제안분포 qq에서 뽑은 표본 x1,…,xNx_1, \dots, x_N과 로그 가중치 log⁡wi=log⁡p~(xi)−log⁡q(xi)\log w_i = \log \tilde{p}(x_i) - \log q(x_i)가 있다. 목표 밀도 p~\tilde{p}는 정규화 상수를 모르는 상태다. 자기 정규화(self-normalized) importance sampling 추정량과 유효 표본 크기(ESS)는

I^=∑iwif(xi)∑iwi,ESS=(∑iwi)2∑iwi2\hat{I} = \frac{\sum_i w_i f(x_i)}{\sum_i w_i}, \qquad \mathrm{ESS} = \frac{\big(\sum_i w_i\big)^2}{\sum_i w_i^2}

이다. 함수 self_normalized_is(logw, fx)를 완성해 (estimate, ess)를 반환한다. logw와 fx는 shape (N,)인 배열이다.

주의. 로그 가중치는 수백에서 수천이 될 수 있다. np.exp(logw)를 그대로 계산하면 overflow가 나서 inf·nan이 된다. 두 식 모두 가중치에 같은 상수를 곱해도 값이 변하지 않는다는 점을 이용한다.

테스트는 다음을 확인한다.

  • 가중치가 모두 같으면 ESS = N이고 추정값은 fx의 평균이다.
  • 가중치 하나가 압도적이면 ESS는 1에 가깝다.
  • 로그 가중치가 1000 근처여도 결과가 유한하다.
  • 목표 N(0,1)\mathcal{N}(0, 1), 제안 N(0,22)\mathcal{N}(0, 2^2)에서 E[X2]=1\mathbb{E}[X^2] = 1을 추정한다.

기각 표집 구현하기 rejection-sampler

구간 [0,1][0, 1] 위의 밀도 p~(x)\tilde{p}(x)(정규화되어 있지 않아도 된다)에서 표본을 뽑는다. 제안분포는 균등분포 q(x)=1q(x) = 1이고, 모든 xx에서 p~(x)≤M\tilde{p}(x) \le M이 되는 상수 MM이 주어진다. 기각 표집의 한 단계는 다음과 같다.

  1. x∼Uniform(0,1)x \sim \mathrm{Uniform}(0, 1), u∼Uniform(0,1)u \sim \mathrm{Uniform}(0, 1)을 뽑는다.
  2. u⋅M<p~(x)u \cdot M < \tilde{p}(x)이면 xx를 받아들이고, 아니면 버린다.

함수 rejection_sample(density, M, n, rng)을 완성한다.

  • density: NumPy 배열을 받아 같은 shape의 밀도 값을 돌려주는 함수
  • M: envelope 상수
  • n: 필요한 표본 수
  • rng: np.random.default_rng(...)로 만든 난수 생성기 (이것만 쓴다)

반환값은 (samples, acceptance_rate)다. samples는 shape (n,)인 배열로 정확히 n개, acceptance_rate는 지금까지 제안한 후보 중 받아들인 비율이다.

테스트는 Beta(2, 5) 밀도 30x(1−x)430x(1-x)^4에서 표본의 평균·분산과 분포 모양(Kolmogorov–Smirnov 검정), 그리고 수용률이 1/M1/M에 가까운지 확인한다.

힌트: 후보를 하나씩 뽑으면 느리다. 한 번에 여러 개를 뽑아 받아들인 것만 모으고, n개가 찰 때까지 반복한다.