あれもPython,これもPython

Pythonメモ※本サイトはアフィリエイトを利用しています

データサイエンスをPythonで試す(1_検定)

そろそろ本腰をいれて、Pythonでデータ分析を始めることにしました。
教科書は以下の本を使用します。(クリックするとamazonに飛びます)

元の本はRでデータ分析を行っているので、
それをPythonでやるにはどうやるのか?
を何回かに分けてノートとして公開します。
(今回は検定)

環境構築

目的 モジュール
環境 Anaconda
IDE IPythonNotebook
データ処理 Numpy,Pandas
グラフ作成 matplotlib
検定等 Scipy
機械学習 Orange,sklearn
時系列分析 statsmodels

以上を導入しておきます。

第三章:検定

というわけで、上記の書籍の第三章、検定から入ります。
IPythonNotebookを起動してノートをつくります。
まずは、必要なモジュールをimportします。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats

# notebook上にmatplotのグラフを表示するようにする
%matplotlib inline

t検定

本書で扱うデータを読み込んでグラフを見てみます。

# スペース区切りのデータなので引数sepにスペースを指定
sales = pd.read_csv("ch3_2_2.txt",sep = " ")

# データを確認
sales.head()
#   DB1      DB2
# 0 0.947729 2.465692
# 1 1.404682 2.132022

# グラフ化(Pandasのmatplotラッパー)
sales.plot()#折れ線グラフ
sales.boxplot()#箱ひげ図

f:id:esu-ko:20160307120444p:plain f:id:esu-ko:20160307120458p:plain

どうも、書籍で使っているデータとは違う気がするが・・・。
作業は同じようにやってみる。

DB1とDB2というデータがあり、
この2つのバラつきの離れ具合をt検定します。
t検定はscipyの中にあります。

t,p = scipy.ttest_rel(sales["DB1","DB2"])
print "t値" + str(t)
print "p値" + str(p)
#t値:-4.25507943128
#p値:0.000800223179842

χ二乗検定

先程はt検定でしたが、
scipyにはその他の検定もあります。
これらを試してみます。

本書に載っていたデータを使います。

病気にかからなかった 病気にかかった
予防接種を受けた 1625 5
予防接種を受けなかった 1022 11
# arrayにする
dat = np.array([[1625,5],[1022,11]])

# 検定
squared,p,dof,ef = stats.chi2_contingency(dat)
print "検定統計量" + str(squared)
print "p値" + str(p)
print "自由度" + str(dof)
print "期待度数"
print str(ef)
# 検定統計量4.88166202954
# p値0.0271434708976
# 自由度1
# 期待度数
# [[ 1620.20653398     9.79346602]
# [ 1026.79346602     6.20653398]]

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

行の1つが全て1桁になるとχ二乗検定では対応できないので、
その場合はフィッシャーの正確確率検定を使用します。

dat_edit = np.array([[1625,5],[5,1]])
odds,p=stats.fisher_exact(dat_edit)
print "odds ratio:" + str(odds)
print "p値:" + str(p)
#odds ratio:65.0
#p値:0.021837205224

wilcoxon検定(Mann-Whitney検定)

ノンパラメトリック検定の順位和検定です。
本書によると、

データがどのように分布していてもお構いなしに使える検定メソッド

※ただしそこまで完全フリーダムではないとのこと 2つのデータの分布が全く似ていない、分からない時に使用する

これまたscipyでできます

sales2 = pd.read_csv("ch3_4_1.txt",sep=" ")
sales2.head()
# A B
# 0 146 157
# 1 162 117

w,p = stats.wilcoxon(sales2["A"],sales2["B"])
print "検定量" + str(w)
print "p値" + str(p)

# 検定量36.0
# p値5.2876668543165082e-05

本書とは値が違うのが気になる・・・

まとめ

Pythonで検定をするには

検定名 関数等
t検定 scipy.stats.ttest_rel
独立性のχ二乗検定 scipy.stats.chi2_contingency
フィッシャーの正確確率検定 scipy.stats.fisher_exact
wilcoxon検定 scipy.stats.wilcoxon

▼ノンパラメトリックな並び替え検定も試しました

esu-ko.hatenablog.com