読者です 読者をやめる 読者になる 読者になる

tak0kadaの何でもノート

発声練習、生存確認用。

医学関連は 医学ノート

χ2検定 - 「Think Stats」第7章

ピアソンの\(\chi^{2}\)検定について

\(\chi^{2}\)検定は計数データに対して用いる手法である*1。係数した「集計表」が偶然生じたものか検定する際に用いる。

ピアソンの\(\chi^{2}\)検定

観察された事象の相対的頻度がある頻度分布に従うという帰無仮説を検討するノンパラメトリック手法である*2。また、によると、この検定は集計値がそれぞれ少なくとも5以上ない場合*3や期待値が10未満や偏りが大きい場合*4は 無効である。標本数が少ない場合はフィッシャーの正確検定を行う。

\(\chi^{2}\)統計量

\[ \chi^{2} \equiv \displaystyle \sum_{i} \dfrac{(O_{i}-E_{i})^{2}}{E_{i}} \]

やってみる

マンガでわかる統計学に従って、

高校生300人に聞いた 電話で メールで 直接会って
女性 34 61 53 148
男性 38 40 74 152
72 101 127 300

というデータが存在したとして考える

検定のステップは

  1. 母集団の定義
  2. カテゴリの定義、帰無仮説の設定
    (例1: クラメールの連関係数は0である。例2: 高校生の男女間に違いはない。)
  3. 行う検定を決める
  4. \(\chi_{0}^{2}\)統計量を使うことにする
  5. 有意水準を決める
  6. 6.1. それぞれのセルに対して偏差を計算する
    6.2. \(\chi_{0}^2\)統計量を計算する
    6.3. モンテカルロ計算や分布表などを用いてp値を計算する

(TODO: 検定のステップの意義を理解すること)

である。モンテカルロ法を行わなくともscipy.statsに検定用の関数が用意されているのでそれを使う。

from __future__ import division
from scipy import stats

obs = np.array([[34, 61, 53], [38, 40, 74]])
chisq, p, dof, exp = stats.chi2_contingency(obs)
print("chisquare-value = " + str(chisq))
print("p-value = " + str(p))

より、p値が0.018となり帰無仮説は棄却される。

参考
当初はchi2_contingencyの存在に気づいていなかったので一般的な検定にも関わらず関数が用意されていないことに疑問を抱きつつ手作業で計算していた。

#np.dotで行列の積が計算できるが次元を合わせておかないといけないのでおまじない
#col = np.array([obs.sum(axis=0)]).Tなどとしても同じ結果になる
col, row = np.array(obs.sum(axis=0), ndmin=2),\
           np.array(obs.sum(axis=1), ndmin=2).T

exp = np.dot(row, col)/obs.sum()

#なぜか"f_exp="はなくてもいけるが公式ドキュメントでは必要になっている
#k-1-ddofは自由度を表す
chisq, p = stats.chisquare(obs.flatten(), f_exp=exp.flatten(), ddof=3)
print("chisquare = " + str(chisq))
print("p-value = " + str(p))

自由度はmin(行数-1, 列数-1)なので2より、ddof=3とした。

フィッシャーの正確確率検定

|a|b|
|c|d|
のような表があった時、

\[ p = \dfrac{(a+b)!(c+d)!(a+c)!(b+d)!}{(a+b+c+d)!a!b!c!d!} \]

やってみる

scipyのドキュメントから取ってきたネタ。大西洋とインド洋でちょっとずつ調査をしてみた時に得られた結果が有意か調べてみる。

大西洋 インド洋
クジラ 8 2
サメ 1 5
table = np.array([[8, 2], [1, 5]])
oddsratio, p = print(stats.fisher_exact(table))
print("p-value = " + str(p))

fisher_exact関数はalternativeキーワードを'two-sided'、'less'、'greater'の3種類から取れてデフォルトが'two-sided'。これを変えるとp値が変わるが理屈は分からなかった。

クラメールの連関係数

カテゴリ変数同士の相関について調べる方法。これまでの話題は母集団についてであったが、クラメールの連関係数は得られた標本の値に相関があるか調べるためのもの。 \[ V = \sqrt{\dfrac{\chi^{2}}{\text{(全標本数)}\times(\text{min(行数, 列数)-1})}} \] 今回は\(\sqrt{8/300/1}=0.16\)程度である。Vは0から1の範囲で、0が無相関、1が強い相関を表す。今回は大きな相関はなさそう。