Pythonで実装する推測統計③(統計的仮説検定)|スクラッチ実装で理解する基礎統計 #6

f:id:lib-arts:20190419173312p:plain

上記のシリーズで機械学習アルゴリズムの実装を行っているのですが、他の内容もできればということで同様のイメージで基礎統計を実装していければと思います。
#4では推測統計に入るにあたっての前段階として統計量を、#5では#5では推測統計のメイントピックである点推定と区間推定について取り扱いました。

#6では統計的仮説検定について取り扱います。
以下目次になります。

1. 統計的仮説検定とは
2. 簡単な検定の例とPythonでの実装
3. 母分散の検定とPythonでの実装
4. まとめ

 

1. 統計的仮説検定とは
1節では統計的仮説検定の大枠について説明します。説明だけだとわかりづらいので、とあるお菓子の含有量のパッケージの記述が28gから30gに変更された時に本当に増量されたのかを調べるという状態を仮定するとします。ここで簡易化のために分散であるσは既知で4であるとします。
この際に下記のように帰無仮説(null hypothesis)のH_{0}と、対立仮説(alternative hypothesis)のH_{1}をおきます。
H_{0}: μ=28
H_{1}: μ\neq28
この時に仮説H_{0}は考察の基準となる仮説であり、これが帰無仮説です。また、H_{1}H_{0}が棄却された時に採択される仮説でありこれが対立仮説です。統計的仮説検定(statistical hypothesis test)では、「H_{0}を棄却する(reject H_{0})」と「H_{0}を採択する(accept H_{0})」の2つの結論の一方を選択します。
具体例がないとわかりにくいので、下記のコードを実行して得られる問題があったとします。

import numpy as np

snack_weight = np.array([28.3, 29.4, 31.2, 30.2, 29.2, 30.4, 29.5, 30.4, 30.6, 29.8])
print(snack_weight)
print(np.sum(snack_weight)/snack_weight.shape[0])

実行結果は下記になります。

f:id:lib-arts:20190503190612p:plain
上記を確認すると、平均の重量が29.9gになっているので、直感的な考察としては重量変更がなされているということが確認できます。こちらについての仮説検定を帰無仮説として母平均を25gとおくことで仮説検定を行っていきます。
具体的な処理に関しては2節では行っていきます。


2. 簡単な検定の例とPythonでの実装
1節では統計的仮説検定の大枠の解説と具体的な問題の設定を行いました。
2節では1節で設定を行った問題に対して、母平均の検定を行えればと思います。具体的には標本平均\overline(X)の29.9gと帰無仮説でおいた母平均の28gの差に意味があるのかないのかを考える必要があります。有意な差かどうかについて分析を行います。
ここで気にするべきなのがどれほどの差があれば優位な差かみなせるかということです。
\overline{X} \sim N(μ,\frac{σ^2}{n})
標本平均に関しては上記が成り立つと考えて良いので、これに基づいて\overline{X}と28の差を偏差\sqrt{\frac{σ^2}{n}}=\sqrt{\frac{4}{10}}を用いて標準化します。標準化した後の値をZとおくと、Zは下記を実行することで求めることができます。

Z = (np.sum(snack_weight)/snack_weight.shape[0]-28)/np.sqrt(4/10)
print(Z)

上記を実行すると下記のようになります。

f:id:lib-arts:20190503190628p:plain
実行した結果として、Zが3に近い値になっており、2σの外になっているため、帰無仮説H_{0}は棄却されると考えることができます。したがって、統計的検定の枠組みではお菓子の重量は変化したと考えることができます。

 

3. 有意水準、片側検定、両側検定とPythonでの実装
2節では簡単な検定の例に基づいて解説を行いました。3節では検定を行う上で重要なトピックである、有意水準(level of significance)、片側検定(one-sided test)、両側検定(two-sided test)などについて取り扱っていきます。
まず有意水準に関してですが、どのくらいの差を有意とみなすかということです。具体的には10%、5%、1%あたりが挙げられることが多く、5%(α=0.05)を用いることが最も多いです。
αの設定を5%におくと、先ほどのZが\pm{1.96}よりも外のケースのみ帰無仮説が棄却されるようになります。先ほど2σを基準にしていたのは、5%を意識していたというように理解しておけば良いかと思います。
このように2節では何と無く2σと設定していたところに有意水準の考え方を導入するとどのくらいの割合かが考察できて良いです。この際の95%は確率分布(今回は正規分布を仮定しています)の区間積分によって得られると考えれば良いです。
次に、片側検定と両側検定に関してですが、両方の側を取るのが両側検定、片方だけ考慮するのが片側検定と考えると良いと思います。具体的に見ないとわかりづらいので、以下実装を元に把握していきます。下記の実装ではscipy.stats.normを元に、正規分布の値を取り出しています。

from scipy.stats import norm

print(norm.cdf(0))
print(norm.cdf(1.96))
print(norm.cdf(-1.96))
print(norm.cdf(1.96)-norm.cdf(-1.96))

上記を動かすと下記のような結果が得られます。

f:id:lib-arts:20190503190645p:plain
ここで注意しておくと良いのが、norm.cdf(Z)が標準化後の変量Zまでの積分値を表しています。この値の解釈としては、Z以下の値に全体のサンプルが含まれている確率がnorm.cdf(Z)だということです。ここで、norm.cdf(1.96)が0.9750..なので、Z=1.96以下の範囲に全体の97.5%が含まれているという意味です。
両側検定ではZ=1.96以下について考えると同時にZ=-1.96以上も考えねばならないので、norm.cdf(1.96)-norm.cdf(-1.96)が0.95になるように1.96という値が設定されています。
片側検定だとこれが半分になるため、1.96を基準に考える際の有意水準は0.025になります。難しく考えるとわからなくなりがちなので、シンプルに捉えておくと良いかと思います。


4. まとめ
#6で取り扱った検定は非常にとっつきづらい話で、基礎統計の文脈ではかなり難解です。
最初から全てを理解しようというのではなく、大枠から少しずつ掴み、徐々に取り扱う話題を増やしていくのが良いのではと思います。