Wilcoxon検定(Wilcoxonの符号順位検定、Wilcoxonの順位和検定、Mann-WhitneyのU検定)

Wilcoxon検定とは?

Wilcoxon検定は多重比較・ノンパラメトリック検定の1種です。

ノンパラメトリック検定は名前をよく混合してしまいますが、以下のようにまとめられます。

検定名英語名パラメトリック?対応コメント
ウィルコクソンの符号順位検定Wilcoxon signed-rank testノンパラメトリック対応あり
ウィルコクソンの順位和検定Wilcoxon rank sum testノンパラメトリック対応なしこの2つは同じ
マン・ホイットニーのU検定Mann-Whitney U testノンパラメトリック対応なし

例題 - データ

RのSleepデータを使用します。

10人の患者に対して、2種類の薬を使用し、対照薬使用時との睡眠時間の差分を算出したデータです。

#!/usr/bin/env Rscript
data(sleep)
sleep
   extra group ID
1    0.7     1  1
2   -1.6     1  2
3   -0.2     1  3
4   -1.2     1  4
5   -0.1     1  5
6    3.4     1  6
7    3.7     1  7
8    0.8     1  8
9    0.0     1  9
10   2.0     1 10
11   1.9     2  1
12   0.8     2  2
13   1.1     2  3
14   0.1     2  4
15  -0.1     2  5
16   4.4     2  6
17   5.5     2  7
18   1.6     2  8
19   4.6     2  9
20   3.4     2 10

例題 - 可視化

以下のコードによって可視化します。

import pandas as pd
import matplotlib.pylab as plt

group1 = [0.7, -1.6, -0.2, -1.2, -0.1, 3.4, 3.7, 0.8, 0.0, 2.0]
group2 = [1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4]

df = pd.DataFrame({
    "group1": group1,
    "group2": group2
})

# 棒グラフ(対応がある場合はこの可視化)
df.plot(kind="bar")
plt.savefig("plt.bar.sleep.png")

# 箱ひげ図(対応がない場合はこの可視化)
df.plot(kind="box", widths=0.66)
plt.savefig("plt.box.sleep.png")

【棒グラフ】

Wilcoxon検定(Wilcoxonの符号順位検定、Wilcoxonの順位和検定、Mann-WhitneyのU検定)

【箱ひげ図】

Wilcoxon検定(Wilcoxonの符号順位検定、Wilcoxonの順位和検定、Mann-WhitneyのU検定)

パッと可視化すると、group2の方が睡眠時間の増加が大きいように見えます。

Group1と2の間で睡眠時間の増加に有意差があるかををWilcoxonの符号順位検定、またはWilcoxonの順位和検定にて計算します。


ソースコード

# Pythonでウィルコクソンの符号順位検定

Pythonの場合、Scipyのscipy.stats.wilcoxon()を使用します(公式リファレンス)。

Python環境構築についてはコチラを参照

#!/usr/bin/env python
# Scipyのバージョンが1.5.0より大きいかによって一部挙動が代わります。
# ここでは、現状のGoogleColabに従い、1.4.1版の結果を記載します。
import sys
import scipy
import scipy.stats as st
print(f"Python {sys.version}")      # 3.7.10
print(f"Scipy {scipy.__version__}") # 1.4.1

group1 = [0.7, -1.6, -0.2, -1.2, -0.1, 3.4, 3.7, 0.8, 0.0, 2.0]
group2 = [1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4]

p_value_wilc = st.wilcoxon(group1, group2, alternative="two-sided").pvalue
print(p_value_wilc)  # => 0.007632441648205508

グラフでの見た目と同様に有意差がついていることがわかります。


# ウィルコクソンの順位和検定・マンホイットニーのU検定(Python)

両側検定を目的としてウィルコクソンの順位和検定を行う際は、alternative="two-sided"を指定する必要がある。

このオプションを指定しないと有利な方向へ片側検定を行ってしまうため。

#!/usr/bin/env python
import sys
import scipy
import scipy.stats as st
print(f"Scipy {scipy.__version__}")
# => 1.4.1

group1 = [0.7, -1.6, -0.2, -1.2, -0.1, 3.4, 3.7, 0.8, 0.0, 2.0]
group2 = [1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4]

p_value_manh = st.mannwhitneyu(group1, group2, alternative="two-sided").pvalue
print(p_value_manh)  # => 0.06932757543362658

# Rでウィルコクソンの符号順位検定

RとPythonでは少し結果が違います。これはタイ値の扱いが関わってきます。次の節にて解説します。

#!/usr/bin/env Rscript
group1 = c(0.7, -1.6, -0.2, -1.2, -0.1, 3.4, 3.7, 0.8, 0.0, 2.0)
group2 = c(1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4)

p_value_wilcoxon = wilcox.test(group1, group2, paired=T)$p.value
print(p_value_wilcoxon) # => 0.009090698

# Rでウィルコクソンの順位和検定・マンホイットニーのU検定

#!/usr/bin/env Rscript
group1 = c(0.7, -1.6, -0.2, -1.2, -0.1, 3.4, 3.7, 0.8, 0.0, 2.0)
group2 = c(1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4)

p_value_mannwhitney = wilcox.test(group1, group2)$p.value
print(p_value_mannwhitney) # => 0.06932758

その他

# ウィルコクソンの符号順位検定におけるオプションについて

RPython(Scipy<1.5.0)Python (Scipy≧1.5.0)
連続性補正行う
(correct = T)
行わない
(correction = False)
行わない
(correction = False)
正確検定自動で判定
(「タイ値がない」かつ「サンプル数が50未満」の場合正確検定を行う)
できない自動で判定
(「タイ値がない」かつ「サンプル数が26未満」の場合正確検定を行う)
比較する2群間で同じ値の扱い破棄する
(オプションで選択できない)
破棄する
(zero_method='wilcox')
破棄する
(zero_method='wilcox')

参考:Scipy1.5.0リリースノート

ウィルコクソンの符号順位検定においては複数のオプションがあり、上記を調整するとRとPythonの結果を一致させることができる。