昨日は仮設検定のための前提として統計量と区間推定について説明しました。もう一度、統計量を求めるためによく使う NumPy の関数を整理しておきましょう。
よく利用する基本統計量の算出関数
ここでは数値ベクトル X と Y があるものとします。なお import numpy as np と from scipy import stats が前提です。
関数 | 説明 |
---|---|
np.max(X) | X の最大値を求める |
np.min(X) | X の最小値を求める |
np.mean(X) | X の平均値を求める |
np.median(X) | X の中央値を求める |
np.var(X) | X の分散を求める |
np.std(X) | X の標準偏差を求める |
stats.scoreatpercentile(X, 25) | X の第一四分位を求める |
stats.scoreatpercentile(X, 75) | X の第三四分位を求める |
np.dot(X, Y) | X と Y の行列積を求める |
np.outer(X, Y) | X と Y の直積を求める |
np.corrcoef(X, Y)[0,1] | X と Y の相関係数を求める |
仮説検定と確率分布
仮説検定とは統計的仮説の有意性検定のことです。仮説検定というからには仮説を立てなければなりませんね。大雑把に仮説を立てるとすると例えば次のようなケースが考えられます。
仮説を立てるケースの例
- サイコロの出目は 1/6 のはずだが、どうも 6 が出る頻度が高いようだ (イカサマじゃないか) 。
- ダイエットを努力して 1 ヶ月後体重が 75 kg から 70 kg に減少した。しかし体重は計測の誤差や日々の変動で上下する。こうした誤差や変動を含めて標準偏差 1 kg の正規分布に従うとしたら、これはやせたと言えるだろうか。
- 医療診断である二つの地域 A と B で疫病の患者数を調査した。 10 回の調査で A では 52 人、 B では 28 人の患者が見つかった。一見すると地域 A のほうが疫病の羅患率は高そうだが地域の人口は異なる。いまのところ患者の出現頻度がポアソン分布に従うことがわかっているとしたら、果たしてそう言えるだろうか。
- ある商品の購買数は 30 代女性が 20 代女性の 2 倍である。このことを確かめるために 100 人から調査をしたところ 30 代女性は 52 人、 20 代女性は 30 人、それ以外の年代が 15 人であった。しかし調査対象の人数を 150 人、 300 人、 500 人と増やすと割合は異なった。こんなときにどう判断をしたら良いか。
※ ここに挙げた「仮説」はいわゆる統計学の仮説検定における仮説ではなくもう少し大きな一般的な視点でいう仮説です。統計学的仮説検定でいう帰無仮説と対立仮説の「仮説」については製品の改良を仮説検定するの回をお読みください。
統計量の標本分布
確率分布の定義を示します。
分布 | 説明 |
---|---|
二項母集団 | 母集団分布が母数 p のベルヌーイ分布ならば二項分布 Bi(1,p), X1 + ... + Xn の分布は二項分布 Bi(n,p) に従う。 |
ポアソン母集団 | 母集団分布が母数 λ のポアソン分布 Po(λ) ならば X1 + ... + Xn はポアソン分布 Po(nλ) に従う。 |
正規母集団 | 母集団分布が母数 u, σ の正規分布 N(μ, σ^2) ならば X1 + ... + Xn は正規分布 N(nμ, nσ^2) に従う |
主な連続型の確率分布
正規分布
しばしば登場する 正規分布 (normal distribution) の説明はWikipedia の記述あたりを見たほうが早いかもしれませんが、定義を示すと次式の通りです。
f(x) = \frac 1 {\sqrt{2\pi\sigma}} exp \{-(x-\mu)^2/2{\sigma^2}\}, -\infty \lt x \lt \infty
確率分布 X が正規分布に従っているとき期待値は次式の通りです。
E(X) = \int_{-\infty}^{\infty}x(1/{\sqrt{2\pi\sigma}}) exp \{-(x-\mu)^2/2{\sigma^2}\}{dx} = \mu
したがって分散は次式となります。
V(X) = \int_{-\infty}^{\infty}(x-\mu)^2(1/{\sqrt{2\pi\sigma}})exp \{-(x-\mu)^2/2{\sigma^2}\}{dx} = \sigma^2
このことから平均 μ 分散 σ^2 の正規分布を次のように表します。
N(\mu, \sigma^2)
指数分布
指数分布 (exponential distribution) は次の確率密度関数で定義される連続型の分布です。
f(x) = {\lambda}e^{-{\lambda}x} \\
ただし \\
(x\ge0), 0 (x\lt0)
この確率分布は連続的な待ち時間分布の性質を持ちます。たとえば故障率が一定のシステムの偶発的な故障までの待ち時間、寿命、耐用年数、あるいは災害までの年数などがこの例です。
この分布に従う確率変数 X の期待値と分散はそれぞれ次式で求まります。
E(X) = 1/{\lambda} \\
V(X) = 1/{\lambda^2}
指数分布によって生起までの年数が分布する希少事象は、確率が小さいとしても、近い将来発生しても不自然ではありません。たとえば大地震などがそのわかりやすく身近な例えです。
主な離散型の確率分布
ポアソン分布
コイントスのような二項分布を考えてみます。二項分布は一様であるが、もし n が大きく p が小さい (大量の観察において確率が稀少) である場合にポアソンの少数の法則が成立します。たとえば 1000 本中 3 本だけ当たりがあり残りが外れであるクジだとか、契約成立まで到達する確率のきわめて低い巨額の商品の成功率などを挙げるとわかりやすいでしょう。定理は次の通りです。
P(X = k) = \frac {{\lambda}^xe^{-\lambda}} {k!}, \lambda \gt 0
確率変数 X がポアソン分布に従うならば期待値と分散は次式の通りです。このように期待値と分散が等しく λ になるのがポアソン分布の特徴とも言えます。
E(X) = \lambda \\
V(X) = \lambda
いろいろな仮説検定
カイ二乗検定
先日も出てきた カイ二乗検定 (chi-square test) では分散の一致を検証します。帰無仮説が棄却されなければ検定統計量がカイ二乗分布に従います。
正規分布 N(μ, σ^2) から n 個の無作為抽出をおこなったとき
Z = \sum_{i=1}^n \frac {(X_i - \mu)^2} {\sigma^2}
となる Z は自由度 n のカイ二乗分布に従います。
たとえばある商店街を観察して女性 45 名、男性 55 名が観測されたとします。この 100 名には偏りがありましたが、実際には男女比は五分五分かもしれないということを調査すると
n = \frac {(45-50)^2} {50} + \frac
{(55-50)^2} {50} = 1
この時の自由度 n は 1 となります。自由度 1 のカイ二乗分布は男女がそもそも等しいと仮定すると 0.32 なので、棄却されません。すなわち十分起こりえるということになります。
t 検定
t 検定 (student's t-test) は、小さな標本について平均値を検定します。正規分布している母集団から抽出された大きさ n の標本に対して母平均 u 、標本平均 X 、標準標本偏差 s を使うと次式の通り T が求まります。
T = \frac {\sqrt{n-1} (X - \mu)} s
このとき T は自由度が n-1 の t 分布に従います。
仮説検定の実践
カイ二乗検定と t 検定でどのような違いがあるのか、また実装コードはどのようになるか例を挙げて説明していきましょう。
カイ二乗検定
カイ二乗検定は次のような集約されたデータに対し店舗と商品売上に関連があるかどうかを調べます。
店舗 | 商品 A | 商品 B | 合計 |
---|---|---|---|
店舗 X | 435 | 165 | 600 |
店舗 Y | 265 | 135 | 400 |
合計 | 700 | 300 | 1000 |
カイ二乗検定は以前おこないましたので省略します。
t 検定
t 検定ではたとえば次のようなデータに対し、国語と数学の得点に有意差があるかどうか調べます。 (※疑似データです)
出席番号 | 国語 | 数学 |
---|---|---|
1 | 68 | 86 |
2 | 75 | 83 |
3 | 80 | 76 |
4 | 71 | 81 |
5 | 73 | 75 |
6 | 79 | 82 |
7 | 69 | 87 |
8 | 65 | 75 |
これを t 検定するとこうなります。
import numpy as np
import scipy as sp
from scipy import stats
X = [68 75 80 71 73 79 69 65]
Y = [86 83 76 81 75 82 87 75]
print(X)
print(Y)
t, p = stats.ttest_rel(X, Y)
print( "t 値は %(t)s" %locals() )
print( "確率は %(p)s" %locals() )
if p < 0.05:
print("有意な差があります")
else:
print("有意な差がありません")
# [68 75 80 71 73 79 69 65]
# [86 83 76 81 75 82 87 75]
# t 値は -2.9923203754253302
# 確率は 0.0201600161737
# 有意な差があります
国語と数学の成績には有意な差があることがわかりました。
では次の理科と社会の成績ではどうでしょうか。
出席番号 | 理科 | 社会 |
---|---|---|
1 | 85 | 80 |
2 | 69 | 76 |
3 | 77 | 84 |
4 | 77 | 93 |
5 | 75 | 76 |
6 | 74 | 80 |
7 | 87 | 79 |
8 | 69 | 84 |
同じコードで試してみましょう。
# [85 69 77 77 75 74 87 69]
# [80 76 84 93 76 80 79 84]
# t 値は -1.6077470858053244
# 確率は 0.151925908683
# 有意な差がありません
今度は有意な差が見られないということがわかりました。