t検定を掘り下げる~後編~
こんにちは、ゆるです。前回の投稿から2週間空いてしまいました…。本業との兼ね合いや自分自身のインプットを続けると週1というのは中々ハードですね(完全に言い訳です)。
さて、t検定について過去2回にわたり扱ってきましたが今回の後編で終わります。前編からここまで、長い道のりを辿りましたが、ようやく本記事で2群の平均値の比較を行うt検定を扱います。生物系、医療統計、またほぼ全ての分野でも有意差を示すときのスタンダードになっているかと思います。
本記事は前編、中編の内容を踏まえているので、是非前編から読んで頂けると嬉しいです!
また本記事を執筆する上で、以下の書籍を参考にしました。
中編のおさらい
中編では1群の平均の検定(分散未知)を扱いました。中でも正規分布に従う標本について
という重要な性質に触れました。これにより
という形式の検定を構成しようとするとき、
とすればt分布をもとにした検定(=t検定)となります。この形式の検定は「平均がある特定の定数と等しいか」に興味がある場合なので、あまり馴染みがないかもしれませんが、実は生物学研究の中でもよく使われています。それが「対応のある2群のt検定」です。
対応のある2群の平均の検定
RやPythonなどでt検定する場合、"paired"といったようなオプションで対応ありかなしかを選択することがあるため、おそらく聞いたことある方も多いのではないでしょうか。以下のような場合になります。
これは2群の平均値の比較の検定になります。そして入会直後と半年後のそれぞれに関して平均を考え、2群の平均の差の検定を考えることもできますが、個人差を考えると人ごとの変化を考える方が合理的に思えます。つまり前後の差をAさんから表すと、$${-9, -5, -6, -4\text{ mg/dL}}$$となり、これが$${0\text{ mg/dL}}$$と等しいか否かという検定を行えばよいということになります。また今回、t検定を行うのでこの変化の値が正規分布に従うという仮定の下での検定となります。具体的な手順は、最初に差をとる部分以外は前回と同様なので、簡略になりますが以下の通りです。
変化前の標本を$${X_1, X_2,…, X_n}$$、変化後の標本を$${Y_1, Y_2,…, Y_n}$$とした時、それぞれの差$${Z_i = Y_i-X_i}$$をとり、$${Z_1, Z_2,…, Z_n}$$とし、$${Zi}$$が正規分布に従うと仮定する。
「前後で変化がない」ということが帰無仮説となるため、$${Zi}$$が従う分布について$${H_0: \mu=0}$$とする。
検定統計量を$${T(Z_1, Z_2, …, Z_n) = \frac{\overline{Z}-\mu}{\sqrt{\frac{V}{n}}}}$$とする。但し、$${V = \frac{1}{n-1}\sum_{i=1}^n{(Z_i-\overline{Z})^2}}$$である。このとき、$${H_0}$$下において$${T(Z_1, Z_2, …, Z_n)}$$が自由度$${n-1}$$の$${t}$$分布に従う。
$${T(Z_1, Z_2, …, Z_n)}$$に標本から得られた値を代入し、$${T}$$としたとき、自由度$${n-1}$$の$${t}$$分布において$${T}$$以上(or 以下)の値をとる確率の倍の値が$${p}$$値となり、有意判定する。
この検定の構築方法は前編をご参照ください。この構成法に従い【問題1】の検定を行うと以下のようになります。
#モジュールのインポート
import numpy as np
import scipy.stats as sts
import math
#データ
before = np.array([90, 78, 86, 103]) #変化前
after = np.array([81, 73, 80, 99]) #変化後
Z_array = after - before #前後の差
n = len(Z_array) #標本数
#検定統計量
Z_mean = Z_array.mean() #平均
V = ((Z_array-Z_mean)**2).sum()/(n-1) #不偏分散
Tz = (Z_mean-0)/math.sqrt(V/n) #Zの計算(帰無仮説下における平均mu=0)
#p値の計算
p = (sts.t(df=n-1).cdf(Tz))*2 #自由度3のt分布において、Tz以下の値をとる確率の倍
print(p)
実行すると$${0.01150…}$$と表示されるかと思います。そしてこの値は以下のようにpythonのstatに実装されている対応のあるt検定を実行しても同じ結果になるかと思います。
#モジュールのインポート
import numpy as np
import scipy.stats as sts
#データ
before = np.array([90, 78, 86, 103]) #変化前
after = np.array([81, 73, 80, 99]) #変化後
p = sts.ttest_rel(before, after)[1]
print(p)
以上が、「1群の平均のt検定」の代表例となる「対応のある2群の平均のt検定」となります。おそらく馴染みあると思われた方も多いのではないでしょうか。t検定と聞くと「対応のない2群の平均のt検定」をまず想像し、特殊パターンとして対応のある場合を考える方も多いかもしれません。しかしどちらかというと、「対応のある2群の平均のt検定」こそが「1群の平均のt検定」であり、より基礎的な階層に存在することがイメージついたかと思います。さて、次章でついに一般的なt検定である「対応のない2群の平均の検定」に触れたいと思います!
対応のない2群の平均の検定(等分散)
対応のない2群のt検定は、それぞれが正規分布に従う2群についてそれらの平均が等しいか否かを検定します。その際それらの2群の正規分布の分散が等しいと仮定する場合(Studentのt検定)と仮定しない場合(Welchのt検定)があります。Welchのt検定については検定統計量の置き方が今までの検定法に従って簡単に構成することができないため、本記事ではStudentのt検定のみを扱います。以下のような問題を考えましょう。
一般化した形でも見慣れた検定だと思われる方が多いのではないでしょうか。今までの応用になるため、今回はこの一般形のまま考えてみましょう。以下の手順で考えてみてください。
群$${X}$$の平均を$${\mu_x}$$、群$${Y}$$の平均を$${\mu_y}$$とし、両群の母集団分布の分散を$${\sigma^2}$$とする。つまり、$${X_i}$$は$${\mathcal{N}(\mu_x, \sigma^2)}$$に従い、$${Y_i}$$は$${\mathcal{N}(\mu_y, \sigma^2)}$$に従うとする。
題意より、帰無仮説$${H_0}$$は$${\mu_x=\mu_y}$$、つまり$${\mu_x-\mu_y=0}$$となる。
それぞれの群の標本平均を$${\overline{X} = \frac{1}{n}\sum_{i=1}^n{X_i}}$$、$${\overline{Y} = \frac{1}{m}\sum_{i=1}^m{Y_i}}$$とすると$${\overline{X}}$$は$${\mathcal{N}(\mu_x, \frac{\sigma^2}{n})}$$に従い、$${\overline{Y}}$$は$${\mathcal{N}(\mu_y, \frac{\sigma^2}{m})}$$に従う。さらに、$${\overline{Y}-\overline{X}}$$は$${\mathcal{N}(\mu_y-\mu_x, (\frac{1}{n}+\frac{1}{m})\sigma^2)))}$$に従う。以上より$${H_0}$$下においては$${(\overline{Y}-\overline{X})/\sqrt{(\frac{1}{n}+\frac{1}{m})\sigma^2}}$$は$${\mathcal{N}(0, 1)}$$に従う。
それぞれの群の標本から計算される不偏分散を$${V_x = \frac{1}{n-1}\sum_{i=1}^n{(X_i-\overline{X})^2}}$$、$${V_y = \frac{1}{m-1}\sum_{i=1}^m{(Y_i-\overline{Y})^2}}$$とすると、$${(n-1)V_x/\sigma^2}$$は自由度$${n-1}$$の$${\chi^2}$$分布に、$${(m-1)V_y/\sigma^2}$$は自由度$${m-1}$$の$${\chi^2}$$分布に従う(「中編のおさらい」参照)。
一般に、$${W}$$が自由度$${k}$$の$${\chi^2}$$分布に従い、それとは独立に$${V}$$が自由度$${l}$$の$${\chi^2}$$分布に従うとき、$${W+V}$$は自由度$${k+l}$$の$${\chi^2}$$分布に従うという性質を持つ。ここで任意の$${i,j}$$において$${X_i}$$と$${Y_j}$$が独立であることから、$${V_x}$$と$${V_y}$$が独立となる。以上より、$${\frac{(n-1)V_x}{\sigma^2}+\frac{(m-1)V_y}{\sigma^2}=((n-1)V_x+(m-1)V_y)/\sigma^2}$$は自由度$${n+m-2}$$の$${\chi^2}$$分布に従う。
3.における$${(\overline{Y}-\overline{X})/\sqrt{(\frac{1}{n}+\frac{1}{m})\sigma^2}}$$と5.における$${((n-1)V_x+(m-1)V_y)/\sigma^2}$$について、$${\overline{X}}$$と$${V_x}$$、$${\overline{Y}}$$と$${V_y}$$が独立となるため$${(\overline{Y}-\overline{X})/\sqrt{(\frac{1}{n}+\frac{1}{m})\sigma^2}}$$と$${((n-1)V_x+(m-1)V_y)/\sigma^2}$$は独立となる(「中編のおさらい」参照)。
以上より$${T(\bold{X},\bold{Y})=\frac{(\overline{Y}-\overline{X})/\sqrt{(\frac{1}{n}+\frac{1}{m})\sigma^2}}{\sqrt{((n-1)V_x+(m-1)V_y)/((n+m-2)\sigma^2)}}}$$は自由度$${n+m-2}$$のt分布に従い、検定統計量を構成できる。
5.で$${\chi^2}$$分布に関する新たな性質が出てきましたが、こちらに関しては今後ガンマ分布という分布を扱うタイミングで触れたいと思います。また7.については$${T}$$の式が複雑になっていますが、中編で扱った以下の性質の通りに計算すれば一致するはずです。
$${T(\bold{X},\bold{Y})}$$をもう少し整理すると以下のようになります。
$$
{T(\bold{X},\bold{Y})=\frac{(\overline{Y}-\overline{X})/\sqrt{\frac{1}{n}+\frac{1}{m}}}{\sqrt{\frac{((n-1)V_x+(m-1)V_y)}{(n+m-2)}}}}
$$
ここで、$${T(\bold{X},\bold{Y})}$$には母集団分布の分散が含まれていないため、分散未知の状態でも等分散を仮定するだけで問題なく計算ができます!ここに標本の値を代入して得られた値を$${T}$$とすると、自由度$${n+m-2}$$の$${t}$$分布において$${T}$$以上(or 以下)の値をとる確率の倍が求める$${p}$$値となります。
例として以下の問題を扱いましょう。
t検定をするだけなら関数を使えば簡単な話ですよね!ただ、せっかく原理を学んだので、ベタ書きで構成してみましょう。以下のコードで実行することができます。
#モジュールのインポート
import numpy as np
import scipy.stats as sts
import math
#データ
rikei = np.array([68, 72, 69, 80, 86]) #理系
bunkei = np.array([79, 86, 81, 75, 93, 85]) #文系
n_r = len(rikei) #理系の標本数
n_b = len(bunkei) #文系の標本数
#検定統計量
R_mean = rikei.mean() #理系の平均
B_mean = bunkei.mean() #文系の平均
R_V = ((rikei-R_mean)**2).sum()/(n_r-1) #理系の不偏分散
B_V = ((bunkei-B_mean)**2).sum()/(n_b-1) #文系の不偏分散
T = (B_mean-R_mean)
/math.sqrt(1/n_r + 1/n_b)
/math.sqrt(((n_r-1)*R_V+(n_b-1)*B_V)/(n_r+n_b-2)) #Zの計算
#p値の計算
p = (1-sts.t(df=n_r+n_b-2).cdf(T))*2 #自由度10のt分布において、T以上の値をとる確率の倍
print(p)
また、scipyのstatを用いると以下のように簡単に記述できます。
#モジュールのインポート
import numpy as np
import scipy.stats as sts
#データ
before = np.array([68, 72, 69, 80, 86]) #理系
after = np.array([79, 86, 81, 75, 93, 85]) #文系
p = sts.ttest_ind(before, after, equal_var=True)[1]
print(p)
いずれの場合も実行すると、$${0.084872…}$$と表示され、理系と文系の英語の点数に有意な差があるとは言えないという結論になります(2つのコードで実行結果の最後の桁が違う可能性がありますが、計算過程の誤差に由来するものです)。以上までを一般形としてまとめたいと思います。
これで皆さんがよく使われるt検定について、関数頼りではなく自ら構成することができるようになったと思います!正直、使うだけなら原理を理解する必要は全くないのですが、単純なツールとしての統計から、数理統計学としての面白さが少しずつ見えてきませんか?ゆるは特に中編で扱った、「母集団が正規分布に従うとき、標本平均と不偏分散が独立になる」という事実に感動しました。何気なく使っている統計であってもいくつものトリビアが潜んでいて、それを理解しようとすると地道な勉強が必要になります。この記事がそのモチベーションになれば非常に嬉しいです!
t検定の拡張
ここまででt検定について扱ってきましたが、実はt検定はもっと多面的に構成・解釈することができます。詳細な説明は今後の記事で行う予定ですが今回のように、標本から構成される推定値が従う分布から考える解釈の他にも、2群のみの分散分析(one-way ANOVA)や、説明変数をダミー変数と見做して行う線形単回帰も同値なt検定として扱うことができます。何のことやら?ほんと?と思った方は今後の記事に乞うご期待ください。
おわりに
t検定に関する記事はここで一旦終わりにしようと思います。3編にわたり読んでくださった方々、本当にありがとうございます。ご指摘、ご質問大歓迎ですので遠慮なくお願いします。ゆるの答えらえる範囲であれば全力で答えさせて頂きます。
今後は
・仮説検定の危険性~$${p}$$値が従う分布~
・多重比較の補正法の理解
・仮説検定の種類と検出力~t検定は正規分布を仮定しないと使えない?~
・不偏分散はなぜ$${n-1}$$で割るのか?$${n}$$や$${n-2}$$ではダメなのか?
という聞いたことはありつつも原理を理解しづらい事実や、ゆるが今ハマっているベイズ統計学のアウトプット、そしてさらには統計検定1級合格までの軌跡などを記事にしていきたいと思います。今後ともよろしくお願いいたします。そしてふわにも時間ができたら記事を書かせます笑
それではまた次回!
【変更履歴】
2023/08/05 初稿投稿