Ruby - 一様乱数の一様性検定(カイ2乗検定)!
Updated:
昨日は、一様乱数の一様性を「カイ2乗検定」で検定する C++ によるアルゴリズムを紹介しました。
今日は、同じアルゴリズムを Ruby で実現してみました。
カイ2乗検定の詳細については、昨日の記事等を参照してください。
実際、アルゴリズム的にはほとんど同じです。
以下、Ruby によるサンプルスクリプトです。
0. 前提条件
- Cygwin 1.7.15
- Ruby 1.9.3-p194
1. Ruby スクリプト作成
今回作成した Ruby ソースは以下のとおりです。
File: chi_2_rndnum.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#! /usr/local/bin/ruby
# *************************************
# 線形合同法による一様乱数の一様性検証
# *************************************
class Chi2Rndnum
A = 1103515245 # 乗数
C = 12345 # 加数
M = 2 ** 31 # 法
N = 1000 # 発生させる乱数の個数
M_MAX = 10 # 整数乱数の範囲
F = N / M_MAX.to_f # 期待値
S = 40.0 / F # ヒストグラム用スケール
def initialize
# 乱数の種の初期値
@r = 12345
# 件数格納用配列初期化
@hist = Array.new(M_MAX + 1, 0)
# カイ2乗検定初期値
@e = 0.0
end
# 一様乱数生成
def generate_rndnum
1.upto(N) do |i|
rank = rnd
@hist[rank] += 1
end
end
# 結果表示
def display
1.upto(M_MAX) do |i|
# 件数表示
printf("%3d:%3d ", i, @hist[i])
# ヒストグラム表示
0.upto(@hist[i] * S - 1) { |j| print "*" }
puts
# カイ2乗検定
@e = @e + (@hist[i] - F) * (@hist[i] - F) / F
end
# カイ2乗検定値表示
puts "χ2 = #{@e}"
end
private
# 1 ~ 10 の整数乱数
def rnd
# 0 ~ 2の31乗 未満の整数乱数
@r = (A * @r + C) % M
# 0 ~ 1 未満の実数乱数に 10 を乗じて 1 を加えることで
# 1 ~ 10 の整数乱数にする
return M_MAX * (@r / (M - 0.9)) + 1;
end
end
f __FILE__ == $0
begin
obj = Chi2Rndnum.new
obj.generate_rndnum
obj.display
rescue => e
puts "[例外発生] #{e}"
end
end
2. 実行
まず、実行権限を付与。
$ chmod +x chi_2_rndnum.rb
そして、実行。
$ ./chi2_rndnum.rb
1:105 ******************************************
2: 89 ***********************************
3:109 *******************************************
4: 99 ***************************************
5:100 ****************************************
6: 97 **************************************
7:103 *****************************************
8:116 **********************************************
9: 89 ***********************************
10: 93 *************************************
χ2 = 6.72
3. 判定
実行した結果が一様であるかどうかですが、ヒストグラムではそんなに大きなバラツキは確認できません。
そして、カイ2乗統計量は 6.72 という値になっています。
今回は 1 から 10 までの 10 個の整数で検証しましたので、カイ2乗検定でいうところの自由度が 9 ということになります。
統計関係書物等で「カイ2乗分布表」を調べてみると 、自由度 9、危険率(αパーセント点) 0.01 の値は 21.660 となっています。
明らかに 6.72 < 21.660 を満たしていますから、発生した乱数は危険率 1% で一様に分布していると判定できます。
乱数生成回数をもっと増やしたり、乱数生成時の定数を変更してみたりすると、もっと一様になるのではないでしょうか?
以上。
Comments