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개의 샘플에 대해
$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개의 샘플에 대해
// 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);
}
구현은 Observable이라고 하는 사이트의 노트북: Box-Muller transform 에 공개하고 있기 (위해)때문에, 브라우저상에서 농락하는 것이 가능.
위 함수에 의해 생성된 10000개의 샘플에 대해
을 그린 것을 이하에 나타낸다.
히스토그램
정규 Q-Q 플롯
거의 직선상에 있는 것을 알 수 있다.
Reference
이 문제에 관하여(JavaScript에서 Box-Muller 방법에 의한 정규 분포로부터의 샘플링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sw1227/items/8f5da8c22d907352e4c9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)