分布に従った乱数生成関数を書きたい

概要

ある分布に従う乱数をプログラム上で生成するときに必要な技術についてまとめます.分布の生成においては一様分布の乱数生成ができることを前提としています.
Facebookシェア Twitterツイート LINEで送る このエントリーをはてなブックマークに追加
この章を学ぶ前に必要な知識
0
条件
  • 一様乱数が必要
  • 確率分布の分布関数がわかっている
効果
  • 乱数を生成することができるようになる

解 説

ある分布に従った乱数生成関数をプログラムで書く方法についてまとめます. 多くの有名な分布に関してはそれぞれやり方が求められていますが、自身が用意した確率分布に対してその分布を生成するプログラムを書きたいときに参照してください. 主な方法は二つあります. ・本当に一様確率のもとでその事象を起こしてみる. ・分布関数の逆関数を求める になります.
分布に従った乱数生成関数を書きたい

1.本当にやってみて乱数を作る

これは愚直な方法で処理時間も一定にはなりませんが、直感的にプログラムをかけるケースがあります. それは確率分布の定義に基づいて実際に試行してみる方法です. 例えばわかりやすいケースは幾何分布になります. 幾何分布に従う乱数を生成したい場合は、幾何分布がそもそも確率pで起こる事象がn回目に初めて起こるときの確率であったことを思い出してそれを実際にやってみればいいのです.
本当にやってみて乱数を作る
C++
1
2
3
4
5
6
7
int geo_rand(double p){
    int n = 1;
    while(rand() > p){
      n++;
    }
    return n;
}
幾何分布に従う乱数の生成を行う関数 rand()は0~1の間の一様乱数. ここでは実際に初めて一様乱数が決められた確率pを超えるまでnをインクリメントしています.

2.分布関数の逆関数を求めて乱数を生成する

もう一つの正当な方法の一つは逆関数を求めて乱数を生成する方法です. 累積分布関数は密度分布を積分することによって求めます. 累積分布関数を作るとその値は単調増加していることがわかり、また密度関数の値が大きいところで大きい傾斜になっていることがわかると思います. このときyの値を決めればそのxの値が得られることになりますが、急な勾配であるところのほうがその近辺の乱数が多く得られることを示します.すなわち適切にそのxの値になる確率が高くなるようになっているのです. ワイブル分布やロジスティック分布などに関してはこの方法によって求めることができます.
分布関数の逆関数を求めて乱数生成
yの方向に一様乱数を取得した時に 対応するxは ・勾配が大きいところでxが多くなりやすい ・勾配が小さいところでxが少なくなりやすい ことが直感的にわかるかと思います.
この章を学んで新たに学べる
Comments

Reasons
>>隠す