Fisherの正確確率検定

1ページ 2ページ 3ページ

超幾何分布

P(X | x=12, m=15, n=14, k=18) 条件付き確率は、超幾何分布から特定の成功数が抽出される確率を計算します。

上記の記事より

P(X=12)=$\dfrac{_{15}C_{12}\times_{14}C_{6}}{_{29}C_{18}}$=0.03949341

Rを使用したら、以下のようになります

R
choose(15, 12)*choose(14, 6)/choose(29, 18)
> choose(15, 12)*choose(14, 6)/choose(29, 18)
[1] 0.03949341

Fisherの正確検定のp値の求め方

Rの関数を使用して、P(X | x=12, m=15, n=14, k=18) を求めます。dhyperは超幾何分布の確率質量を求める関数です(”d”は通常 “density” を意味しますが、ここでは離散分布の確率質量を指します)。

dhyper関数のパラメータ説明
 x : 成功が観測された回数(”severe” and “yes” の数)
 m : 母集団における成功の数(”severe” の数)
 n : 母集団における失敗の数(”mild” の数)
 k : 抽出回数、サンプルサイズ(”yes” の数)
*重度群に対する効果を検証するので、この例では、成功を”重度群”、また観察を”効果あり”として扱います。少し分かりにくいので、超幾何分布をご参照ください。

R
x <- 12  # Observed number of successes
m <- 15  # Total number of successes in the population
n <- 14  # Total number of failures in the population
k <- 18  # Size of the sample to be drawn
dhyper(x, m, n, k)
> dhyper(x, m, n, k)
[1] 0.03949341
片側検定(上側),alternative = “greater” のp値

再掲

> fisher.test(tab, alternative = "greater")

        Fisher's Exact Test for Count Data

data:  tab
p-value = 0.04601
alternative hypothesis: true odds ratio is greater than 1
95 percent confidence interval:
 1.029929      Inf
sample estimates:
odds ratio 
  5.003853

sumは集計結果を算出する関数です。

R
x <- c(12:15)
m <- 15
n <- 14
k <- 18
sum(dhyper(x, m, n, k))
> sum(dhyper(x, m, n, k))
[1] 0.04601384

P(X≧12) = P(X=12) + P(X=13) + P(X=14) + P(X=15)

X=12, 13, 14, 15 の確率を直接求めることになるので、なかなか大変です。なので、nが大きくなると昔は計算が大変だった思います。今はパソコンですぐに計算できます。

両側検定, alternative = “two.sided” のp値

再掲

R
fisher.test(tab, alternative = "two.sided")
> fisher.test(tab, alternative = "two.sided")

        Fisher's Exact Test for Count Data

data:  tab
p-value = 0.06043
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
  0.8163182 40.7244582
sample estimates:
odds ratio 
  5.003853 

dhyper関数は指定されたxの値での超幾何分布の確率を計算します。ここではxが15から4の範囲で、各xに対する確率を求めます。phyperは累積分布関数です。qパラメータで指定された各点での累積確率を計算し、その値以下の確率の総和を返します。lower.tail=Fオプションで、qパラメータで指定された値よりも大きな値の確率の総和を求めています。puはq = 14:3で計算されているため、各xの値に対してその次の数以上の成功を得る確率を求めています。また、plは、下側の確率を求めます。

R
x <- c(15:4)
m <- 15
n <- 14
k <- 18

d  <- dhyper(x = 15:4, m, n, k)
pu  <- phyper(q = 14:3, m, n, k, lower.tail=F)
pl  <- phyper(q = 15:4, m, n, k)
df <- data.frame(x, d, pu, pl)
round(df,6)

観測されたオッズ比の出現確率と、それよりも低い確率を合計します。 周辺合計を固定して、セルの値を再配分して組合せを求めるます。黄色ハイライト部分の合計がfisher.testの両側検定のp値。

0.046014 + 0.014419 = 0.060433

R
d1 <- d[1:4]
d2 <- d[10:12]
sum(d1, d2)
> d1 <- d[1:4]
> d2 <- d[10:12]
> sum(d1, d2)
[1] 0.06043294

ここでは、両側検定と片側検定の累積確率の位置が同じなっていますが、以下のような例になるとズレが生じるので注意が必要です。

累積確率と異なる値になる場合

R
tab2 <- matrix(c(7, 2, 8, 10), 2, 2)
tab2
> tab2
     [,1] [,2]
[1,]    7    8
[2,]    2   10
R
x <- 7  # Observed number of successes
m <- 15  # Total number of successes in the population
n <- 12  # Total number of failures in the population
k <- 9  # Size of the sample to be drawn
dhyper(x, m, n, k)
> dhyper(x, m, n, k)
[1] 0.09061785
R
fisher.test(tab2, alternative = "two.sided")$p.value
> fisher.test(tab2, alternative = "two.sided")$p.value
[1] 0.2172387
R
X <- c(9:0)
m <- 15
n <- 12
k <- 9

d  <- dhyper(x = 9:0, m, n, k)
pu  <- phyper(q = 8:-1, m, n, k, lower.tail=F)
pl  <- phyper(q = 9:0, m, n, k)
df2 <- data.frame(X, d, pu, pl)
round(df2,6)

tabの例では確率と累積確率のXが同じ値になるのですが、このように異なる場合もあるので注意が必要です。

> 0.001068+0.016476+0.090618+0.089703+0.017743+0.001584+0.000047
[1] 0.217239
> 0.108162+0.019375
[1] 0.127537

念のためにRで確認します

R
sum(df2[c(1:3, 7:10), 2])
df2[3, 3] + df2[8, 4]
> sum(df2[c(1:3, 7:10), 2])
[1] 0.2172387
> df2[3, 3] + df2[8, 4]
[1] 0.1275362

黒木玄様(@genkuroki)よりご助言いただき、サンプルも使用させていただきました。ありがとうございました。

コメント欄 『間違い』や『分かりにくい部分』などのご意見もお寄せください

タイトルとURLをコピーしました