適合度の検定についても,フィッシャーの検定と同じように考えれば正確な検定ができます。
ここでは簡単のために,5つのカテゴリーに対する観察値が与えられたとき,各カテゴリーの理論比が一様であるかどうか検定するものとします。
BEGIN {
cat = 5 # カテゴリー数
o[0] = 1 # 5つのカテゴリーにおける観察数
o[1] = 1
o[2] = 3
o[3] = 1
o[4] = 0
e[0] = 2.54 # 5つのカテゴリーにおける理論値
e[1] = 1.62
e[2] = 0.46
e[3] = 1.15
e[4] = 0.23
for (i = 0; i < cat; i++) {
N += o[i]
}
x0 = calcX(o[0], o[1], o[2], o[3], o[4]) # 引数は5つのカテゴリーにおける観察数
print "観察値に対するカイ二乗値 =", x0
for (i1 = 0; i1 <= N; i1++)
for (i2 = 0; i2 <= N; i2++)
for (i3 = 0; i3 <= N; i3++)
for (i4 = 0; i4 <= N; i4++) {
i5 = N-i1-i2-i3-i4
if (i5 < 0) break
x2 = calcX(i1, i2, i3, i4, i5)
w = way(i1, i2, i3, i4, i5) \
*(e[0]/N)^i1*(e[1]/N)^i2*(e[2]/N)^i3 \
*(e[3]/N)^i4*(e[4]/N)^i5
wt += w # これは不要ですが検算のために残しておきます
if (x2 >= x0) {
w2 += w
}
}
print "条件を満たす確率 p 値 = ", w2
print "全ての場合の確率 = ", wt
}
function calcX(i1, i2, i3, i4, i5) { # 任意の分布表に対するカイ二乗値
return calc1(i1, e[0])+calc1(i2, e[1]) \
+calc1(i3, e[2])+calc1(i4, e[3])+calc1(i5, e[4])
}
function calc1(o, e) { # 個々のセルのカイ二乗値
return (o-e)^2/e
}
function way(i1, i2, i3, i4, i5) { # 超幾何分布の場合の数
return factorial(i1+i2+i3+i4+i5)/ \
(factorial(i1)*factorial(i2)*factorial(i3) \
*factorial(i4)*factorial(i5))
}
function factorial(n, i, retv){ # 階乗の計算
retv = 1
for (i = 1; i <= n; i++)
retv *= i
return retv
}