scipy.stats: 一元配置分散分析 -- Welch の方法
scipy.stats の f_oneway
は,各群の母分散が等しいと仮定する,古典的な検定である。
R では,等分散を仮定しない Welch の方法がデフォルトであるが,Python ではどのライブラリにもない。
じゃあ,作っちゃお。
関数定義
import numpy as np
from scipy.stats import f
def oneway_ANOVA(*x, equal_var=False):
k = len(x)
ni = np.array([len(y) for y in x])
mi = np.array([np.mean(y) for y in x])
vi = np.array([np.var(y, ddof=1) for y in x])
if equal_var:
n = sum(ni)
mean_x = sum(ni * mi) / n
df1, df2 = k - 1, n - k
F = sum(ni * (mi - mean_x)**2) / df1 / (sum((ni - 1) * vi) / df2)
else:
wi = ni / vi
sum_wi = sum(wi)
tmp = sum((1 - wi / sum_wi)**2 / (ni - 1)) / (k**2 - 1)
m = sum(wi * mi) / sum_wi
df1, df2 = k - 1, 1 / (3 * tmp)
F = sum(wi * (mi - m)**2) / (df1 * (1 + 2 * (k - 2) * tmp))
return F, f.sf(F, df1, df2)
使用例
引数に各群の配列,リストを列挙すればよい。
デフォルトで Welch の方法による検定を行う。
戻り値は,検定統計量 $F$ 値と $p$ 値のタプル。
a = [0.0571, 0.0813, 0.0831, 0.0976, 0.0817, 0.0859, 0.0735, 0.0659, 0.0923, 0.0836]
b = [0.0873, 0.0662, 0.0672, 0.0819, 0.0749, 0.0649, 0.0835, 0.0725]
c = [0.0974, 0.1352, 0.0817, 0.1016, 0.0968, 0.1064, 0.105]
d = [0.1033, 0.0915, 0.0781, 0.0685, 0.0677, 0.0697, 0.0764, 0.0689]
e = [0.0703, 0.1026, 0.0956, 0.0973, 0.1039, 0.1045]
oneway_ANOVA(a, b, c, d, e) # (5.6644794946224915, 0.005079648192270907)
(5.6644794946224915, 0.005079648192270907)
equal_var=True
オプションは指定しないようにしよう。
oneway_ANOVA(a, b, c, d, e, equal_var=True) # (7.121019471642447, 0.0002812242314534544)
(7.121019471642447, 0.0002812242314534544)
以下は読む必要なし。
「まず,等分散性の検定をして,その結果により(等分散性を仮定する)一元配置分散分析を採用するか,クラスカル・ウォリス検定を行うか決める」などと,古臭いことを書いてある教科書,サイトがあっても,信じてはいけない。
常に,等分散性を仮定しない Welch の方法による一元配置分散分析を行えばよい。
from scipy.stats import f_oneway
f_oneway(a, b, c, d, e)
F_onewayResult(statistic=7.121019471642447, pvalue=0.0002812242314534544)