En realidad, no es muy difícil manejar la heterocedasticidad en modelos lineales simples (p. Ej., Modelos ANOVA de una o dos vías).
Robustez de ANOVA
Primero, como otros han notado, el ANOVA es increíblemente robusto a las desviaciones del supuesto de variaciones iguales, especialmente si tiene datos aproximadamente equilibrados (igual número de observaciones en cada grupo). Las pruebas preliminares sobre variaciones iguales, por otro lado, no lo son (aunque la prueba de Levene es mucho mejor que la prueba F que se enseña comúnmente en los libros de texto). Como lo expresó George Box:
¡Hacer la prueba preliminar sobre las variaciones es como embarcarse en un bote de remos para averiguar si las condiciones son lo suficientemente tranquilas para que un transatlántico salga del puerto!
Aunque el ANOVA es muy robusto, ya que es muy fácil tener en cuenta la heterocedaticidad, hay pocas razones para no hacerlo.
Pruebas no paramétricas.
Si está realmente interesado en las diferencias de medias , las pruebas no paramétricas (p. Ej., La prueba de Kruskal-Wallis) realmente no sirven de nada. Lo hacen diferencias entre los grupos de prueba, pero lo hacen no en las diferencias generales de ensayo en los medios.
Datos de ejemplo
Generemos un ejemplo simple de datos donde uno quisiera usar ANOVA, pero donde la suposición de varianzas iguales no es cierta.
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)
Tenemos tres grupos, con diferencias (claras) tanto en medias como en variaciones:
stripchart(x ~ group, data=d)
ANOVA
No es sorprendente que un ANOVA normal maneje esto bastante bien:
> 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
Entonces, ¿qué grupos difieren? Usemos el método HSD de Tukey:
> 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
Con un valor P de 0.26, no podemos reclamar ninguna diferencia (en medias) entre el grupo A y B. E incluso si no tomáramos en cuenta que hicimos tres comparaciones, no obtendríamos un P bajo . valor ( 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
¿Porqué es eso? Sobre la base de la trama, no es una diferencia bastante clara. La razón es que ANOVA asume variaciones iguales en cada grupo y estima una desviación estándar común de 2.77 (mostrada como 'Error estándar residual' en la summary.lm
tabla, o puede obtenerla tomando la raíz cuadrada del cuadrado medio residual (7.66) en la tabla ANOVA).
Pero el grupo A tiene una desviación estándar (población) de 1, y esta sobreestimación de 2.77 hace que sea (innecesariamente) difícil obtener resultados estadísticamente significativos, es decir, tenemos una prueba con (demasiado) baja potencia.
'ANOVA' con variaciones desiguales
Entonces, ¿cómo ajustar un modelo adecuado, uno que tenga en cuenta las diferencias en las variaciones? Es fácil en 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
Por lo tanto, si desea ejecutar un simple 'ANOVA' unidireccional en R sin asumir variaciones iguales, use esta función. Básicamente es una extensión de (Welch) t.test()
para dos muestras con variaciones desiguales.
Por desgracia, no funciona con TukeyHSD()
(o la mayoría de las otras funciones que se utilizan en aov
los objetos), por lo que incluso si estamos seguros de que no hay diferencias entre los grupos, no sabemos donde están.
Modelando la heteroscedasticidad
La mejor solución es modelar las variaciones explícitamente. Y es muy fácil en 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
Todavía diferencias significativas, por supuesto. Pero ahora las diferencias entre el grupo A y B también se han vuelto estadísticamente significativas ( 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
¡Así que usar un modelo apropiado ayuda! También tenga en cuenta que obtenemos estimaciones de las desviaciones estándar (relativas). La desviación estándar estimada para el grupo A se puede encontrar en la parte inferior de los resultados, 1.02. La desviación estándar estimada del grupo B es 2.44 veces esto, o 2.48, y la desviación estándar estimada del grupo C es similar 3.97 (escriba intervals(mod.gls)
para obtener intervalos de confianza para las desviaciones estándar relativas de los grupos B y C).
Corrección para pruebas múltiples
Sin embargo, realmente deberíamos corregir las pruebas múltiples. Esto es fácil usando la biblioteca 'multcomp'. Desafortunadamente, no tiene soporte incorporado para objetos 'gls', por lo que primero tendremos que agregar algunas funciones auxiliares:
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),...)
Ahora manos a la obra:
> 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 *
Todavía diferencia estadísticamente significativa entre el grupo A y el grupo B! ☺ E incluso podemos obtener intervalos de confianza (simultáneos) para las diferencias entre las medias grupales:
> 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
Usando un modelo aproximadamente (aquí exactamente) correcto, ¡podemos confiar en estos resultados!
Tenga en cuenta que para este ejemplo simple, los datos para el grupo C realmente no agregan ninguna información sobre las diferencias entre el grupo A y B, ya que modelamos medias separadas y desviaciones estándar para cada grupo. Podríamos haber utilizado las pruebas t por pares corregidas para comparaciones múltiples:
> 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
Sin embargo, para modelos más complicados, por ejemplo, modelos de dos vías o modelos lineales con muchos predictores, usar GLS (mínimos cuadrados generalizados) y modelar explícitamente las funciones de varianza es la mejor solución.
Y la función de varianza no necesita ser simplemente una constante diferente en cada grupo; podemos imponerle estructura. Por ejemplo, podemos modelar la varianza como una potencia de la media de cada grupo (y, por lo tanto, solo necesitamos estimar un parámetro, el exponente), o tal vez como el logaritmo de uno de los predictores del modelo. Todo esto es muy fácil con GLS (y gls()
en R).
Los mínimos cuadrados generalizados son, en mi humilde opinión, una técnica de modelado estadístico muy poco utilizada. En lugar de preocuparse por las desviaciones de los supuestos del modelo, ¡ modele esas desviaciones!
R
, puede ser beneficioso leer mi respuesta aquí: Alternativas al ANOVA unidireccional para datos heteroscedasticos , que discute algunos de estos problemas.