9 votos

¿Cuándo es útil la codificación de la desviación?

Después de muchos años de aprendizaje sobre los contrastes en los modelos lineales, tengo curiosidad por la utilidad relativa de la codificación de la desviación, tal y como la define este sitio web . Agradecería que alguien me informara de algunas cosas. He aquí un ejercicio de simulación de datos para poner de manifiesto el origen de mi confusión. Quiero simular datos en los que hay un predictor categórico de dos niveles ( group ) y un predictor continuo ( pred ). He programado en las diferencias entre grupos la relación de ambos predictores con la variable de resultado ( outcome ).

# toy data

set.seed(0001)

# two variables with a .7 correlation, where mean of outcome variable is 0
mu1 <- c(0,0)
Sigma1 <- matrix(.7, nrow=2, ncol=2) + diag(2)*.3 
rawvars1 <- as.data.frame(MASS::mvrnorm(n=100, mu=mu1, Sigma=Sigma1))
names(rawvars1) <- c("pred", "outcome")

# two variables with a .3 correlation where mean of outcome variable is 4
mu2 <- c(0,4)
Sigma2 <- matrix(.3, nrow = 2, ncol = 2) + diag(2)*.7
rawvars2 <- as.data.frame(MASS::mvrnorm(n=100, mu=mu2, Sigma=Sigma2))
names(rawvars2) <- c("pred", "outcome")

# bind dataframes and add a grouping variable 
df <- rbind(rawvars1, rawvars2)
df$group <- factor(rep(letters[1:2], each = 100))

Comprobemos que hemos hecho lo que pretendíamos obteniendo el pred-outcome correlaciones en cada nivel de grupo

by(df, df$group, function (i) cor.test(i$outcome, i$pred))

Bien. Las correlaciones de r \= .666 en el grupo a y r \= .3 en el grupo b . Muy cerca de las correlaciones que programamos en los dos conjuntos de datos antes de ligarlos. ¿Y las medias de los resultados?

tapply(df$outcome, df$group, mean)

Medias de ~0 para el resultado en el grupo a y ~4 en el grupo b . Así que nuestro dataframe se comporta como le hemos dicho. Ahora vamos a intentar la regresión con un esquema de codificación diferente

Codificación del tratamiento

lm(outcome ~ pred*group, df, contrasts = list(group = c(0,1)))

# Coefficients:
#   (Intercept)         pred       group1  pred:group1  
#      0.009227     0.665201     4.047715    -0.288114 

Bien, aquí el intercepto es la media del resultado en el grupo a , que es aproximadamente 0. A continuación, el pred El coeficiente es la cantidad que pred predice el resultado en el grupo a sólo, más o menos lo mismo que la correlación que extrajimos antes, así que bien. A continuación, el group1 es la diferencia en el valor medio del resultado (es decir, el intercepto) entre el grupo b en comparación con el grupo a . Una vez más, esto es correcto, una diferencia prevista de ~4. Por último, el pred:group1 El coeficiente es la diferencia de pendiente entre el grupo b y el grupo a = 0,665 + -,288 = 0,377, lo que, una vez más, es aproximadamente la correlación entre el predictor y el resultado en el grupo b . Este esquema de codificación ha recuperado los parámetros con precisión. Siguiente codificación simple

Codificación simple

lm(outcome ~ pred*group, df, contrasts = list(group = c(-.5,.5)))

# Coefficients:
#   (Intercept)         pred       group1  pred:group1  
#        2.0331       0.5211       4.0477      -0.2881  

Aquí el intercepto debe ser la media general

mean(df$outcome) 
[1] 2.070099

...lo suficientemente cerca. Y el pred el coeficiente debe ser la pendiente/correlación promediada entre los grupos

mean(c(.665, .377))
[1] 0.521 

El group coeficiente también es correcto, una diferencia media de cuatro, y el pred:group1 El coeficiente, una vez más, es la diferencia de pendiente entre los grupos: -2,88. Al igual que la codificación del tratamiento, la codificación simple nos proporciona información precisa. Su beneficio incremental sobre la codificación de tratamiento es que produce algo así como un contraste de "efecto principal", el pred coeficiente, que es la cantidad que el pred predice el resultado, promediado entre los grupos.

Codificación de la desviación

lm(outcome ~ pred*group, df, contrasts = list(group = c(-1,1)))

# Coefficients:
#   (Intercept)         pred       group1  pred:group1  
#        2.0331       0.5211       2.0239      -0.1441 

Estoy confundido sobre lo que los coeficientes nos dan aquí. Aquí el intercepto es una vez más la media general, el pred es la pendiente media de todos los grupos, pero los coeficientes de los group1 y pred:group1 son exactamente la mitad de lo que son en el esquema de codificación simple

Así es el group ¿El coeficiente es simplemente la mitad de la diferencia real entre grupos, la mitad del coeficiente obtenido por el esquema de codificación simple, es decir, incorrecto?

2 * 2.0239
[1] 4.0478

¿O es la diferencia entre el grupo b resultado medio y la media general?

2.0331 + 2.0239
[1] 4.057 # not quite right but close

¿Y cuál es el pred:group1 ¿coeficiente, si no me equivoco?

¿Y cómo se relaciona todo esto con las sumas de cuadrados de tipo 1 y 3? La codificación de la desviación es lo que obtenemos si especificamos options(contrasts = c("contr.sum", "contr.poly)) que se supone que es de tipo 3 (según la codificación por defecto del SPSS). Pero no recupera los parámetros correctos, a no ser que me equivoque e interprete mal la salida de la regresión.

10voto

Isabella Ghement Puntos 9964

@llewmills: Esta semana me encontré con un proyecto en el que la codificación de desviación sobre la que preguntaste me resultó útil, así que pensé en compartir aquí lo que aprendí sobre este tema.

En primer lugar, creo que será más fácil si empezamos con un modelo más sencillo:

m0.dev <- lm(outcome ~ group, df, 
             contrasts = list(group = c(-1,1)))
summary(m0.dev)

cuya salida viene dada por:

Call:
lm(formula = outcome ~ group, data = df, 
   contrasts = list(group = c(-1, 1)))

Residuals:
    Min      1Q  Median      3Q     Max 
-3.3119 -0.6728  0.1027  0.6748  2.8539 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2.07010    0.07019   29.49   <2e-16 ***
group1       1.98435    0.07019   28.27   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.9926 on 198 degrees of freedom
Multiple R-squared:  0.8015,    Adjusted R-squared:  0.8005 
F-statistic: 799.3 on 1 and 198 DF,  p-value: < 2.2e-16

En este modelo, que utiliza la codificación de la desviación para el grupo, el intercepto representa la media global del valor de resultado y en los grupos a y b, mientras que el coeficiente del grupo1 representa la diferencia entre esta media global y la media del valor de resultado y para el grupo a. La media global no es otra que la media de estas dos medias: (i) la media de y para el grupo a y (ii) la media de y para el grupo b.

En otras palabras:

2.07010 \= media global de y en los grupos a y b

1.98435 \= (media global de y entre los grupos a y b) - media de y para el grupo a

Recuerde que, para sus datos simulados, la media de y para el grupo a es 0,08574619 y la media de y para el grupo b es 4,05445164. Efectivamente:

means <- tapply(df$outcome, df$group, mean)
means

> means    
     a          b 
0.08574619 4.05445164 

Así es como se recuperan estas medias a partir del resumen del modelo que se ha informado anteriormente:

# group a: 
mean of group a = overall mean  - (overall mean - mean of group a) 
            = intercept in deviation coded model m0.dev - coef of group a (aka, group 1) in model m0.dev 
            = 2.07010 - 1.98435 = 0.08575

# group b: 
mean of group b = overall mean  - (overall mean - mean of   group b) 
            = overall mean + (overall mean - mean of group a) 
            = intercept in deviation coded model m0.dev + coef of group a (aka, group 1) in model m0.dev 
            = 2.07010 + 1.98435 = 4.05445

En lo anterior, utilizamos el hecho de que la suma de las desviaciones de la media de cada grupo con respecto a la media general es cero:

(overall mean - mean of group a) + (overall mean - mean of group b) = 0.  

Esto implica que:

(overall mean - mean of group b) = -(overall mean - mean of group a).      

Ahora, podemos trazar las medias específicas de los grupos y las medias globales derivadas del resumen del modelo m0.dev utilizando este código:

plot(1:2, as.numeric(means), type="n", xlim=c(0.5,2.5), ylim=c(0,5), xlab="group", ylab="y", xaxt="n", las=1)
segments(x0=1-0.2, y0=means[1], x1 = 1+0.2, y1=means[1], lwd=3, col="dodgerblue") # group a mean
segments(x0=2-0.2, y0=means[2], x1 = 2+0.2, y1=means[2], lwd=3, col="orange")# group b mean  
segments(x0=1.5-0.2, y0=coef(m0.dev)[1], x1 = 1.5+0.2, y1=coef(m0.dev)[1], lwd=3, col="red3", lty=2) # overall mean
text(1, means[1]+0.3, "Mean value of y \nfor group a\n(0.0857)", cex=0.8)
text(2, means[2]+0.3, "Mean value of y \nfor group b\n(4.0545)", cex=0.8)
text(1.5, coef(m0.dev)[1]+0.3, "Overall mean value of y \n across groups a and b\n(2.0701)", cex=0.8)
axis(1, at = c(1,2), labels=c("a","b"))

enter image description here

Ahora estamos preparados para pasar al modelo más complicado que aparece a continuación:

m1.dev <- lm(outcome ~ pred*group, df, contrasts = list(group = c(-1,1)))

summary(m1.dev)

cuya salida viene dada por:

Call:
lm(formula = outcome ~ pred * group, data = df, contrasts = list(group = c(-1, 
1)))

Residuals:
     Min       1Q   Median       3Q      Max 
-2.78611 -0.60587 -0.05853  0.58578  2.42940 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2.03308    0.06125  33.191  < 2e-16 ***
pred         0.52114    0.06557   7.947 1.47e-13 ***
group1       2.02386    0.06125  33.041  < 2e-16 ***
pred:group1 -0.14406    0.06557  -2.197   0.0292 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.8628 on 196 degrees of freedom
Multiple R-squared:  0.8515,    Adjusted    R-squared:  0.8493 
F-statistic: 374.7 on 3 and 196 DF,  p-value: < 2.2e-16

Este modelo consiste esencialmente en ajustar dos líneas diferentes -una por cada uno de los grupos a y b- que describen cómo el valor del resultado y tiende a variar con el predictor pred. Los interceptos de las dos líneas se expresan en relación con el intercepto de la línea general en los dos grupos. Además, las pendientes de las dos líneas se expresan en relación con las pendientes de la línea de regresión general en los dos grupos. El modelo informa de las siguientes cantidades:

2.03308 \= intercepción estimada de la línea de regresión general en los dos grupos a y b (es decir, la intercepción indicada en el resumen del modelo m1.dev)

0.52114 \= pendiente estimada de la línea de regresión global (es decir, el coeficiente de predicción indicado en el resumen del modelo m1.dev)

2.02386 \= diferencia estimada entre el intercepto de la línea de regresión global y el intercepto de la línea de regresión para el grupo a (también conocido como grupo 1) (es decir, el coeficiente del grupo1 indicado en el resumen del modelo m1.dev)

-0.14406 \= diferencia estimada entre la pendiente de la línea de regresión global y la pendiente de la línea de regresión para el grupo a (también conocido como grupo 1) (es decir, el coeficiente de pred:grupo1 que aparece en el resumen del modelo m1.dev)

Aquí está el código R que permite recuperar el intercepto y la pendiente para las líneas de regresión específicas del grupo:

# Note: group a is re-labelled as group 1

intercept of group a line = intercept of overall line  - (intercept of overall line - intercept of group a line)  
            = intercept in deviation coded model m1.dev - coef of group 1 in model m1.dev 
            = 2.03308 - (2.02386) = 0.00922

slope of group a line = slope of overall line  - (slope of overall line - slope of group a line) = 
            = slope of pred in deviation coded model m1.dev - slope of pred:group1 in model m1.dev 
            = 0.52114 - (-0.14406) =  0.6652

# Now, use that: 
# (intercept of overall line - intercept of group a line)  + (intercept of overall line - intercept of group b line) = 0 
# which means that: 
# (intercept of overall line - intercept of group b line) = - (intercept of overall line - intercept of group a line)  

# Similarly: 
# (slope of overall line - slope of group a line)  + (slope of overall line - slope of group b line) = 0 
# which means that: 
# (slope of overall line - slope of group b line) = - (slope of overall line - slope of group a line)  

intercept of group b line = intercept of overall line  - (intercept of overall line - intercept of group b line)
                      = intercept of overall line  + (intercept of overall line - intercept of group a line)  
                      = intercept in deviation coded model m1.dev + coef of group 1 in model m1.dev 
                      = 2.03308 + (2.02386) = 4.05694

slope of group b line = slope of overall line  - (slope of overall line - slope of group b line) = 
                  = slope of overall line  + (slope of overall line - slope of group a line) = 
                  = slope of pred in deviation coded model m1.dev + slope of pred:group1 in model m1.dev 
                  = 0.52114 + (-0.14406) = 0.37708

Utilizando esta información, puede trazar las líneas de regresión específicas del grupo y globales con este código:

plot(outcome ~ pred, data = df, type="n")
# overall regression line 
abline(a = coef(m1.dev)["(Intercept)"], 
       b = coef(m1.dev)["pred"], 
       col="red3", lwd=2, lty=2)
# regression line for group a 
abline(a = coef(m1.dev)["(Intercept)"] - coef(m1.dev)["group1"], 
      b = coef(m1.dev)["pred"] - coef(m1.dev)["pred:group1"], 
      col="dodgerblue", lwd=2)
 # regression line for group b 
 abline(a = coef(m1.dev)["(Intercept)"] + coef(m1.dev)["group1"], 
        b = coef(m1.dev)["pred"] + coef(m1.dev)["pred:group1"], col="orange", lwd=2)
 points(outcome ~ pred, data = subset(df, group=="a"), col="dodgerblue")
 points(outcome ~ pred, data = subset(df, group=="b"), col="orange")

enter image description here

Por supuesto, el resumen del modelo m1.dev le permite probar la significación del intercepto y la pendiente de la línea de regresión general juzgando la significación de los valores p reportados para las porciones de Intercepto y pred de la salida. También le permite probar la significación de la:

  • Desviación del intercepto de la línea de regresión del grupo a con respecto al intercepto global (a través del valor p indicado para el grupo1);
  • Desviación de la pendiente de la línea de regresión del grupo b con respecto a la pendiente global (a través del valor p indicado para pred:group1).

¿Cuándo querría utilizar la situación de codificación de la desviación captada por el modelo m1.dev? Si:

  • La variable de resultado y representa algún parámetro de calidad del agua;
  • La variable predictora representa una variable anual (centrada);
  • El factor de grupo representa una variable estacional (con niveles a = Invierno y b = Verano);

entonces puede imaginarse que se quiere informar no sólo de una tendencia específica de invierno y otra específica de verano (lineal) a lo largo del tiempo en los valores del parámetro de calidad del agua, sino también de una tendencia general a lo largo de las dos estaciones. Sin embargo, para que la tendencia global sea interpretable, es posible que desee tener algún solapamiento en los datos de las dos estaciones. (En sus datos generados, no tiene esencialmente ningún solapamiento, por lo que una tendencia global puede no ser informativa).

Espero que esto responda a su pregunta, que era muy interesante.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X