R:aov和lm方差分析的区别

在R中经常会用aov()和lm()两个函数进行方差分析,aov 函数的内核使用了lm算法,但二者有一定的区别。
aov() 默认(summary) 结果是基于Type I 平方和,而 lm() 默认(summary)的结果是Type III平方和。aov()分析的结果受自变量输入顺序的影响,而lm()与自变量输入顺序无关。当然这种差异是针对非平衡数据而言。对于平衡全处理的数据结构,二者分析的结果是一致的。

Ⅲ型平方和与Ⅰ型平方和

如果是等组设计,这几种平方和没有任何区别。不同类型的平方和是针对非等组设计提出的。需要通过线性模型来理解。

I型平方和也叫顺序平方和,需要考虑各主效应的进入顺序。但I型平方和不正交,顺序不同计算出的结果也不同,不推荐使用。

II型平方和叫偏序平方和,不考虑主效应顺序,但在计算主效应时不考虑交互作用。

如果各效应之间不存在交互作用,II型平方和效力较高III型平方和也叫正交平方和,不考虑顺序,但不能将总平方和完全分解。目前非等组设计中推荐使用的是III型平方和

anova函数r语言 r语言中aov函数_anova函数r语言


anova函数r语言 r语言中aov函数_平方和_02


anova函数r语言 r语言中aov函数_平方和_03

from statsmodels.formula.api import ols #拟合线性模型的包
from statsmodels.stats.anova import anova_lm#进行方差分析的包
import pandas as pd
import numpy as np
data={
    'XA1':  [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1],
    'XA2':  [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1],
    'XB1':  [1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1],
    'XAB11':[1,1,1,-1,-1,-1,-1,-1, 0,0,0,0, 0,0,0,0,0,-1,-1,-1,1,1,1,1],
    'XAB21':[0,0,0, 0,0,0,0,0,1,1,1,1, -1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1],
    'Y':[6,3,3,6,3,5,5,2,7,6,7,5,8,7,8,9,8,9,7,5,10,12,11,7],
    'A':[1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3],
    'B':[1,1,1,2,2,2,2,2,1,1,1,1,2,2,2,2,2,1,1,1,2,2,2,2]
}#其中前5行是虚拟变量,Y是观测值,A,B是分类变量
df=pd.DataFrame(data)
model_none=ols('Y~1',data=df).fit()#零模型,即没有任何效应
#-----------------首先进场的三种情况-----------------
model_A=ols('Y~XA1+XA2',data=df).fit()#只有A因素,即A先入场
model_B=ols('Y~XB1',data=df).fit()#只有B因素,即B先入场
#------------------其次进场的情况----------------------
model_AB=ols('Y~XA1+XA2+XB1',data=df).fit()#A,B主效应同时存在
#------------------最后进场,全模型-------------------------
model_full=ols('Y~XA1+XA2+XB1+XAB11+XAB21',data=df).fit()#全模型
#------------------以下为方差分析结果---------------------
model_anova_ABR=ols('Y~C(A,Sum)+C(B,Sum)+C(A,Sum):C(B,Sum)',data=df).fit()
#用分类变量进行方差分析,进场顺序为ABR
anova_Result_ABR=anova_lm(model_anova_ABR,typ=1)#此时选择Ⅰ型平方和

model_anova_BAR=ols('Y~C(B,Sum)+C(A,Sum)+C(A,Sum):C(B,Sum)',data=df).fit()
#用分类变量进行方差分析,进场顺序为BAR
anova_Result_BAR=anova_lm(model_anova_BAR,typ=1)#此时选择Ⅰ型平方和

先来计算进场顺序依次为A主效应,B主效应,AB交互作用的Ⅰ型平方和。看看结果如何

#以下计算进场顺序A-B-R的Ⅰ型平方和
SSEN=model_none.mse_resid*model_none.df_resid#零模型残差
SSEA=model_A.mse_resid*model_A.df_resid#A先进场模型残差
SSEAB=model_AB.mse_resid*model_AB.df_resid#AB模型残差,此时B第二个进场
SSEF=model_full.mse_resid*model_full.df_resid#全模型残差
SSA=SSEN-SSEA#A主效应
SSB=SSEA-SSEAB#B主效应
SSR=SSEAB-SSEF#交互作用效应
print('用回归计算的Ⅰ型平方和输出结果为:'
      '\nSSA:%.3f,\nSSB:%.3f,\nSSR:%.3f'%(SSA,SSB,SSR))
#依次打印A主效应平方和,B主效应平方和,交互作用平方和

用回归计算的Ⅰ型平方和输出结果为:
SSA:83.766,
SSB:15.226,
SSR:7.083
print('Ⅰ型平方和方差分析输出结果为:\n',anova_Result_ABR)#打印方差分析结果

Ⅰ型平方和方差分析输出结果为:
                        df     sum_sq    mean_sq          F    PR(>F)
C(A, Sum)             2.0  83.765873  41.882937  17.310973  0.000064
C(B, Sum)             1.0  15.226146  15.226146   6.293241  0.021911
C(A, Sum):C(B, Sum)   2.0   7.082981   3.541490   1.463762  0.257627
Residual             18.0  43.550000   2.419444        NaN       NaN
print('各主效应与交互作用平方和之和为:%.3f'%(np.sum(anova_Result_ABR.sum_sq[0:3])))

各主效应与交互作用平方和之和为:106.075

可见,此时用回归模型计算的结果与用方差分析计算的结果相同,注意此时的方差分析使用的是Ⅰ型平方和。而且Ⅰ型平方和的主效应与交互作用之和刚好等于组间平方和106.075

接下来再计算进场顺序为B主效应,A主效应,AB交互作用的Ⅰ型平方和看看

#以下计算进场顺序B-A-R的Ⅰ型平方和
SSEN=model_none.mse_resid*model_none.df_resid#零模型残差
SSEB=model_B.mse_resid*model_B.df_resid#B先进场模型残差
SSEAB=model_AB.mse_resid*model_AB.df_resid#AB模型残差,此时A第二个进场
SSEF=model_full.mse_resid*model_full.df_resid#全模型残差
SSA=SSEN-SSEB#A主效应
SSB=SSEB-SSEAB#B主效应
SSR=SSEAB-SSEF#交互作用效应
print('用回归计算的Ⅰ型平方和输出结果为:'
      '\nSSA:%.3f,\nSSB:%.3f,\nSSR:%.3f'%(SSA,SSB,SSR))
#依次打印A主效应平方和,B主效应平方和,交互作用平方和

用回归计算的Ⅰ型平方和输出结果为:
SSA:11.668,
SSB:87.324,
SSR:7.083
print('Ⅰ型平方和方差分析输出结果为:\n',anova_Result_BAR)#打印方差分析结果

Ⅰ型平方和方差分析输出结果为:
                        df     sum_sq    mean_sq          F    PR(>F)
C(B, Sum)             1.0  11.667857  11.667857   4.822536  0.041435
C(A, Sum)             2.0  87.324162  43.662081  18.046325  0.000050
C(A, Sum):C(B, Sum)   2.0   7.082981   3.541490   1.463762  0.257627
Residual             18.0  43.550000   2.419444        NaN       NaN
print('各主效应与交互作用平方和之和为:%.3f'%(np.sum(anova_Result_BAR.sum_sq[0:3])))

各主效应与交互作用平方和之和为:106.075

anova函数r语言 r语言中aov函数_统计学_04

详细阅读:用回归理解方差分析

为了更好理解这篇文章,你可能需要了解:

  • 两因素方差分析
  • 平方和的分解
  • 方差分析模型
  • 虚拟变量

双因素方差分析python

from statsmodels.formula.api import ols #拟合线性模型的包
from statsmodels.stats.anova import anova_lm#进行方差分析的包
import pandas as pd
import numpy as np
data={
    'XA1':  [1,1,1,1, 1, 1, 1, 1,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1],
    'XA2':  [0,0,0,0, 0, 0, 0, 0,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1],
    'XB1':  [1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1],
    'XAB11':[1,1,1,1,-1,-1,-1,-1,0,0,0,0,0,0,0,0,-1,-1,-1,-1,1,1,1,1],
    'XAB21':[0,0,0,0,0,0,0,0,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1],
    'Y':[5,3,4,2,6,3,5,5,7,6,7,8,8,7,8,5,9,7,5,7,10,12,11,7],
    'A':[1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3],
    'B':[1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2]
}#其中前5行是虚拟变量,Y是观测值,A,B是分类变量
df=pd.DataFrame(data)
model_lin=ols('Y~XA1+XA2+XB1+XAB11+XAB21',data=df).fit()#用虚拟变量进行回归
model_anova=ols('Y~C(A)*C(B)',data=df).fit()#用分类变量进行方差分析
anova_Result=anova_lm(model_anova)

print(anova_Result)

df     sum_sq    mean_sq          F    PR(>F)
C(A)        2.0  79.083333  39.541667  17.905660  0.000052
C(B)        1.0  12.041667  12.041667   5.452830  0.031315
C(A):C(B)   2.0   9.083333   4.541667   2.056604  0.156887
Residual   18.0  39.750000   2.208333        NaN       NaN
#利用方差分析结果计算决定系数,组间平方和(主效应与交互作用之和)/总平方和
R_square=np.sum(anova_Result.sum_sq[0:3])/np.sum(anova_Result.sum_sq)
print(R_square)

0.7159869008633524
#打印回归分析结果
print(model_lin.summary())

OLS Regression Results                            
==============================================================================
Dep. Variable:                      Y   R-squared:                       0.716
Model:                            OLS   Adj. R-squared:                  0.637
Method:                 Least Squares   F-statistic:                     9.075
Date:                Sat, 11 Apr 2020   Prob (F-statistic):           0.000191
Time:                        18:02:59   Log-Likelihood:                -40.109
No. Observations:                  24   AIC:                             92.22
Df Residuals:                      18   BIC:                             99.29
Df Model:                           5                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      6.5417      0.303     21.566      0.000       5.904       7.179
XA1           -2.4167      0.429     -5.633      0.000      -3.318      -1.515
XA2            0.4583      0.429      1.068      0.299      -0.443       1.360
XB1           -0.7083      0.303     -2.335      0.031      -1.346      -0.071
XAB11          0.0833      0.429      0.194      0.848      -0.818       0.985
XAB21          0.7083      0.429      1.651      0.116      -0.193       1.610
==============================================================================
Omnibus:                        1.556   Durbin-Watson:                   2.330
Prob(Omnibus):                  0.459   Jarque-Bera (JB):                1.295
Skew:                          -0.535   Prob(JB):                        0.523
Kurtosis:                       2.614   Cond. No.                         1.73
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
#利用回归模型输出各预测值
model_lin.predict()

array([ 3.5 ,  3.5 ,  3.5 ,  3.5 ,  4.75,  4.75,  4.75,  4.75,  7.  ,
        7.  ,  7.  ,  7.  ,  7.  ,  7.  ,  7.  ,  7.  ,  7.  ,  7.  ,
        7.  ,  7.  , 10.  , 10.  , 10.  , 10.  ])
#利用回归模型输出参数估计值
model_lin.params

Intercept    6.541667
XA1         -2.416667
XA2          0.458333
XB1         -0.708333
XAB11        0.083333
XAB21        0.708333
dtype: float64
#输出原始观测值的总均值
np.mean(df['Y'])

6.541666666666667

2 不等组设计的平方和Ⅲ型

from statsmodels.formula.api import ols #拟合线性模型的包
from statsmodels.stats.anova import anova_lm#进行方差分析的包
import pandas as pd
import numpy as np
data={
    'XA1':  [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1],
    'XA2':  [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1],
    'XB1':  [1,1,1,-1,-1,-1,-1,-1,1,1,1,1,-1,-1,-1,-1,-1,1,1,1,-1,-1,-1,-1],
    'XAB11':[1,1,1,-1,-1,-1,-1,-1, 0,0,0,0, 0,0,0,0,0,-1,-1,-1,1,1,1,1],
    'XAB21':[0,0,0, 0,0,0,0,0,1,1,1,1, -1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1],
    'Y':[6,3,3,6,3,5,5,2,7,6,7,5, 8,7,8,9,8, 9,7,5,10,12,11,7],
    'A':[1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3],
    'B':[1,1,1,2,2,2,2,2,1,1,1,1,2,2,2,2,2,1,1,1,2,2,2,2]
}#其中前5行是虚拟变量,Y是观测值,A,B是分类变量
df=pd.DataFrame(data)
model_full=ols('Y~XA1+XA2+XB1+XAB11+XAB21',data=df).fit()#全模型回归
model_A=ols('Y~XB1+XAB11+XAB21',data=df).fit()#去掉A因素主效应
model_B=ols('Y~XA1+XA2+XAB11+XAB21',data=df).fit()#去掉B因素主效应
model_R=ols('Y~XA1+XA2+XB1',data=df).fit()#去掉交互作用
model_anova=ols('Y~C(A,Sum)*C(B,Sum)',data=df).fit()#用分类变量进行方差分析
anova_Result=anova_lm(model_anova,typ=3)

SSE=model_full.mse_resid*model_full.df_resid#全模型残差
SSEA=model_A.mse_resid*model_A.df_resid#去A模型残差
SSEB=model_B.mse_resid*model_B.df_resid#去B模型残差
SSER=model_R.mse_resid*model_R.df_resid#去交互模型残差
print(SSEA-SSE,SSEB-SSE,SSER-SSE)
#依次打印A主效应平方和,B主效应平方和,交互作用平方和

74.03142710822807 15.639893617021286 7.082980539433265
print(anova_Result)#打印方差分析结果

sum_sq    df           F        PR(>F)
Intercept            993.384574   1.0  410.583751  7.687336e-14
C(A, Sum)             74.031427   2.0   15.299262  1.311731e-04
C(B, Sum)             15.639894   1.0    6.464250  2.041777e-02
C(A, Sum):C(B, Sum)    7.082981   2.0    1.463762  2.576274e-01
Residual              43.550000  18.0         NaN           NaN