Fisher's exact probability test に対して「フィッシャーの直接確率法」という訳語を
(1) 最初に与えたのは誰でしょう?
(2) それでいいと思いますか?
文献調査結果を報告します。このスクリプトを使った例が別の所にあります。
普通にやったのでは,総ケース数があまりに大きいと計算できないので,階乗の log をベースにして計算を進め,最後にアンチログ(つまり exp)を取るというように工夫しています。このようにすると,乗除算が加減算になるのも都合がよい。
# Fisher.awk
BEGIN {
a = input("aの度数を入力してください...")
b = input("bの度数を入力してください...")
c = input("cの度数を入力してください...")
d = input("dの度数を入力してください...")
ab = a+b
cd = c+d
ac = a+c
bd = b+d
n = ab+cd
oa = a
for (i = 1; i <= n; i++) {
q[i] = q[i-1]+log(i)
}
x = q[ab]+q[cd]+q[ac]+q[bd]-q[n]
pu = 1
maxa = (ab <= ac) ? ab : ac
mina = ab-((ab <= bd) ? ab : bd)
adbc = a*d-b*c
printf "★ 分割表の生起確率 # 印は観察された分割表\n\n" \
" a b c d ad-bc 分割表の生起確率" \
" 累積確率1 累積確率2\n"
for (i = mina; i <= maxa; i++) {
b = ab-i
c = ac-i
d = bd-b
adbc1 = i*d-b*c
p = exp(x-(q[i]+q[b]+q[c]+q[d]))
pl += p; mk = " "
mark = (oa == i) ? "#" : " "
if (abs(adbc1) >= abs(adbc)) {
p2 += p
mk = "@"
}
printf "%c%4i%4i%4i%4i%9i %c %#15.12f %#15.12f %#15.12f\n",\
mark, i, b, c, d, adbc1, mk, p, pl, pu
pu -= p
}
printf "\nフィッシャーの正確確率検定(両側検定) p = %.12f\n" \
" (@ 印の付いた生起確率の合計。別法もある)\n", p2
}
function input(prompt, var) {
printf prompt > "/dev/stderr"
getline var < "/dev/stdin"
return var
}
# x の絶対値を求める
# 使用例: x = abs(-10.95)
function abs(x)
{
return (x < 0) ? -x : x
}