欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

方差分析原理及python演练

程序员文章站 2022-04-18 12:47:57
...

前言

检验多个总体均值是否相等,通过分析察数据的误差判断各总体均值是否相等

相关概念:
  • 因素或因子(factor):所要检验的对象,要分析行业对投诉次数是否有影响,行业是要检验的因素或因子
  • 水平或处理(treatment):因素的不同表现,即每个自变量的不同取值称为因素的水平
  • 观察值:在每个因素水平下得到的样本值,每个行业被投诉的次数就是观察值
  • 试验:这里只涉及一个因素,因此称为单因素四水平的试验
  • 总体:因素的每一个水平可以看作是一个总体,比如零售业、旅游业、航空公司、家电制造业可以看作是四个总体
  • 样本数据:被投诉次数可以看作是从这四个总体中抽取的样本数据

实例
为了对几个行业的服务质量进行评价,消费者协会在四个行业分别抽取了不同的企业作为样本。最近一年中消费者对总共23家企业投诉的次数如下表
方差分析原理及python演练

实例分析

分析四个行业之间的服务质量是否有显著差异,也就是要判断“行业”对“投诉次数”是否有显著影响

如果它们的均值相等,就意味着“行业”对投诉次数是没有影响的,即它们之间的服务质量没有显著差异;如果均值不全相等,则意味着“行业”对投诉次数是有影响的,它们之间的服务质量有显著差异

先看下散点图分布情况

F=[1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4]
S=[57,66,49,40,34,53,44,68,39,29,45,56,51,31,49,21,34,40,44,51,65,77,58]
df=pd.DataFrame(np.array(data).T,columns=["F","S"])
avg=df.groupby(["F"])["S"].mean()
plt.scatter(df["F"],df["S"])
plt.scatter(avg.index,avg,color='red')

方差分析原理及python演练

  • 不同行业被投诉的次数是有明显差异的
  • 即使是在同一个行业,不同企业被投诉的次数也明显不同
  • 家电制造也被投诉的次数较高,航空公司被投诉的次数较低
  • 行业与被投诉次数之间有一定的关系
问题
  • 仅从散点图上观察还不能提供充分的证据证明不同行业被投诉的次数之间有显著差异
  • 这种差异也可能是由于抽样的随机性所造成的
  • 需要有更准确的方法来检验这种差异是否显著,也就是进行方差分析
  • 之所以叫方差分析,因为虽然我们感兴趣的是均值,但在判断均值之间是否有差异时则需要借助于方差

基本思想

基本概念
  • 比较两类误差,以检验均值是否相等
  • 比较的基础是方差比
  • 如果系统(处理)误差显著地不同于随机误差,则均值就是不相等的;反之,均值就是相等的

水平的均值
假定从第i个总体中抽取一个容量为nin_i的简单随机样本,第i个总体的样本均值为该样本的全部观察值总和除以观察值的个数
xi=j=1nini\overline{x}_i=\frac{\sum_{j=1}^{n_i}}{n_i}
全部观察值的总均值
全部观察值的总和除以观察值的总个数
x=i=1kj=1nixijn\overline{\overline{x}}=\frac{\sum_{i=1}^k\sum_{j=1}^{n_i}x_{ij}}{n}
n=i=1nnin=\sum_{i=1}^nn_i

随机误差:
  • 因素的同一水平(总体)下,样本各观察值之间的差异

  • 比如,同一行业下不同企业被投诉次数是不同的

  • 这种差异可以看成是随机因素的影响,称为随机误差

系统误差:
  • 因素的不同水平(不同总体)下,各观察值之间的差异
  • 比如,不同行业之间的被投诉次数之间的差异
  • 这种差异可能是由于抽样的随机性所造成的,也可能是由于行业本身所造成的,后者所形成的误差是由系统性因素造成的,称为系统误差
组内方差:

SSE=i=1kj=1ni(xijxi)2SSE=\sum_{i=1}^k\sum_{j=1}^{n_i}(x_{ij}-\overline{x}_i)^2

  • 因素的同一水平(同一个总体)下样本数据的方差
  • 比如,零售业被投诉次数的方差
  • 组内方差只包含随机误差
组间方差:

SSE=i=1kni(xix)2SSE=\sum_{i=1}^kn_i(\overline{x}_{i}-\overline{\overline{x}})^2
nin_i为第i个总体样本观察值的个数

  • 因素的不同水平(不同总体)下各样本之间的方差
  • 比如,四个行业被投诉次数之间的方差
  • 组间方差既包括随机误差,也包括系统误差
总误差平方和 SST:

全部观察值与总平均值的离差平方和,反映全部观察值的离散状况
SST=i=1kj=1ni(xijx)2=SSA+SSESST=\sum_{i=1}^k\sum_{j=1}^{n_i}(x_{ij}-\overline{\overline{x}})^2=SSA+SSE

方差的比较:
  • 若不同行业对投诉次数没有影响,则组间误差中只包含随机误差,没有系统误差。这时,组间误差与组内误差经过平均后的数值就应该很接近,它们的比值就会接近1

  • 若不同行业对投诉次数有影响,在组间误差中除了包含随机误差外,还会包含有系统误差,这时组间误差平均后的数值就会大于组内误差平均后的数值,它们之间的比值就会大于1

  • 这个比值大到某种程度时,就可以说不同水平之间存在着显著差异,也就是自变量对因变量有影响

  • 判断行业对投诉次数是否有显著影响,实际上也就是检验被投诉次数的差异主要是由于什么原因所引起的。如果这种差异主要是系统误差,说明不同行业对投诉次数有显著影响

方差分析的前提:
每个总体都应服从正态分布
  • 对于因素的每一个水平,其观察值是来自服从正态分布总体的简单随机样本
  • 比如,每个行业被投诉的次数必需服从正态分布
各个总体的方差必须相同
  • 各组观察数据是从具有相同方差的总体中抽取的
  • 比如,四个行业被投诉次数的方差都相等
观察值是独立的
  • 比如,每个行业被投诉的次数与其他行业被投诉的次数独立

在上述假定条件下,判断行业对投诉次数是否有显著影响,实际上也就是检验具有同方差的四个正态总体的均值是否相等

假设检验

原假设成立,即H0: μ1 = μ2 = μ3 = μ4
假设检验的理解可以参见:https://blog.csdn.net/Andy_shenzl/article/details/81453509

  • 四个行业被投诉次数的均值都相等意味着每个样本都来自均值为μ、方差为σ^2的同一正态总体
    方差分析原理及python演练

备择假设成立,即H1: μ1 μ2 μ3 μ4 不完全相等

  • 至少有一个总体的均值是不同的,四个样本分别来自均值不同的四个正态总体

SST反映全部数据总的误差程度;SSE反映随机误差的大小;SSA反映随机误差和系统误差的大小
如果原假设成立,则表明没有系统误差,组间平方和SSA除以*度后的均方与组内平方和SSE和除以*度后的均方差异就不会太大;如果组间均方显著地大于组内均方,说明各水平(总体)之间的差异不仅有随机误差,还有系统误差,判断因素的水平是否对其观察值有影响,实际上就是比较组间方差与组内方差之间差异的大小

均方MS

各误差平方和的大小与观察值的多少有关,为消除观察值多少对误差平方和大小的影响,需要将其平均,这就是均方,也称为方差,计算方法是用误差平方和除以相应的*度

各自*度
  • SST 的*度为n-1,其中n为全部观察值的个数

  • SSA的*度为k-1,其中k为因素水平(总体)的个数

  • SSE 的*度为n-k

F统计量

将MSA(组间方差,SSA的均方,记为MSA)和MSE(组内方差,SSE的均方,记为MSE)进行对比,即得到所需要的检验统计量F

F=MSAMSE F(k1,nk)F=\frac{MSA}{MSE} ~ F(k-1,n-k)

求解一下上例的F值

def SSE(a,b):
    s=0
    A=np.array(a)
    #总体均值
    avg_t=np.mean(b)
    for x in set(a):
        #先求组内均值
        avg_i=sum(np.where(A==x,b,0))/a.count(x)
        s=s+a.count(x)*pow(avg_i-avg_t,2)
    return s
    
def SSA(a,b):
    s=0
    A=np.array(a)
    for x in set(a):
        #先求组内均值
        avg_i=sum(np.where(A==x,b,0))/a.count(x)
        #取出第i组的值
        B=np.array(S)[np.where(list(np.where(A==x,b,0)))]
        #print(B)
        for y in B:
            s=s+pow(y-avg_i,2)
            
    return s
def F_s(a,b):
    k=len(set(a))
    n=len(a)
    f=(SSE(F,S)/(k-1))/(SSA(F,S)/(n-k))
    return f
F_s(F,S)

3.4066426904716036

根据给定的显著性水平,在F分布表中查找与第一*度df1=k-1、第二*度df2=n-k 相应的临界值

  • 若F>Fα ,则拒绝原假设H0 ,表明均值之间的差异是显著的,所检验的因素对观察值有显著影响
  • 若F<Fα ,则不拒绝原假设H0 ,不能认为所检验的因素对观察值有显著影响

方差分析中的多重比较

  • 通过对总体均值之间的配对比较来进一步检验到底哪些均值之间存在差异

  • 可采用Fisher提出的最小显著差异方法,简写为LSD

  • LSD方法是对检验两个总体均值是否相等的t检验方法的总体方差估计而得到的

LSD方法:

对k组中的两组的平均数进行比较,当两组样本容量分别为ni,nj都为时,有
t=XiXjMSE(1ni+1nj) t(dfw)t=\frac{\overline{X_i}-\overline{X_j}}{\sqrt{MSE(\frac1{n_i}+\frac1{n_j})}}~t(df_w)
如果XiXj>ta/2MSE(1ni+1nj)|\overline{X_i}-\overline{X_j}|>t_{a/2}\sqrt{MSE(\frac1{n_i}+\frac1{n_j})}则认为u1u_1u2u_2有显著差异,否则认为没有显著差异

LSD法进行的是两两比较的t检验。所不同的是,在满足方差齐性的前提下,LSD法采用所有样本的联合方差来估计均数差的标准误,而不是要比较的两个样本的联合方差

当两组均数差大于LSD时,说明差异达到显著的水平,也就可以拒绝零假设,认为两组均数不相等。需要注意的是,LSD法单次比较的检验水准仍然为α\alpha。LSD法检验的灵敏度最高,但是会因为对比的频数增加使得第一类型错误概率增加。为解决该问题,便出现了Sidak法和Bonferroni法。

https://blog.csdn.net/huangguohui_123/article/details/103966000

多因素方差分析

无交互效应的多因素方差分析
有交互效应的多因素方差分析

主效应与交互效应

主效应(main effect):各个因素对观测变量的单独影响称为主效应。
交互效应(interaction effect):各个因素不同水平的搭配所产生的新的影响称为交互效应。

双因素方差分析的类型

双因素方差分析中因素A和B对结果的影响相互独立时称为无交互效应的双因素方差分析。
如果除了A和B对结果的单独影响外还存在交互效应,这时的双因素方差分析称为有交互效应的双因素方差分析 。

无交互效应的双因素方差分析模型

离差平方和的分解:
方差分析原理及python演练

有交互效应的双因素方差分析模型

离差平方和的分解:
方差分析原理及python演练
方差分析原理及python演练

双因素方差分析的步骤
提出假设
  • 要说明因素A有无显著影响,就是检验如下假设:

H0:因素A不同水平下观测变量的总体均值无显著差异。

H1:因素A不同水平下观测变量的总体均值存在显著差异。

  • 要说明因素B有无显著影响,就是检验如下假设:

H0:因素B不同水平下观测变量的总体均值无显著差异。

H1:因素B不同水平下观测变量的总体均值存在显著差异。

  • 在有交互效应的双因素方差中,要说明两个因素的交互效应是否显著,还要检验第三组零假设和备择假设:

H0:因素A和因素B的交互效应对观测变量的总体均值无显著差异。

H1:因素A和因素B的交互效应对观测变量的总体均值存在显著差异。

构造统计量

在原假设成立的情况下,三个统计量分别服从*度为(r-1,rs(m-1))、(s-1,rs(m-1))、((r-1)(s-1),rs(m-1))的F分布。
FA=MSAMSE,FB=MSBMSE,FAB=MSABMSEF_A=\frac{MSA}{MSE}\,, F_B=\frac{MSB}{MSE} \,,F_{AB}=\frac{MSAB}{MSE}

利用原假设和样本数据分别计算3个F统计量的值和其对应的p值,对比p值和α,结合原假设作出推断。若p<α,则拒绝关于这个因素的原假设,得出此因素不同水平下观测变量各总体均值存在显著差异的结论。

实例演示
# # 呷哺呷哺2个因素:环境等级,食材等级
from scipy import stats  
import pandas as pd  
import numpy as np  
from statsmodels.formula.api import ols  
from statsmodels.stats.anova import anova_lm  

  
environmental =  [5,5,5,5,5,4,4,4,4,4,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1]       
ingredients    = [5,4,3,2,1,5,4,3,2,1,5,4,3,2,1,5,4,3,2,1,5,4,3,2,1]    
score      =     [5,5,4,3,2,5,4,4,3,2,4,4,3,3,2,4,3,2,2,2,3,3,3,2,1]  
  
data = {'E':environmental, 'I':ingredients, 'S':score}  
df = pd.DataFrame(data)  

formula = 'S~E+I+E:I'                           
                                                 
model = ols(formula,df).fit()                   
results = anova_lm(model)                       
print (results) 
         df  sum_sq    mean_sq           F        PR(>F)
E          1.0    7.22   7.220000   54.539568  2.896351e-07
I          1.0   18.00  18.000000  135.971223  1.233581e-10
E:I        1.0    0.64   0.640000    4.834532  3.924030e-02
Residual  21.0    2.78   0.132381         NaN           NaN

E和I对结果有显著影响,之间有交互