Fisherの検定

[2023-01-05] SciPy 1.10.0 が出たのでそれに合わせて修正しました。

RでFisherの検定をするには fisher.test() を使います。行列は縦に読んで、行数(または列数)を指定します:

> fisher.test(matrix(c(3, 1, 2, 4), nrow=2))

	Fisher's Exact Test for Count Data

data:  matrix(c(3, 1, 2, 4), nrow = 2)
p-value = 0.5238
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
   0.218046 390.562917
sample estimates:
odds ratio 
  4.918388 

Pythonでは scipy.stats.fisher_exact を使います。行列は行ごとに与えます:

from scipy import stats

stats.fisher_exact([[3, 2], [1, 4]])
SignificanceResult(statistic=6.0, pvalue=0.5238095238095238)

返ってくるのはオッズ比と p 値です。これらを別々に取り出して変数に代入するには

oddsratio, pvalue = stats.fisher_exact([[3, 2], [1, 4]])

のようにします。Rの fisher.test() と違って、こちらの [[a, b], [c, d]] のオッズ比は (a/b)/(c/d) と同じです。オッズ比の2通りの求め方については2×2の表,オッズ比,相対危険度もご覧ください。オッズ比を報告する際には (a/b)/(c/d) のほうでいいと思います。

fisher_exact() は残念ながら2×2行列しか扱えません。より大きな行列を扱うには FisherExactfexact があるようですが、rpy2 等を使ってPythonからRを呼び出すのがいいかもしれません。

Fisherの検定がいいか、単純なカイ2乗検定がいいか(その場合、連続性の補正はするべきか)といった議論はいろいろあります。カイ2乗検定はPythonでは次のようにして行います(補正なしの場合):

stats.chi2_contingency([[3, 2], [1, 4]], correction=False)
Chi2ContingencyResult(statistic=1.6666666666666665, pvalue=0.1967056024589432, dof=1, expected_freq=array([[2., 3.],
       [2., 3.]]))