pythonで統計学基礎:03 検定・分散分析

前回までに引き続き,ハンバーガー統計学をpythonで進めることで,基本的な統計学の内容をどのようにpythonで表現していくかを学びます.今回はχ二乗検定t検定一元配置分散分析を扱います.
これまでの記事はこちらです.
– 「pythonで統計学基礎: 01 平均と分散
– 「pythonで統計学基礎:02 信頼区間・t分布

まずは必要なライブラリのimportを行いましょう.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns
sns.set()

χ二乗検定

2つのお店の売り上げデータをpandasのデータフレームとして入力し(赤字部分),得られたテーブルをscipy.stats.chi2_contingencyで処理することで,χ二乗検定が行えます.「contigency table」とは聞き慣れない単語かもしれませんが「分割表」のことで,下のようなテーブルを指します.つまり分割表を入力データとすることでχ二乗検定を行ってくれるメソッドになります.

potato chicken total
wakuwaku 435 165 600
mogumogu 265 135 400
total 700 300 1000
df1 = pd.DataFrame({'potato': [435, 265], 'chicken': [165, 135]},
                   index=['wakuwaku', 'mogumogu'])
stats.chi2_contingency(df1, correction=False)
(4.464285714285714, 0.03461055751570723, 1,
array([[180., 420.],
       [120., 280.]]))

戻り値はχ二乗値p値,帰無仮説下での売り上げデータです.すなわち以下のデータを仮定してχ二乗値を求めていることになります.(pandasの都合上データの順番が変わっています)

chicken potato total
wakuwaku 180 420 600
mogumogu 120 280 400
total 300 700 1000

いろいろなt検定

t検定には前提条件によって色々なバリエーションが存在し,用いるべきpythonのメソッドも異なります.
t検定用のメソッドはscipy.stats.ttest_XXXXの形で4種類存在しています.

対応なしのt検定

scipy.stats.ttest_ind(list1, list2)
scipy.stats.ttest_ind_from_stats

対応なしのt検定とは,各々の処置をされた被験者間に関係がない場合に用いる検定で,そのうち入力データによってscipy.stats.ttest_indscipy.stats.ttest_ind_from_statsを用いることになります.

生データからのt検定

入力データが各群における生データの場合の例が以下のコードになります.ttest_indは入力データ2つを配列で受け取ります.

taste1 = pd.DataFrame({'wakuwaku': [70,75,70,85,90,70,80,75],
                       'mogumogu': [85,80,95,70,80,75,80,90]})
waku_taste = taste1['wakuwaku']
mogu_taste = taste1['mogumogu']
stats.ttest_ind(waku_taste,mogu_taste)

戻り値はt値p値になります.今回の場合はp値が0.21と非常に大きいので帰無仮説が棄却できません.

Ttest_indResult(statistic=-1.2881223774390613, pvalue=0.21858702220219914)

データの平均と標準偏差からのt検定

上記の例ではt検定を行うにあたり,データの配列を入力値としました.もしデータの平均値,標準偏差,データ数のみがわかっている場合にはscipy.stats.ttest_ind_from_statsを使うことでt検定が行えます.

stats.ttest_ind_from_stats(mean1=waku_taste.mean(),
                           std1=waku_taste.std(),
                           nobs1=len(waku_taste),
                           mean2=mogu_taste.mean(),
                           std2=mogu_taste.std(),
                           nobs2=len(mogu_taste))

今回の場合は元データが同じですので,結果は当然同じになります.

Ttest_indResult(statistic=-1.2881223774390613, pvalue=0.21858702220219914)

対応ありのt検定

scipy.stats.ttest_rel(list1, list2)

対応ありのt検定とは,異なる処置を同じ個体に施す場合などに使います.この場合は個体差が無視できるようになるため,全体の差の標準誤差が小さくなります.そのため信頼区間が狭くなり,類似のデータを用いた場合にも検出力の高い検定が可能になります.pythonではscipy.stats.ttest_relに実装されています.

waku_taste2 = pd.Series([90,75,75,75,80,65,75,80])
mogu_taste2 = pd.Series([95,80,80,80,75,75,80,85])
stats.ttest_rel(waku_taste2,mogu_taste2)

戻り値は対応なしと同様に,t値p値です.この場合には5%水準で棄却できる結果になりました.

Ttest_relResult(statistic=-2.965614910077132, pvalue=0.020937570206924612)

一元配置分散分析(One-way ANOVA)

scipy.stats.f_oneway(list1, list2, list3)

比較する系が3つ以上の場合にはt検定を使うことはできません.このような場合にも使える分析手法として分散分析(ANOVA)があります.pythonでは一元配置分散分析scipy.stats.f_onewayで,二次元配置statsmodelsに実装されていますが,今回は一元配置のみ扱います.f_onewayの使い方はほぼ上記のt検定と同じで,単純にデータの配列を入力するだけです.

waku_taste3 = pd.Series([80,75,80,90,95,80,80,85,85,80,
                         90,80,75,90,85,85,90,90,85,80])
mogu_taste3 = pd.Series([75,70,80,85,90,75,85,80,80,75,
                        80,75,70,85,80,75,80,80,90,80])
paku_taste3 = pd.Series([80,80,80,90,95,85,95,90,85,90,
                         95,85,98,95,85,85,90,90,85,85])
stats.f_oneway(waku_taste3,mogu_taste3,paku_taste3)

結果の戻り値はF値p値になります.今回はp値が非常に小さいことから,3つの群のうち少なくともどれかの組み合わせでは差があることがわかります.しかし,どの組み合わせに差があるかがわからないのが,分散分析の弱みで,多重比較法などの他の分析法に頼ることになります.

F_onewayResult(statistic=12.223110194494566, pvalue=3.824826458393889e-05)

終わりに

これまで3回に渡ってハンバーガー統計学の内容を用いてpythonの勉強を進めてきました.複雑な内容も簡単なコードで実現できることがわかってワクワクしてきたかと思います.もちろんプログラムで1発の内容であっても,その中身を理解しないで使うことは誤用の可能性もあり危険です.プログラミング言語の勉強と理論の勉強を常に並行して進めていきたいですね.その点ハンバーガー統計学は,高校レベルの確率・統計も怪しかった私を,簡潔・明快な説明で引っ張り上げてくれました.統計分析をこれから勉強したい初心者に全力でおすすめできる1冊です.次回は続編であるアイスクリーム統計学を使って回帰分析などを取り上げる予定です.

シェアする

  • このエントリーをはてなブックマークに追加

フォローする