在简单的线性模型(例如,单向或双向方差分析模型)中处理异方差实际上并不是很困难。
方差分析的稳健性
首先,正如其他人所指出的那样,方差分析对于偏离均等假设的偏差具有惊人的鲁棒性,尤其是当您具有近似平衡的数据(每组中的观察数相等)时。另一方面,对等方差的初步检验不是(尽管Levene的检验比教科书中通常讲授的F检验要好得多)。正如George Box所说:
对差异进行初步测试就像在划船中出海,以查明条件是否足够平静,以使远洋客轮离开港口!
尽管方差分析非常强大,但考虑到异方差性非常容易,没有理由不这样做。
非参数测试
如果您真的对均值差异感兴趣,那么非参数检验(例如Kruskal–Wallis检验)实际上没有任何用处。他们确实测试了组之间的差异,但通常不测试均值的差异。
示例数据
让我们生成一个简单的数据示例,在该示例中,我们希望使用ANOVA,但是假设均方差不成立。
set.seed(1232)
pop = data.frame(group=c("A","B","C"),
mean=c(1,2,5),
sd=c(1,3,4))
d = do.call(rbind, rep(list(pop),13))
d$x = rnorm(nrow(d), d$mean, d$sd)
我们分为三组,均值和方差都有(明显)差异:
stripchart(x ~ group, data=d)
方差分析
毫不奇怪,普通的方差分析可以很好地处理此问题:
> mod.aov = aov(x ~ group, data=d)
> summary(mod.aov)
Df Sum Sq Mean Sq F value Pr(>F)
group 2 199.4 99.69 13.01 5.6e-05 ***
Residuals 36 275.9 7.66
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
那么,哪些群体不同?让我们使用Tukey的HSD方法:
> TukeyHSD(mod.aov)
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = x ~ group, data = d)
$group
diff lwr upr p adj
B-A 1.736692 -0.9173128 4.390698 0.2589215
C-A 5.422838 2.7688327 8.076843 0.0000447
C-B 3.686146 1.0321403 6.340151 0.0046867
随着P的0.26 -值,我们不能要求A组和B即使我们之间的任何差别(在方法)并没有考虑到我们做了三个比较,我们就不会得到一个较低的P -值(P = 0.12):
> summary.lm(mod.aov)
[…]
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.5098 0.7678 0.664 0.511
groupB 1.7367 1.0858 1.599 0.118
groupC 5.4228 1.0858 4.994 0.0000153 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.768 on 36 degrees of freedom
这是为什么?根据剧情,还有就是一个很明显的区别。原因是,ANOVA在每个组中均假设为均方差,并且估计的通用标准偏差为2.77(在summary.lm
表中显示为“残差标准误差” ,也可以通过采用残差均方根的平方根(7.66)来得出)在ANOVA表中)。
但是A组的(人口)标准偏差为1,而2.77的高估使其(不必要)难以获得具有统计意义的结果,即,我们进行了(过)低功效的测试。
方差不等的“方差分析”
那么,如何拟合一个适当的模型,其中要考虑方差的差异?在R中很简单:
> oneway.test(x ~ group, data=d, var.equal=FALSE)
One-way analysis of means (not assuming equal variances)
data: x and group
F = 12.7127, num df = 2.000, denom df = 19.055, p-value = 0.0003107
因此,如果您想在R中运行简单的单向“ ANOVA”而不假设均等方差,请使用此函数。它基本上是(Welch)t.test()
对两个方差不相等的样本的扩展。
不幸的是,它不工作TukeyHSD()
(或大多数其他功能使用的aov
对象),所以即使我们可以肯定存在的群体差异,我们不知道在那里他们。
建模异方差
最好的解决方案是显式建模方差。在R中非常简单:
> library(nlme)
> mod.gls = gls(x ~ group, data=d,
weights=varIdent(form= ~ 1 | group))
> anova(mod.gls)
Denom. DF: 36
numDF F-value p-value
(Intercept) 1 16.57316 0.0002
group 2 13.15743 0.0001
当然,仍然存在重大差异。但是现在,A组和B组之间的差异也变得静态显着(P = 0.025):
> summary(mod.gls)
Generalized least squares fit by REML
Model: x ~ group
[…]
Variance function:
Structure: Different standard
deviations per stratum
Formula: ~1 | group
Parameter estimates:
A B C
1.000000 2.444532 3.913382
Coefficients:
Value Std.Error t-value p-value
(Intercept) 0.509768 0.2816667 1.809829 0.0787
groupB 1.736692 0.7439273 2.334492 0.0253
groupC 5.422838 1.1376880 4.766542 0.0000
[…]
Residual standard error: 1.015564
Degrees of freedom: 39 total; 36 residual
因此,使用适当的模型会有所帮助!还要注意,我们获得了(相对)标准偏差的估计值。A组的估计标准偏差可以在结果的底部1.02处找到。B组的估计标准偏差是此值的2.44倍,即2.48,C组的估计标准偏差类似地为3.97(键入intervals(mod.gls)
以获得B和C组的相对标准偏差的置信区间的类型)。
更正多次测试
但是,我们确实应该纠正多次测试。使用“ multcomp”库很容易。不幸的是,它没有对'gls'对象的内置支持,因此我们必须首先添加一些辅助函数:
model.matrix.gls <- function(object, ...)
model.matrix(terms(object), data = getData(object), ...)
model.frame.gls <- function(object, ...)
model.frame(formula(object), data = getData(object), ...)
terms.gls <- function(object, ...)
terms(model.frame(object),...)
现在开始工作:
> library(multcomp)
> mod.gls.mc = glht(mod.gls, linfct = mcp(group = "Tukey"))
> summary(mod.gls.mc)
[…]
Linear Hypotheses:
Estimate Std. Error z value Pr(>|z|)
B - A == 0 1.7367 0.7439 2.334 0.0480 *
C - A == 0 5.4228 1.1377 4.767 <0.001 ***
C - B == 0 3.6861 1.2996 2.836 0.0118 *
A组与B组之间仍存在统计学上的显着差异!☺我们甚至可以得到(同时)组均值之间差异的置信区间:
> confint(mod.gls.mc)
[…]
Linear Hypotheses:
Estimate lwr upr
B - A == 0 1.73669 0.01014 3.46324
C - A == 0 5.42284 2.78242 8.06325
C - B == 0 3.68615 0.66984 6.70245
使用近似(此处准确)的模型,我们可以相信这些结果!
请注意,对于这个简单的示例,C组的数据实际上并没有添加有关A组和B组之间差异的任何信息,因为我们为每个组建模了均值和标准差。我们可以只使用成对的t检验来校正多个比较:
> pairwise.t.test(d$x, d$group, pool.sd=FALSE)
Pairwise comparisons using t tests with non-pooled SD
data: d$x and d$group
A B
B 0.03301 -
C 0.00098 0.02032
P value adjustment method: holm
但是,对于更复杂的模型(例如双向模型或具有许多预测变量的线性模型),使用GLS(广义最小二乘)并对方差函数进行显式建模是最佳解决方案。
并且方差函数不必在每个组中简单地是一个不同的常数。我们可以对其施加结构。例如,我们可以将方差建模为每组均值的幂(因此仅需要估计一个参数,即指数),或者建模为模型中一个预测变量的对数。使用GLS(和gls()
R)非常简单。
广义最小二乘法是恕我直言,是一种未被充分利用的统计建模技术。不必担心与模型假设的偏差,而对那些偏差建模!
R
,在这里阅读我的回答都可以使您受益:异方差数据的单向方差分析的替代方法,该方法讨论了其中的一些问题。