参考书目:贾俊平. 统计学——Python实现. 北京: 高等教育出版社,2021.
方差分析的定义是检验分类型自变量对数值型因变量是否有显著性影响。
方差分析的简称是ANOVA,在心理学医学等领域运用很常见。
分类的自变量x称为因素、因子,而对应的因变量y均值是否相等则作为原假设,备择假设是不全相等。比如接下来举的这个的例子就是分析不同品种的小麦的产量。品种就是分类型自变量x,产量就是数值型因变量y。
下面进行代码演示,先导入包,读取案例数据
- import pandas as pd
- example8_1=pd.read_csv("example8_1.csv",encoding="gbk")
- example8_1
数据前几行
由于这个数据的类别变量在列上面,三个品种三列。要把他们变为一列上
数据融合
- example8_2=pd.melt(example8_1,value_vars=example8_1.columns,var_name='品种',value_name='产量') #融合数据
- example8_2.to_csv("example8_2.csv",encoding="gbk",index=True) #保存融合后的数据
- example8_2.head() #展示数据前5行
拟合单因子方差分析模型并输出方差分析表
- # 拟合单因子方差分析模型并输出方差分析表
- from statsmodels.formula.api import ols
- from statsmodels.stats.anova import anova_lm
- #example8_2=pd.read_csv("example8_2.csv",encoding="gbk")
- model = ols(formula='产量~品种',data=example8_2).fit() #拟合方差分析模型
- anova_lm(model,typ=1)
使用summary函数输出模型摘要
print(model.summary())
品种2 的p小于0.05,说明品种2和1之间的均值存在显著性差异,而3和1之间不存在显著性差异。
画图
- import matplotlib.pyplot as plt
- plt.rcParams ['font.sans-serif'] ='SimHei' #显示中文
- plt.rcParams ['axes.unicode_minus']=False #显示负号
- mean= model.params.values[0]
- lci,uci = model.conf_int().iloc[0].values
- df_mean=pd.DataFrame([lci,mean,uci],index=['lci','mean','uci'],columns=['品种1'])
- df_mean['品种2']=df_mean['品种1']+model.params.values[1]
- df_mean['品种3']=df_mean['品种1']+model.params.values[2]
- ax=df_mean.T.plot(ls='',marker='o',legend=False,c='black',figsize=(9,6),xlabel='品种',ylabel='产量')
- ax = df_mean.loc['mean'].plot()
前面的方差分析原假设是全部一样,如果拒绝原假设就是三个不全相等,但是不知道到底是谁和谁之间有差异,使用要进行多重比较。
- from statsmodels.stats.multicomp import MultiComparison
- mc = MultiComparison(example8_2['产量'],groups=example8_2['品种'])
- print(mc.tukeyhsd(alpha=0.05))
看最后一列就知道1和2 ,2和3之间有差异。1和3之间没有差异。
上面这个只是一个因素的方差分析,即一个变量的方差分析。还有两个变量,或者更多类别变量之间的分析。而且变量之间可能存在交互效应。具体实现会有很多计算细节。但由于这些方法不常用,较为复杂,所以不展示了。
目前这些传统的统计学方法还是有很多局限之处,而且数学公式较为复杂,对于这些 表格数据 使用现在的机器学习方法会更好。对于这种分类变量,可以使用决策树,随机森林,梯度提升等算法寻找分类变量的重要性程度。可以参考我之前的机器学习版块的文章。