mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

Ruby - 一様乱数の一様性検定(カイ2乗検定)!

[ プログラミング, 数学 ] [ Ruby ]

こんばんは。

昨日は、一様乱数の一様性を「カイ2乗検定」で検定する C++ によるアルゴリズムを紹介しました。

今日は、同じアルゴリズムを Ruby で実現してみました。 カイ2乗検定の詳細については、昨日の記事等を参照してください。

実際、アルゴリズム的にはほとんど同じです。

以下、Ruby によるサンプルスクリプトです。

記録

0. 前提条件

  • Cygwin 1.7.15
  • Ruby 1.9.3-p194

1. Ruby スクリプト作成

今回作成した Ruby ソースは以下の通りです。 【 ファイル名: chi2_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
67
68
69
70
71
72
73
74
75
# -*- coding: utf-8 -*-
class Chi2Rndnum
  # 各種定数定義
  A = 1103515245  # 乗数
  C = 12345       # 加数
  M = 2 ** 31     # 法
  N = 1000        # 発生させる乱数の個数
  M_MAX = 10      # 整数乱数の範囲
  F = N / M_MAX.to_f  # 期待値
  S = 40.0 / F    # ヒストグラム用スケール

  # 計算クラス
  class Calc
    # コンストラクタ
    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

    # 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

    # 結果表示
    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
  end

  # メイン処理
  begin
    # 計算クラスインスタンス化
    obj_calc = Calc.new

    # 一様乱数生成
    obj_calc.generate_rndnum

    # 結果表示
    obj_calc.display
  rescue => e
    # エラーメッセージ
    puts "[例外発生] #{e}"
  end
end

2. 実行

実際に実行して検証してみる。

1
2
3
4
5
6
7
8
9
10
11
12
$ ruby 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

4. 判定

実行した結果が一様であるかどうかですが、ヒストグラムではそんなに大きなバラツキは確認できません。 そして、カイ2乗統計量は 6.72 という値になっています。

今回は 1 から 10 までの 10 個の整数で検証しましたので、カイ2乗検定でいうところの自由度が 9 ということになります。 統計関係書物等で「カイ2乗分布表」を調べてみると 、自由度 9、危険率(αパーセント点) 0.01 の値は 21.660 となっています。 明らかに 6.72 < 21.660 を満たしていますから、発生した乱数は危険率 1% で一様に分布していると判定できます。


乱数生成回数をもっと増やしたり、乱数生成時の定数を変更してみたりすると、もっと一様になるのではないでしょうか?

以上。

Comments