Wilcoxonの符号付き順位検定

Rの符号検定とWilcoxonの符号付き順位検定の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

このデータで,絶対値の順序関係

\[ 0.1 = 0.1 < 0.8 < 1.1 < 1.6 < 1.9 < 3.4 < 4.4 < 4.6 < 5.5 \]

に意味があるのであれば,順位(同順位があれば順位の平均をとります)

\[ 1.5, 1.5, 3, 4, 5, 6, 7, 8, 9, 10 \]

に変換してから,符号を戻して,合計した値

\[ -1.5 + 1.5 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 52 \]

を考えます。この符号の付け方は $2^{10} = 1024$ 通りありますが,順位和が 52 以上になるのは全部 $+$ にした場合と二つの $1.5$ のどちらかに $-$ を付けた場合の3通りです。同様に,順位和が $-52$ 以下になるのも3通りですので,偶然で順位和が $\pm 52$ またはそれより極端な値になる確率は $p = 6/1024 = 0.005859$ です。これがWilcoxon(ウィルコクソン)の符号付き順位検定(符号付き順位和検定,Wilcoxon signed-rank test)です。

PythonでWilcoxonの符号つき順位検定をするには次のようにします。

from scipy.stats import wilcoxon

x = [1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4]
wilcoxon(x, method="exact")   # or "asymptotic"
WilcoxonResult(statistic=np.float64(1.5), pvalue=np.float64(0.005859375))

$p = 0.005859$ が得られました。

method="exact" が遅い場合は method="asymptotic" にします。

Brunner-Munzel検定で紹介した permutations-stats パッケージを使ってもできます。あらかじめ pip install permutations-stats しておきます。こちらの方は2群を比較する場合が想定されているようで、1群の場合は全部0の列を補います。

import numpy as np
from permutations_stats.permutations import repeated_permutation_test

x = [1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4]
y = [0] * len(x)

data = np.stack((x, y), axis=1)

repeated_permutation_test(data, test="wilcoxon")
PermutationsResults(statistic=52.0, pvalue=0.005859375, permutations=1024, test='wilcoxon', alternative='TWO_SIDED', method='exact')