統計的検定:Python によるカイ2乗検定の実装

数学的理論と計算

カイ二乗検定について、例題を解きながら学習することにします。

通常のt検定とカイ2乗検定の違いは

  • カイ二乗検定はカテゴリカルデータで独立性を検定
  • t検定は、連続データで平均の差を検定

になります。

といわれてもよくわからないので、実際の例を使って解説します。

Sponsored Link

カイ二乗分布:サイコロの目の検定

いかさまがされていないサイコロを例えば120回振ると、普通は一つの目が20回の確率で出ることになります。

では目が出た数が以下の場合、1 = 18、2=19、3 = 23、4= 24、5 = 19、6= 17、このサイコロは公平なサイコロかそうでないかを調べるためにカイ二乗検定が使われます。

では実際にやってみましょう。

データはいつものように、演習で身につける統計学入門から生成しています。

サイコロを120回振った時の期待値は一つの目当たり120/6 = 20ですね。

それを踏まえて、分割表を作成しpythonで読み込んでみました。

import pandas as pd

ex14 = pd.read_excel('ex 14 x2.xlsx', header = 0, index_col = 0)
ex14

上記のような分割表ができるわけですが、この観測度数と理論値に差があるのかを検定していきます。

まず初めに仮説を立てます。

  • 帰無仮説: 観測度数と期待度数は一致する
  • 対立仮説:観測度数と期待度数は一致しない。

Pythonを使ってカイ二乗検定を行う場合のモジュールは「stats.chi2_contingency()」を用います。

参考サイト:

クロス集計とカイ二乗検定 - Qiita
次のようなシナリオを想定します。関東圏内を中心としたチェーン店 D フランチャイズでは都市ごとの店舗で複数の商品を扱っています。このたび、市場に投入した新商品 A と B について、人気の 2 店…
カイ二乗検定 | 観測データの分布が理論値の分布に従うかどうかを検定

ではさっそくやってみましましょう。

import scipy as sp
import scipy.stats

x2, p, dof, expected = sp.stats.chi2_contingency(ex14)

print("カイ二乗値は %(x2)s" %locals() )
print("確率は %(p)s" %locals() )
print("自由度は %(dof)s" %locals() )
print( expected )

if p < 0.05:
print("有意な差があります")
else:
print("有意な差がありません")

カイ二乗値は 0.9727271416377904
確率は 0.9647353856191604
自由度は 5
[[19.  19.5 21.5 22.  19.5 18.5]
 [19.  19.5 21.5 22.  19.5 18.5]]
有意な差がありません 

確率が0.972…であり、有意水準0.05 (5%)よりも大きいことから、観測値が偶然ではないとは言えず、したがって帰無仮説は棄却できません。

つまり「観測度数が確率理論に従っていないとは言えない」となります。

カイ二乗分布:食中毒の場合

ではもう一問やってみましょう。

今回も演習で身につける統計学入門の例題で、データもそこから生成していきます。

問題は以下の通り。

あるパーティ会場で食中毒事件が起こり、メニューの中の食品Aについて出席者全員76人から喫食と発症の有無を聞き取り調査した結果、次の表のようになりました。食品Aを食べた39人のうち、発症した客は26人発症しなかったのは13人。食品Aはこの食中毒と関連するか有意水準5%で検定しなさい。

まずは仮説の設定:

  • 帰無仮説:食品Aは食中毒と関連しない。
  • 対立仮説:食品Aは食中毒と関連する。

この問題からエクセルで表を作り、それをpythonを使って読み込んでみます。

参考サイト:

pandas.DataFrameの行・列を指定して削除するdrop | note.nkmk.me
pandas.DataFrameの行・列を指定して削除するにはdrop()メソッドを使う。 pandas.DataFrame.drop — pandas 2.0.3 documentation DataFrameの行を指定して削除行名(行ラ...
ex15 = pd.read_excel('ex15.xlsx', header = 0, index_col = 0)
ex15 = ex15.drop('小計', axis=0)
ex15 = ex15.drop('小計', axis = 1)
ex15

以上のような表ができるわけですが、これをカイ二乗分布を使って検定を行います。

とはいっても、プログラムに当て込むだけですのでそれほど手間はかかりません。

import scipy as sp
import scipy.stats

x2, p, dof, expected = sp.stats.chi2_contingency(ex15)

print("カイ二乗値は %(x2)s" %locals() )
print("確率は %(p)s" %locals() )
print("自由度は %(dof)s" %locals() )
print( expected )

if p < 0.05:
print("有意な差があります")
else:
print("有意な差がありません")

カイ二乗値は 4.217885213007162
確率は 0.03999998526330005
自由度は 1
[[21.03947368 17.96052632]
 [19.96052632 17.03947368]]
有意な差があります 

この場合確率が、p<0.05であるため観測値は偶然ではなく、帰無仮説は棄却され、食中毒は食品Aと関連すると推測されます。

Sponsored Link

コメント

タイトルとURLをコピーしました