이번 글은
2022.06.14 - [수학의 재미/확률분포] - 정균분포 난수를 만들어 주세요 #3 : Normal CDF 이용
정균분포 난수를 만들어 주세요 #3 : Normal CDF 이용
이번 글은 2022.06.13 - [수학의 재미/확률분포] - 정균 분포 난수를 만들어 주세요 #2 : Normal CDF 이용 정균분포 난수를 만들어 주세요 #2 : Normal CDF 이용 이번글은 2022.06.13 - [수학의 재미/확률분포] -..
sine-qua-none.tistory.com
에서 이어집니다. 정규분포 난수를 구하는 가장 유명하고 아름다운 방법입니다.
방법1 | 중심극한 정리를 이용하여, uniform random number의 표본평균 구하기 |
방법2 | Normal cumulative distribution function 을 이용하기 |
방법3 | Box Muller 방법으로 정규분포 난수 2개를 한방에 구하기 |
Box 와 Muller는 각각 통계학자, 컴퓨터 과학자입니다.

어떠한 식으로 정규분포 난수를 얻어내는지 그 테크닉을 감상하시죠.
문제는
I=∫∞−∞e−x2/2dx
의 값을 구하는데서 힌트를 얻습니다. 우선 식(1)을 어떻게 구하는지 알아봅니다.
이 값은 직접적인 적분으로 얻을 수 없다는 것이 알려져 있습니다. 대신 유명한 트릭으로 해결합니다.
I2=∫∞−∞e−x2/2dx⋅∫∞−∞e−y2/2dy⋅=∫∞−∞∫∞−∞e−(x2+y2)/2dxdy=∫2π0∫∞0e−r2/2rdrdθ=2π[−e−r2/2]∞0=2π
중간에
x=rcosθ,y=rsinθ
극좌표계로 치환하는 방법이 쓰였습니다. 이렇게 되면 면적소 dxdy는 rdrdθ로 바뀌게 됩니다.
결론적으로
I=√2π
이고
1=∫∞−∞∫∞−∞12πe−(x2+y2)/2dxdy
를 만족합니다.
Box Muller 방법은 바로 여기서 힌트를 얻는 것입니다.
우선 독립인 두 표준정규분포 X,Y의 joint probability density function은
f(x,y)=12πexp(−x2+y22) 입니다.
따라서 어떠한 (x,y)에 대한 2차원 영역 D에 대해
P(D)=∬
입니다.
그러면 극좌표변환 식(2)를 사용하여 \mathcal{D}는 (r,\theta)에 대한 2차원 영역 \mathcal{D}'에 대응이 될 것이고, 수식(3)은
\iint_{\mathcal{D}'} \frac1{2\pi} r e^{-r^2/2} drd\theta \tag{4}
라 치환이 됩니다.
그런데 수식(4)의 적분 되는 함수를 잘 살펴보면
\frac1{2\pi} r e^{-r^2/2}
는 (r,\theta)의 joint probability density function (이것을 f_{R,\Theta}라 쓰죠.)이고 R의 density function f_R과 \Theta의 density function f_{\Theta}는 각각
f_R(r) = re^{-r^2/2} ~,~ f_\Theta(\theta) = \frac{1}{2\pi}
라 쓰인 것이다!라고 해석이 됩니다. 심지어
f_{R,\Theta}(r,\theta) = f_R(r) f_\Theta(\theta)
처럼 joint density function이 각각 density function의 곱으로 나눠지니 R과 \Theta의 independance도 보장이 됩니다.
또한 0\leq r~,~ 0\leq \theta \leq 2\pi 임을 고려하여 f_R과 f_{\Theta}의 cdf F_R과 F_{\Theta}를 구하면 각각
\begin{align} F_R(r) &= \int_0^r f_R(s) ds = \int_0^r se^{-s^2/2} ds =1-e^{-r^2/2} \\ F_{\Theta}(\theta) & = \int_0^{\theta} \frac{1}{2\pi} dt = \frac{\theta}{2\pi} \end{align}
이죠.
여기서 마지막 단계로 또 cdf의 역함수 전법을 씁니다.
uniform random number를 w,v\sim \mathcal{U}[0,1] 2개 뽑습니다. 그리고
F_R(r) = w~, F_\Theta(\theta) =v
인 r, \theta를 찾으면 각각
r= \sqrt{-2\ln(1-w)}~,~ \theta = 2\pi v 가 되죠. 기호의 편의를 위해 1-w:=u로 바꾸면 u역시 uniform random이 될 것이고
r= \sqrt{-2\ln u}~,~ \theta= 2\pi v
최종적으로 정리하면 다음의 결과를 얻습니다.
Box Muller Method
균등분포 난수 u,v \sim \mathcal{U}[0,1]를 뽑아
x= \sqrt{-2\ln u} \cos(2\pi v) ~,~ y=\sqrt{-2\ln u} \sin(2\pi v)
라 하면 x,y는 서로 독립이고, 표준정규분포 \mathcal{N}(0,1)을 따른다.
위 정리가 표준정규분포 난수를 추출하는 가장 아름답고 효율적인 이론인 듯합니다.
coding을 해봅시다.
import math
import numpy as np
import matplotlib.pyplot as plt
def box_muller(n=1):
u = np.random.rand(n)
v = np.random.rand(n)
r = np.sqrt(-2 * np.log(u))
x = np.cos(2 * np.pi * v)
y = np.sin(2 * np.pi * v)
z1 = r * x
z2 = r * y
return z1, z2
if __name__ == '__main__':
res= box_muller(3)
print(res[0])
수식을 그대로 coding 해 주면 됩니다. 다만, 결괏값이 2개이므로 tuple 형식의 결과를 반환합니다.
결과는 아래와 같습니다.
[ 1.03447874 -0.66217353 -0.56004769]
Process finished with exit code 0
res[0]을 출력하므로 box_muller함수의 z1 이 출력되는 것입니다. 그렇다면 정말 정규분포 형태를 이루는지 관찰을 안 해볼 수 있겠죠. 3개 차트를 동시에 그려보겠습니다.
- X좌표 (python code에서 z1) 을 뜻함
- Y좌표 (python code에서 z2) 을 뜻함
- X와 Y의 관계
import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
def box_muller(n=1):
u = np.random.rand(n)
v = np.random.rand(n)
r = np.sqrt(-2 * np.log(u))
x = np.cos(2 * np.pi * v)
y = np.sin(2 * np.pi * v)
z1 = r * x
z2 = r * y
return z1, z2
def plot_box_muller_result():
nSimulation = 5000
rand = box_muller(nSimulation)
plt.subplot(131)
plt.hist(rand[0], bins=100)
plt.title('histogram(X)')
plt.subplot(132)
plt.hist(rand[1], bins=100)
plt.title('histogram(Y)')
plt.subplot(133)
plt.scatter(rand[0], rand[1])
plt.title('X vs Y')
plt.show()
if __name__ == '__main__':
plot_box_muller_result()
거두절미하고 결과를 보면,

극좌표를 써서 x,y를 표현한 것이라, 관계는 세 번째 그림처럼 동그란 모양이 나옵니다. x와 y는 정규분포 양상을 띠고 있습니다.
앞으로 이어질 글에서도 살펴보겠으나, Box Muller 방법은 정규성이 잘 보장되는 난수 발생 방법이라 많이 쓰입니다. 다음 글에서 조금 더 이야기를 진행해 보겠습니다.
'수학의 재미 > 확률분포' 카테고리의 다른 글
정균분포 난수를 만들어 주세요 #6 : random.normal (0) | 2022.06.17 |
---|---|
정균분포 난수를 만들어 주세요 #5 : Marsaglia-Bray method (0) | 2022.06.15 |
정균분포 난수를 만들어 주세요 #3 : Normal CDF 이용 (0) | 2022.06.14 |
정균분포 난수를 만들어 주세요 #2 : Normal CDF 이용 (0) | 2022.06.13 |
정균분포 난수를 만들어 주세요 #1 : 중심극한정리 이용 (0) | 2022.06.13 |
댓글