JavaScript에서 Box-Muller 방법에 의한 정규 분포로부터의 샘플링

1. 배경



표준 정규 분포에 따라 확률 변수를 생성하는 방법으로 Box-Muller법(박스=뮬러법)이 알려져 있습니다.
Box-Muller법을 사용하면, 균일 분포에 따른 확률 변수를 변환함으로써 정규 분포에 따른 의사 난수를 생성할 수 있다. 균일 분포에 따른 난수는 대부분의 프로그래밍 언어로 제공되고 있기 때문에(자바스크립트라면 Math.random() ) Box-Muller법과 조합하면 정규 분포로부터의 샘플링이 가능해진다.

2. 수식



$U_1, U_2$가 구간 $(0, 1)$에서의 균일 분포를 따르는 서로 독립적인 확률 변수인 경우, 다음 식에 의해 정의되는 $Z_0, Z_1$는 표준 정규 분포 $N(0, 1 )$에 따라 서로 독립적인 확률 변수가 된다.
\left\{
    \begin{array}{l}
     Z_0 = R cos(\Theta) = \sqrt{-2lnU_1} cos (2 \pi U_2) \\
     Z_1 = R sin(\Theta) = \sqrt{-2lnU_1} sin (2 \pi U_2)
    \end{array}
  \right.

3. 구현



표준에서 사용할 수 있는 Math.random() 가 균일 분포에 따른 난수임을 이용한다.
// Generate n samples from standard normal distribution
function boxMuller(n) {
  const samples = [];
  Array(Math.ceil(n / 2)).fill().forEach(_ => {
    const R = Math.sqrt(-2 * Math.log(Math.random()));
    const theta = 2 * Math.PI * Math.random();
    samples.push(R * Math.cos(theta)); // z1
    samples.push(R * Math.sin(theta)); // z2
  });
  // if n is odd, drop the last element
  return samples.slice(0, n);
}

예를 들어 boxMuller(10)를 호출하면 표준 정규 분포에서 10 개의 샘플이 들어있는 Array가 반환됩니다.

4. 데모



구현은 Observable이라고 하는 사이트의 노트북: Box-Muller transform 에 공개하고 있기 (위해)때문에, 브라우저상에서 농락하는 것이 가능.

위 함수에 의해 생성된 10000개의 샘플에 대해
  • 히스토그램
  • 정규 Q-Q 플롯

  • 을 그린 것을 이하에 나타낸다.

    히스토그램


    정규 Q-Q 플롯
    거의 직선상에 있는 것을 알 수 있다.

    좋은 웹페이지 즐겨찾기