Binomial sampling with nodejs


nodejsで二項分布のサンプリングを行いたかったので、nodeで書いてみた。

二項分布はベルヌーイ分布に従うサンプリングを何度も行い、その総和をとればいい。
まずベルヌーイ分布に従う確率変数を得るコード。

ベルヌーイ分布

function bernouli(p) {
    if (Math.random() <= p) {
        return 1;
    } else {
        return 0;
    }
}

ベルヌーイ分布は以下の式に従う離散確率分布。そのサンプリングを行うには、一様乱数からとってきた値が確率pより大きいかどうかを見ればいい。

二項分布

二項分布はこのベルヌーイ分布のサンプリングをn回行ったときに1となる回数を表現する確率分布。
つまりn回繰り返してその総和をとってあげればいい。

function binomial(n, p) {
    var x = 0;
    for (var i = 0; i < n; i++) {
        x += bernouli(p);
    }
    return x;
}

これで確率分布B(n,p)に従う分布からサンプリングできることになる。
これでいくつか試してみた。

Try

まずはp=0.5の確率、つまり表か裏かがでるような状況で10000回の試行を繰り返す。
そのときに表がでるときの回数の分布は上のプログラムを使って以下のようになった。

普通に考えて5回くらいでるのが一番多そうで、裏がでる確率と同じ確率なので大体左右対称になる。

次にp=0.17にしてみる。サイコロで1の目がでる確率だ。(別に1じゃなくてもいいけれど)
これで同じように10000回試行してみると

やっぱりだいたい1.7回くらいでるのが一番多くなる感じがする。これを見ると10回振って7回以上1が出るなんてことはほとんどないことが分かる。なかなかおもしろい。

npm

コード自体は小さいけれど、また使う機会がありそうなのでnpm moduleにしておいた

binomial-sampling

よかったら使ってください。