一定の確率で何かが起きるメソッドが、ホントにその確率で起きているかテストしたくなったので書いてみた。統計確率とか分からんので、いろいろと調べながらなので全く自信ない! まるっと間違えてる可能性あるw ツッコミ大歓迎。
使い方
dice.t
use Test::ChiSquare;
chisquare_ok( [[23, 20], [16, 20], [21, 20], [19, 20], [13, 20], [28, 20]], 0.05, 'dice' );
done_testing();
サイコロを121回振っていたので修正しました >_<
chisquare_ok の第一引数は、 [観測値, 期待値]
の配列。
上の例はさいころを120回振ったときのそれぞれの目の観測値と期待値を配列にしてる。120回振ったらそれぞれの目の期待値は一律20だよね?
第2引数は有意水準。
内部の動き
- カイ二乗検定の式に従ってカイ二乗値を求める
- 項目数 - 1 で自由度 k を求める。今回は項目数が6なので5。
- カイ二乗分布の式で、自由度 k と有意水準から値を求める
- 今回は 自由度 5 で 有意水準が 5% なので、11.07
- 1 で求めたカイ二乗値が 3 で求めた値より小さければ ok。(観測値は期待値に近しいと言える)
実際に、 rand() つかってさいころ作って試してみたけど何度か test が fail した。さいころを振る回数(試行回数)が少ないのかも。
参考
- カイ二乗検定 (wikipedia)
- ランダムに振る舞う機能を JUnit する #渋谷Java 第3回
-
Statistics::Distributions (CPAN)
- 統計で使う公式っぽいのがたくさん入ってるっぽい
- カイ二乗分布は chisqrdistr で求められる……と思う。
- そもそもここが間違えていたら残念なことにw
そもそもカイ二乗を求めるっぽいその名の通りのモジュール ( Statistics::ChiSquare ) もあったんだけど、カイ二乗分布の表を二次元配列で持っていたりとか、返って来る結果がメッセージだったりとかでスルーした。