フィッシャーの検定     Last modified: May 15, 2002

 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
}


・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI