$t$ 検定

はじめに

平均値の検定をする場合、高校では正規分布による検定しか扱いません。例えば、母集団が分散 1 の正規分布だということはわかっているけれども、平均値がわかりません。実際にデータを3個とったところ、値は 1、2、3 でした。平均値が 0 であるという帰無仮説は棄却できるでしょうか。

1、2、3 の平均値は 2 です。分散 1 を仮定すると、3個の平均値の分散は 1/3 です。母集団の平均が 0 だとすると、3個の平均値は平均 0、分散 1/3 の正規分布をするはずです。分散 1/3 ということは、標準偏差 $\sqrt{1/3} \approx 0.577$ です。1、2、3 の平均値 2 は、この標準偏差の $2 / \sqrt{1/3} \approx 3.46$ 倍も離れています。標準偏差の 1.96 倍以上離れる確率は 0.05 ですから、このようなことが起きる確率は 0.05 より小さく、帰無仮説は水準 0.05 で棄却できます。

この論理そのものも難しいですが、平均がわからないのに分散だけわかっているというのは何とも不思議です。現場では平均がわからなければ分散もわからないのが一般的です。

平均も分散もわからないけれども、中心極限定理から、サンプルの平均値はほぼ正規分布をすることがわかっているという一般の場合に、サンプルの平均値が 0 かどうか、あるいは2つのサンプルの平均値が等しいかどうかを検定するのが $t$ 検定です。

こういった統計計算をするための標準的なツールは R ですが、やっぱり Python でも同じことをしたいですよね。Python では SciPy を使うのが一般的でしたが、あまり便利ではありません。以下では Pingouin という新しめのパッケージを使っています。pip install pingouin でインストールできます。念のため SciPy による方法も書いておきました(pip install scipy)。なお、$t$ 分布の密度関数などを求めるには SciPy の scipy.stats.t を使います。

1標本の $t$ 検定

10人の患者にある睡眠薬を飲ませたところ、睡眠時間がそれぞれ次の時間だけ増えました(Arthur R. Cushny and A. Roy Peebles, The Journal of Physiology 32, 501-510 (1905)):

x = [1.9, 0.8, 1.1, 0.1, -0.1, 4.4, 5.5, 1.6, 4.6, 3.4]

この睡眠薬は効果があるといえるでしょうか。

帰無仮説は、効果はない(上の x の平均値は 0 である)です。10個の平均値は中心極限定理から正規分布で近似できそうですが、分散については何もわかりません。

こういうときに使うのが、1標本の $t$ 検定です(関数の名前は2標本と同じですが、2番目の引数に 0 を指定します)。

import pingouin as pg

pg.ttest(x, 0)
               T  dof alternative     p-val        CI95%   cohen-d    BF10     power
T-test  3.679916    9   two-sided  0.005076  [0.9, 3.76]  1.163692  10.715  0.904364

$p$ 値は 0.005 程度ですので、効果があると言えそうです。睡眠時間の増加の 95% 信頼区間は [0.90, 3.76] 時間です。

2標本の $t$ 検定(対応がない場合)

2組の患者たちに痛みのレベルを報告してもらったところ,次のような結果を得ました (T. Lumley, Biometrics 52, 354-361 (1996))。

x = [1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 1, 1]
y = [3, 3, 4, 3, 1, 2, 3, 1, 1, 5, 4]

これらの平均値に差があるといえるでしょうか。

このような問題では、両群の分散が等しいと仮定しない $t$ 検定(Welch の検定)を使うのが推奨です(R のデフォルトはそうなっています)。

pg.ttest(x, y, correction=True)
               T        dof alternative     p-val           CI95%   cohen-d   BF10     power
T-test -2.948615  15.915569   two-sided  0.009479  [-2.36, -0.38]  1.255397  6.556  0.846951

$p$ 値は 0.009 程度で、両群の平均値に差があると言えそうです。両群の平均値の差の 95% 信頼区間は [-2.36, -0.38] です。

pg.ttest() のデフォルトは、両群のサイズ(個数)が等しければ分散が等しいと仮定し、そうでなければ Welch の方法を用います。オプション correction=True で常に Welch の方法を用います。

2標本の $t$ 検定(対応がある場合)

5人の成績が 1、2、3、4、5 だったのが、勉強したのでそれぞれ 3、5、4、7、6 になりました。勉強によって成績が伸びたと言えるでしょうか?

pg.ttest([1,2,3,4,5], [3,5,4,7,6], paired=True)
               T  dof alternative     p-val           CI95%   cohen-d   BF10     power
T-test -4.472136    4   two-sided  0.011056  [-3.24, -0.76]  1.264911  6.555  0.571609

$p$ 値は 0.01 ほどなので、成績が伸びたと言えそうです。

実は、これは一人一人の成績の伸びを1標本の $t$ 検定したのと本質的に同じです:

pg.ttest([2, 3, 1, 3, 1], 0)
               T  dof alternative     p-val         CI95%  cohen-d   BF10     power
T-test  4.472136    4   two-sided  0.011056  [0.76, 3.24]      2.0  6.555  0.908885