Rの符号検定とWilcoxonの符号付き順位検定の符号検定をPythonにしたものです。
10人の患者にある睡眠薬を飲ませたところ,睡眠時間がそれぞれ次の時間だけ増えました (Arthur R. Cushny and A. Roy Peebles, The Journal of Physiology 32, 501-510 (1905)):
1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4
つまり,10個のうち負の値は1個だけで,残り9個は正です。正・負の符号の付き方は全部で $2^{10} = 1024$ 通りあり,そのうちで
等々のように場合分けできます。すべての場合を合計すると,当然ですが $2^{10} = 1024$ になります。
もし正になる確率と負になる確率が同じなら,
となるはずです。実際のデータは10個のうち一つだけ負ですので,このようになる確率と,もっと極端な(すべて正になる)確率を合計すれば,10/1024 + 1/1024 = 11/1024 です。逆に,すべて負になる確率と,一つだけ正になる確率を合計すれば,やはり 10/1024 + 1/1024 = 11/1024 です。そこで,10個のうち1個以下の符号が他と異なる確率は,22/1024 で,$p$ 値は約0.02です。つまり,偶然では50回に1回しか起きない事象です。
このような検定法を符号検定(sign test)といいます。
符号検定では,差が 0 のデータは外して考えます。
一般に,0でない数が n 個あって,そのうち m 個が正(または負)であるなら,scipy.stats.binomtest で符号検定できます。例えば上の例の場合は
import numpy as np from scipy import stats x = np.array([1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4]) stats.binomtest(np.sum(x > 0), np.sum(x != 0))
BinomTestResult(k=1.0, n=10.0, alternative='two-sided', statistic=0.1, pvalue=0.021484375)
で,$p = 0.02148$ となります。