Processing math: 21%
본문 바로가기
수학의 재미/확률분포

정균분포 난수를 만들어 주세요 #4 : Box-Muller 방법

by hustler78 2022. 6. 15.
728x90
반응형

이번 글은 

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는 각각 통계학자, 컴퓨터 과학자입니다.

호..혹시 박스 뮬러? Franck Muller unveils the First Automated Watch Box - Watch I Love

어떠한 식으로 정규분포 난수를 얻어내는지 그 테크닉을 감상하시죠.

문제는 

I=ex2/2dx

의 값을 구하는데서 힌트를 얻습니다. 우선 식(1)을 어떻게 구하는지 알아봅니다.

이 값은 직접적인 적분으로 얻을 수 없다는 것이 알려져 있습니다. 대신 유명한 트릭으로 해결합니다.

I2=ex2/2dxey2/2dy=e(x2+y2)/2dxdy=2π00er2/2rdrdθ=2π[er2/2]0=2π

중간에 

x=rcosθ,y=rsinθ

극좌표계로 치환하는 방법이 쓰였습니다. 이렇게 되면 면적소 dxdyrdrdθ로 바뀌게 됩니다.

결론적으로 

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_Rf_{\Theta}의 cdf  F_RF_{\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개 차트를 동시에 그려보겠습니다.

  1. X좌표 (python code에서 z1) 을 뜻함
  2. Y좌표 (python code에서 z2) 을 뜻함
  3. XY의 관계
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를 표현한 것이라, 관계는 세 번째 그림처럼 동그란 모양이 나옵니다. xy는 정규분포 양상을 띠고 있습니다. 

앞으로 이어질 글에서도 살펴보겠으나, Box Muller 방법은 정규성이 잘 보장되는 난수 발생 방법이라 많이 쓰입니다. 다음 글에서 조금 더 이야기를 진행해 보겠습니다.

728x90
반응형