# ライブラリの読み込み
import numpy as np
import pandas as pd
import scipy as sp
import statsmodels
import statsmodels.api as sm
import statsmodels.formula.api as smf
# ライブラリのバージョン
print('np ',np.__version__)
print('pd ',pd.__version__)
print('sp ',sp.__version__)
print('sm ',statsmodels.__version__)
# データの読み込み
data = pd.read_csv('data.csv')
print(data)
# モデル化
anova_mod = smf.ols('weight ~ food', data=data).fit()
# 分散分析表
anova_table = sm.stats.anova_lm(anova_mod, type=2)
print(anova_table)
# F分布を使ってp値を計算する
1 - sp.stats.f.cdf(16, 2, 3)
# 分散分析表はDataFrameなので結果の取り出しは容易
type(anova_table)
# F比
anova_table['F']
anova_table.loc['food', 'F']
# モデルから直接取り出してもよい
anova_mod.fvalue
# 帰無仮説が正しい(foodによって体重が変わらない)ことを仮定したモデル
anova_null = smf.ols('weight ~ 1', data=data).fit()
# 総平均
anova_null.params
np.mean(data.weight)
# モデルの標準偏差
np.sqrt(anova_null.scale)
np.std(data.weight, ddof=1)
# 平均7、標準偏差3.741657の正規分布に従う確率変数を生成
np.random.seed(1)
mu = np.mean(data.weight)
sd = np.std(data.weight, ddof=1)
size = len(data)
norm_instance = sp.stats.norm(loc=mu, scale=sd)
res_rnorm = norm_instance.rvs(size=size)
print(res_rnorm)
# このシミュレーションデータに対してF比を計算すると、
# 小さなF比が得られやすい
# DataFrameに直す(statsmodels.regression.linear_model.OLSを使う方法もある)
sim_df = pd.DataFrame({
'weight': res_rnorm,
'food': data.food
})
# 分散分析の実行
mod_sim = smf.ols('weight ~ food', data=sim_df).fit()
print('F比', mod_sim.fvalue)
print(sm.stats.anova_lm(mod_sim, type=2))
# PB検定の実行
# 時間がかかるので注意
n_sim = 50000 # シミュレーションする回数
f_ratio_vec = np.zeros(n_sim) # F比を保管する容れ物
exp_vec = data.food # 水準
np.random.seed(1)
for i in range(0, n_sim):
# シミュレーションにより体重データを生成
# このデータは、体重が餌によって変化しないことを想定している
simlated_weight = norm_instance.rvs(size=size)
sim_df = pd.DataFrame({
'weight': simlated_weight,
'food': exp_vec
})
# モデル化と分散分析表の出力
mod_sim = smf.ols('weight ~ food', data=sim_df).fit()
# F比を保管
f_ratio_vec[i] = mod_sim.fvalue
# F比が16を超えた割合
sum(f_ratio_vec > 16) / n_sim