用Python学分析|用Python学分析 - 单因素方差分析
单因素方差分析(One-Way Analysis of Variance)
判断控制变量是否对观测变量产生了显著影响
分析步骤
- 建立检验假设
- H1:不同因子水平间的均值有显著差异
- 【注意】有差异,有可能是所有因子水平间都存在差异,也有可能只有两个因子水平间的均值存在差异
- 计算检验统计量F值
MSA = SSA / ( k - 1 ) MSA:组间均方, 对总体方差的一个估计
MSE = SSE / ( n - k ) MSE:组内均方,不论H0是否为真,MSE都是总体方差的一个无偏估计
SST = SSA + SSE SST:总误差平方和,反映全部观测值的离散情况
SSA:组间误差平方和,也称水平项误差平方和,反映各因子水平(总体)的样本均值之间的差异程度
SSE: 组内误差平方和
- 确定P值
- 方差分析表
- 根据给定的显著性水平,并作出决策
根据选定的显著性水平,F值大于临界值时,将拒绝原假设
根据P值进行假设检验
- 进一步分析
方差齐性检验
多重比较检验
- 哪个水平的作用明显区别于其他水平
- 哪个水平的作用是不显著
- 等等
【python分析:用ols模块进行计算】
# 引入数据
import pandas as pd
data_value = https://www.it610.com/article/{'无促销':[23,19,17,26,28,23,24,30],
'被动促销':[26,22,20,30,36,28,30,32],
'主动促销':[30,23,25,32,48,40,41,46]}# 因变量
da = pd.DataFrame( data_value ).stack()
da.columns = ['水平','观测值']# ols模块进行分析from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm formula = '{} ~ {}'.format(da.columns[1], da.columns[0])
model = ols( formula, da ).fit()
anovat = anova_lm(model)
print(anovat)
输出结果:
文章图片
【python分析:用自定义函数进行计算】
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,互帮互助,
群里还有不错的视频学习教程和PDF电子书!
'''
def ANOVA_oneway( df, a = 0.05 ):
from scipy.stats import f
'''
进行单因素方差分析
输入值:df - pd.DataFrame,第一列为水平,第二列为观测值;a - 显著性水平,默认为0.05
返回类型:字典
返回值:方差分析相关数据
'''
res = { 'SSA':0, 'SST':0 }
mu = df[df.columns[1]].mean()
da = df.groupby( df.columns[0] ).agg( {df.columns[1]:['mean','count']})
da.columns = ['mean','count']
res['df_A'] = len(list(da.index)) - 1# 自由度
# 组间误差平方和
for row in da.index:
res['SSA'] += (da.loc[row,'mean'] - mu )**2 * da.loc[row,'count']
# 总误差平方和
for e in df[df.columns[1]].values:
res['SST'] += (e - mu )**2
res['SSE'] = res['SST'] - res['SSA']# 组内误差平方和
res['df_E'] = len(df) - res['df_A'] - 1# 残差自由度
res['df_T'] = len(df) - 1# 总和自由度
res['MSA'] = res['SSA'] / res['df_A']# 组间均方
res['MSE'] = res['SSE'] / res['df_E']# 组内均方
res['F'] = res['MSA'] / res['MSE']# F值
res['p_value'] = 1 - f(res['df_A'],res['df_E'] ).cdf( res['F'])#p值
res['a'] = a
res['F_alpha'] = f(res['df_A'],res['df_E'] ).ppf( 1-a ) # 基于显著性水平a的F临界值
return resdef print_ANOVA_oneway( d, maxedg = 90 ):
'''
打印单因素方差分析表
输入值:d - dict字典,包含分析表所需要的数据;
maxedg - 打印输出时装饰分隔符的最大长度
'''
title = '【单因素方差分析表】'
print( title.center( maxedg ))
print( '=' *maxedg )
print( '{:^12s}|{:^16s}|{:^6s}|{:^16s}|{:^12s}|{:^10s}|'.format('误差来源','平方和','自由度','均方和','F','p值'))
print( '-' *maxedg )
print( '{:8s}|{:>18,.4f} |{:>8d} |{:>18,.4f} |{:>11.6f} |{:>10.3%} |'.format( '组间(因子影响)',d['SSA'],d['df_A'],d['MSA'],d['F'],d['p_value']))
print( '{:10s}|{:>18,.4f} |{:>8d} |{:>18,.4f} |'.format( '组内(误差)',d['SSE'],d['df_E'],d['MSE']))
print( '{:14s}|{:>18,.4f} |{:>8d} |'.format( '总和',d['SST'],d['df_T']))
print( '-' *maxedg )
print('备注:显著性水平为 {:.2%} 时,F的临界值是 {:.6f}。'.format(d['a'],d['F_alpha']))p = 0.95 # 设定置信度水平
maxedg = 93 # 设定输出时装饰分隔符的最大长度
# 计算并输出单因素方差分析表
res = ANOVA_oneway( da, a = 1-p )
print_ANOVA_oneway( res, maxedg = maxedg )
文章图片
推荐阅读
- 慢慢的美丽
- Docker应用:容器间通信与Mariadb数据库主从复制
- 开学第一天(下)
- 奔向你的城市
- JS中的各种宽高度定义及其应用
- 学无止境,人生还很长
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- “成长”读书社群招募
- 继续努力,自主学习家庭Day135(20181015)