异方差数据的单向方差分析的替代方法


36

我有3个藻类生物量(,,)的数据,它们包含不相等的样本大小(,,),我想比较一下这两个组是否来自同一种群。ABCnA=15nB=13nC=12

单向ANOVA绝对是必经之路,但是在对我的数据进行正态性测试时,异质性似乎是主要问题。我的原始数据未经任何转换就产生了方差比(),该比率远高于临界值(F _ {\ rm crit} = 4.16),因此我无法执行单向方差分析。Fmax=19.1Fcrit=4.16

我还尝试了转换以标准化我的数据。即使经过各种变换(对数,平方根,平方)的试验,使用\ log_ {10}变换进行变换后产生的最低F _ {\ max}也为7.16,与F _ {\ rm crit}相比仍然更高。Fmaxlog107.16Fcrit

这里有人可以建议我从这里出发吗?我想不出其他通过数据标准化的转换方法。有单向方差分析的替代方法吗?

PS:我的原始数据如下:

A: 0.178 0.195 0.225 0.294 0.315 0.341 0.36  0.363 0.371 0.398 0.407 0.409 0.432 
   0.494 0.719
B: 0.11  0.111 0.204 0.416 0.417 0.441 0.492 0.965 1.113 1.19  1.233 1.505 1.897
C: 0.106 0.114 0.143 0.435 0.448 0.51  0.576 0.588 0.608 0.64  0.658 0.788 0.958

2
F检验清楚地表明,这些群体并非来自同一人群。下一步将是解释此结果,首先是对分组分解的数据进行清晰的可视化显示和定量描述。
ub

硬币包装中也有置换测试。对于ANOVA,它将是oneway_test函数。快速R示例:statmethods.net/stats/resampling.html
user16263

Answers:


73

处理异方差数据时,有许多选项可用。不幸的是,它们中的任何一个都不能保证始终有效。这是我熟悉的一些选项:

  • 转变
  • 韦尔奇方差分析
  • 加权最小二乘
  • 稳健回归
  • 异方差一致性标准误
  • 引导程序
  • Kruskal-Wallis检验
  • 有序逻辑回归

更新: 当您具有方差的异方差/异质性时,这是一些拟合线性模型的方式的演示R (即ANOVA或回归)。

让我们开始看看您的数据。为了方便起见,我将它们加载到两个数据帧中,它们称为my.data(结构如上,每组一列)和stacked.data(具有两列:values数字和ind组指示符)。

我们可以使用Levene检验来正式测试异方差

library(car)
leveneTest(values~ind, stacked.data)
# Levene's Test for Homogeneity of Variance (center = median)
#       Df F value   Pr(>F)   
# group  2  8.1269 0.001153 **
#       38                    

当然,您具有异方差性。我们将检查各组的差异。经验法则是,线性模型对方差的异质性相当鲁棒,只要最大方差不大于最小方差的,因此我们也可以找到该比率: 4×

apply(my.data, 2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.01734578 0.33182844 0.06673060 
var(my.data$B, na.rm=T) / var(my.data$A, na.rm=T)
# [1] 19.13021

你的变化很大不同,最大的,B,是最小,。这是异性恋的一个有问题的水平。 19×A

你曾想过使用转换,如日志或平方根稳定方差。在某些情况下可以使用,但是Box-Cox类型转换通过不对称地挤压数据,以最高的数据挤压最多的方式向下挤压它们或以最低的数据挤压最多的方式向上挤压它们来稳定方差。因此,您需要数据的方差随均值而变化,以使其最佳工作。您的数据方差差异很大,但均值和中位数之间的差异相对较小,即分布大多重叠。作为教学练习,我们可以parallel.universe.data通过在所有值上加上在值上加上来创建一些值2.7B.7C以显示其工作方式:

parallel.universe.data = with(my.data, data.frame(A=A, B=B+2.7, C=C+.7))
apply(parallel.universe.data,       2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.01734578 0.33182844 0.06673060 
apply(log(parallel.universe.data),  2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.12750634 0.02631383 0.05240742 
apply(sqrt(parallel.universe.data), 2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.01120956 0.02325107 0.01461479 
var(sqrt(parallel.universe.data$B), na.rm=T) / 
var(sqrt(parallel.universe.data$A), na.rm=T)
# [1] 2.074217

使用平方根变换可以很好地稳定这些数据。您可以在此处查看并行Universe数据的改进:

在此处输入图片说明

不仅仅是尝试不同的转换,更系统的方法是优化Box-Cox参数(尽管通常建议将其四舍五入到最接近的可解释转换)。在您的情况下,平方根或对数都是可以接受的,尽管实际上都无效。对于并行Universe数据,平方根最好: λλ=.5λ=0

boxcox(values~ind, data=stacked.data,    na.action=na.omit)
boxcox(values~ind, data=stacked.pu.data, na.action=na.omit) 

在此处输入图片说明

由于这种情况是ANOVA(即没有连续变量),因此处理异质性的一种方法是在检验(分数nb ,而不是)中对分母的自由度使用Welch校正Fdf = 19.445df = 38

oneway.test(values~ind, data=stacked.data, na.action=na.omit, var.equal=FALSE)
#  One-way analysis of means (not assuming equal variances)
# 
# data:  values and ind
# F = 4.1769, num df = 2.000, denom df = 19.445, p-value = 0.03097

更通用的方法是使用加权最小二乘。由于某些组(B)分布更多,因此与其他组中的数据相比,这些组中的数据提供的均值位置信息较少。通过为每个数据点提供权重,我们可以让模型将其合并。一个常见的系统是使用组方差的倒数作为权重:

wl = 1 / apply(my.data, 2, function(x){ var(x, na.rm=T) })
stacked.data$w = with(stacked.data, ifelse(ind=="A", wl[1], 
                                           ifelse(ind=="B", wl[2], wl[3])))
w.mod = lm(values~ind, stacked.data, na.action=na.omit, weights=w)
anova(w.mod)
# Response: values
#           Df Sum Sq Mean Sq F value  Pr(>F)  
# ind        2   8.64  4.3201  4.3201 0.02039 *
# Residuals 38  38.00  1.0000                  

与未加权的方差分析(,)相比,这产生的和略有不同,但是很好地解决了异质性: Fp4.50890.01749

在此处输入图片说明

但是,加权最小二乘不是万能药。一个令人不安的事实是,只有权重正确才是正确的,这意味着,除其他外,这些权重是先验的。它也不能解决非正态(例如偏斜)或异常值。但是,使用从数据估算的权重通常会很好地工作,特别是如果您有足够的数据来以合理的精度估算方差(这类似于在有或时使用表而不是表的想法zt50100自由度),您的数据就足够正常,并且您似乎没有任何异常值。不幸的是,您的数据相对较少(每组13或15),有些偏斜,可能还有一些异常值。我不确定这些值是否足以造成很大的损失,但是您可以将加权最小二乘与稳健的方法混合使用。您可以使用四分位间距的倒数(不受每组中多达50%的离群值的影响),而不必使用方差作为散布的度量值(对离群值敏感,尤其是在低的情况下比较敏感)。然后,可以使用不同的损失函数(如Tukey的bisquare)将这些权重与稳健的回归相结合: N

1 / apply(my.data,       2, function(x){ var(x, na.rm=T) })
#         A         B         C 
# 57.650907  3.013606 14.985628 
1 / apply(my.data,       2, function(x){ IQR(x, na.rm=T) })
#        A        B        C 
# 9.661836 1.291990 4.878049 

rw = 1 / apply(my.data, 2, function(x){ IQR(x, na.rm=T) })
stacked.data$rw = with(stacked.data, ifelse(ind=="A", rw[1], 
                                            ifelse(ind=="B", rw[2], rw[3])))
library(robustbase)
w.r.mod = lmrob(values~ind, stacked.data, na.action=na.omit, weights=rw)
anova(w.r.mod, lmrob(values~1,stacked.data,na.action=na.omit,weights=rw), test="Wald")
# Robust Wald Test Table
# 
# Model 1: values ~ ind
# Model 2: values ~ 1
# Largest model fitted by lmrob(), i.e. SM
# 
#   pseudoDf Test.Stat Df Pr(>chisq)  
# 1       38                          
# 2       40    6.6016  2    0.03685 *

这里的权重并不是那么极端。预测组的装置稍有不同(A:WLS 0.36673,鲁棒0.35722; B:WLS 0.77646,健壮0.70433; C:WLS 0.50554,鲁棒0.51845)中,用的装置BC通过极值被较少拉动。

在计量经济学中,Huber-White(“三明治”)标准误差非常普遍。像Welch校正一样,这不需要您先验方差,也不需要您根据数据和/或可能不正确的模型估算权重。另一方面,我不知道如何将其与方差分析相结合,这意味着您只能将它们用于单个伪代码的测试,这使我在这种情况下不太有用,但无论如何我将向他们展示:

library(sandwich)
mod = lm(values~ind, stacked.data, na.action=na.omit)
sqrt(diag(vcovHC(mod)))
# (Intercept)        indB        indC 
#  0.03519921  0.16997457  0.08246131 
2*(1-pt(coef(mod) / sqrt(diag(vcovHC(mod))), df=38))
#  (Intercept)         indB         indC 
# 1.078249e-12 2.087484e-02 1.005212e-01 

该函数vcovHC为您的beta(您的虚拟代码)计算一个异方差一致的方差-协方差矩阵,这就是函数调用中的字母所代表的含义。要获取标准误差,请提取主对角线并取平方根。要获得Beta的检验,请将系数估算值除以SE,然后将结果与适当的(即带有剩余自由度的)进行比较。 ttt

对于R特定的用户,@ TomWenseleers在下面的注释中指出,程序包中的?Anova函数car可以接受white.adjust参数,以使用异方差一致错误获取因子的值。 p

Anova(mod, white.adjust=TRUE)
# Analysis of Deviance Table (Type II tests)
# 
# Response: values
#           Df      F  Pr(>F)  
# ind        2 3.9946 0.02663 *
# Residuals 38                 
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

您可以尝试通过自举来获得对测试统计量的实际抽样分布情况的经验估计。首先,通过使所有组均值完全相等来创建一个真正的null。然后,用替换进行重新采样,并在每个引导样本上计算测试统计量(),以得到在数据为零的情况下的抽样分布的经验估计,无论其状态是正常还是均匀。值等于或大于观察到的检验统计量的抽样分布比例是值: FFp

mod    = lm(values~ind, stacked.data, na.action=na.omit)
F.stat = anova(mod)[1,4]
  # create null version of the data
nullA  = my.data$A - mean(my.data$A)
nullB  = my.data$B - mean(my.data$B, na.rm=T)
nullC  = my.data$C - mean(my.data$C, na.rm=T)
set.seed(1)
F.vect = vector(length=10000)
for(i in 1:10000){
  A = sample(na.omit(nullA), 15, replace=T)
  B = sample(na.omit(nullB), 13, replace=T)
  C = sample(na.omit(nullC), 13, replace=T)
  boot.dat  = stack(list(A=A, B=B, C=C))
  boot.mod  = lm(values~ind, boot.dat)
  F.vect[i] = anova(boot.mod)[1,4]
}
1-mean(F.stat>F.vect)
# [1] 0.0485

在某些方面,自举是进行参数(例如均值)分析的最终简化假设方法,但它确实假设您的数据很好地代表了总体,这意味着您拥有合理的样本量。由于您的很小,因此可能不太值得信赖。针对非正态性和异质性的最终保护措施可能是使用非参数检验。方差分析的基本非参数版本是Kruskal-Wallis检验n

kruskal.test(values~ind, stacked.data, na.action=na.omit)
#  Kruskal-Wallis rank sum test
# 
# data:  values by ind
# Kruskal-Wallis chi-squared = 5.7705, df = 2, p-value = 0.05584

尽管Kruskal-Wallis检验绝对是抵御I型错误的最佳方法,但它只能与单个类别变量一起使用(即,没有连续的预测变量或阶乘设计),并且在所讨论的所有策略中作用最小。另一种非参数方法是使用有序逻辑回归。这对很多人来说似乎很奇怪,但是您只需要假设您的响应数据包含合法的序数信息,他们肯定会这样做,否则上述其他所有策略也都无效:

library(rms)
olr.mod = orm(values~ind, stacked.data)
olr.mod
# Model Likelihood          Discrimination          Rank Discrim.    
# Ratio Test                 Indexes                Indexes       
# Obs            41    LR chi2      6.63    R2                  0.149    rho     0.365
# Unique Y       41    d.f.            2    g                   0.829
# Median Y    0.432    Pr(> chi2) 0.0363    gr                  2.292
# max |deriv| 2e-04    Score chi2   6.48    |Pr(Y>=median)-0.5| 0.179
#                      Pr(> chi2) 0.0391

从输出中可能不清楚,但是整个模型的测试(在本例中是您组的测试)是chi2under Discrimination Indexes。列出了两个版本,似然比测试和得分测试。似然比测试通常被认为是最好的。产生一个值。 p0.0363


1
爱你的答案!现在有一丝微光可以处理我的数据!:)在所有这些方法中,您强烈建议使用哪种数据,特别是提供足够统计能力的术语?我不太热衷于使用非参数方法,即Kruskal-Wallis测试,因为那将意味着我可能会犯I型错误?如果我错了纠正我。
里克·L.

2
如果有机会,我将在这里整理更多材料,但没有,Kruskal-Wallis测试可能为您提供最佳的保护,以防止I型错误。OTOH,它可能不是您拥有的最强大的选项。
gung-恢复莫妮卡

4
请注意,在库中car,还有一个选项可以设置white.adjust=T为使用经过怀特调整的经异方差校正的标准误差来处理异方差性
Tom Wenseleers 2014年

3
是的,它只是提到它lm的,但它也似乎工作aov的(选项white.adjustwhite.adjust=c(FALSE, TRUE, "hc3", "hc0", "hc1", "hc2", "hc4")-更多信息见?hccm
汤姆Wenseleers

1
@Nakx,不,不是我所知道的。这是一个经验法则;它不太可能出现在统计文献的论文中。它可能在一些入门教科书中。
gung-恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.