マン・ホイットニーのU検定について
- 独立2群間の代表値の差の検定
- 2群間の平均値が独立であり(データに対応がない)、かつ正規分布が仮定できない(ノンパラメトリック)場合に用いる。下記図参照。
- ウィルコクソンの順位和検定と同様の結論が得られる。
- 順序尺度に対応している。
- 各群のサンプル数は一致しなくてよい。
コード
import numpy as np
from scipy import stats
import seaborn as sns
#用いるデータ
A = np.array([1.83, 1.50, 1.62, 2.48, 1.68, 1.88, 1.55, 3.06, 1.30, 2.01, 3.11])
B = np.array([0.88, 0.65, 0.60, 1.05, 1.06, 1.29, 1.06, 2.14, 1.29])
#試しにバイオリンプロットを作成
sns.violinplot(x=['A' for i in range(len(A))]+['B' for i in range(len(B))],
y=np.concatenate([A, B]))
# 有意水準を0.05、帰無仮説を「2群間の代表値に差がないこと」とする。
result = stats.mannwhitneyu(A,B,alternative='two-sided')
print('p-value:',round(result.pvalue,5))
# >>> p-value: 0.00183
結果、p < 0.05なので、帰無仮説は棄却され2群の代表値には差があるといえる。
バイオリンプロットはこんな感じ
検定の方法(詳細)
手順
- 仮説を設定する。
帰無仮説(Ho):「2群間に差がない」と仮定する。
対立仮説(H1):「2群間に差がある」と仮定する。 - 有意水準 $\alpha$ を設定する。
- 統計量 $U$ を算出する。
- 標本サイズに応じて、 $p$ 値を算出する。
4-a. 比較したい標本の標本サイズがどちらも20以下の時:Mann-Whitner検定表から算出
4-b. どちらかの標本サイズが20より大きい時:正規分布表から算出 - p値と有意水準から帰無仮説の棄却可否を判断する。
P ≧ α の時:帰無仮説は棄却できない。
P < α の時:帰無仮説を棄却する。(=2群に有意差あり)
統計量Uの求め方
- 標本サイズが小さい方を標本A、もう一方を標本Bとする。
- 標本Aの各データについて、標本Bの中でそれよりも大きいをもつデータの数の総和をUとする。
(もし両群に同じ値があるなら、「相手よりわずかに値が大きい場合」と「相手よりわずかに値が小さい場合」を想定してその平均を算出する)
計算コード
比較したい標本の標本サイズがどちらも20以下の時
#下記のデータを利用する。
A = np.array([6, 10, 13, 15, 18, 20])
B = np.array([2, 3, 6, 8, 9, 12, 16, 17])
#Uを求める
num_bigger_value = []
for i in A:
# i よりも大きい値がの個数
bigger_temp = len(np.where(B>i)[0])
# i と同じ値の個数(平均をとるので2で割る)
equal_temp = len(np.where(B==i)[0]) / 2
num_bigger_value.append(bigger_temp + equal_temp)
U = np.array(num_bigger_value).sum()
print('U-value:',U)
# >>> U-value: 12.5
それぞれの標本サイズ n1=6, n2=8、p<0.05としてMann-Whitney検定表(両側検定表)を参照すると、U値の下限有意点は8となり、計算したU値(12.5)はこれよりも大きい。
よって、P≧0.05となり帰無仮説を棄却できない。(「2群に有意差がある」と言えない)
比較したい標本の標本サイズがのどちらかが20以上の時
統計量Uを計算する。
A = np.array([50, 49, 49, 47, 45, 45, 43, 43, 43, 41, 38, 37, 36, 35, 34, 33, 33, 31, 31, 30])
B = np.array([48, 48, 46, 44, 42, 42, 42, 41, 41, 36, 34, 32, 30, 30, 29, 28, 28, 28, 26, 25, 24, 22])
#Uを求める
num_bigger_value = []
for i in A:
bigger_temp = len(np.where(B>i)[0])
equal_temp = len(np.where(B==i)[0]) / 2
num_bigger_value.append(bigger_temp + equal_temp)
U = np.array(num_bigger_value).sum()
print('U-value:',U)
# >>> U-value: 135.0
次の式を用いて、平均値 $\mu_u$、標準偏差$\sigma_u$、$z$ 値を求める。
(この式ではUは近似的に正規分布となる)
$$ \mu_u = \frac{n_1n_2}{2} $$
$$ \sigma_u = \frac{n_1n_2(n_1+n_2+1)}{12} $$
$$ z = \frac{U-\mu}{\sigma} $$
n1 = len(A)
n2 = len(B)
#平均値
mu = (n1 * n2)/2
print('平均値:', mu)
#標準偏差
sigma = np.sqrt(n1 * n2 * (n1 + n2 + 1)/12)
print('標準偏差:', round(sigma,2))
z = abs((U - mu)/sigma)
print('z:',round(z,3))
"""output
平均値: 220.0
標準偏差: 39.71
z: 2.141
"""
計算したZ値より、標準正規分布表から確率Pを求めると、P = 0.03236<0.05 となる。
P<0.05なので帰無仮説は棄却、対立仮説が採用される。(「2群に有意差がある」といえる)
参考
リンク
リンク