符号検定

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$ となります。