Encontrar los valores ajustados y predichos para un modelo estadístico

12

Digamos que tengo los siguientes datos y estoy ejecutando un modelo de regresión:

df=data.frame(income=c(5,3,47,8,6,5),
              won=c(0,0,1,1,1,0),
              age=c(18,18,23,50,19,39),
              home=c(0,0,1,0,0,1))

Por un lado, ejecuto un modelo lineal para predecir los ingresos:

md1 = lm(income ~ age + home + home, data=df)

En segundo lugar, ejecuto un modelo logit para predecir la variable ganada:

md2 = glm(factor(won) ~ age + home, data=df, family=binomial(link="logit"))

Para ambos modelos, me pregunto cómo puedo generar una tabla o marco de datos con la categoría de respuesta del predictor, el valor ajustado y el valor predicho del modelo.

Entonces, para el modelo lineal, algo como:

age  fitted_income  predicted_income
18    3              5 
23    3              3
50    4              2
19    5              5
39    6              4

home   fitted_income    predicted_income
0       5               6       
1       3               9

O tal vez debería ser para cada punto de datos. Entonces, para el punto de datos x_i, los valores ajustados y predichos son:

id   age  fitted_income  predicted_income
1     18    3              5 
2     23    3              3
3     50    4              2
4     19    5              5
5     39    6              4
  1. Desde un punto de vista estadístico, ¿es útil esta tarea? ¿Por qué o por qué no?

  2. ¿Cómo se puede hacer esto en R? (miré los nombres (md1) y encontré lo que puedo extraer del modelo, pero no he pasado de eso)

¡Gracias!

ATMathew
fuente
1
Re # 2: stat.ethz.ch/R-manual/R-patched/library/stats/html/… . Re # 1: útil para qué? ¿Qué quieres lograr al final?
Whuber
Útil para saber si el modelo es "predictivo" para cada punto de datos individual. Quiero ver cualquier fila / id, y poder comparar el valor verdadero / ajustado y el valor predicho para ver qué tan "correcto" es.
ATMathew
Si desea escanear la tabla para ver cómo varía la respuesta real con respecto a la covariable, supongo que podría ser útil. Sin embargo, no entiendo tu terminología. El valor ajustado y el valor predicho deben ser los mismos. Lo que debería diferir es el valor observado y el valor ajustado.
Michael R. Chernick
2
Podría intentar algo como: x = cbind (df, md1 $ ajustado.values) colnames (x) = c (colnames (df), "predicho")
RioRaider
2
Las diferencias entre los valores observados y ajustados están disponibles a través del residualscomando en R. Use cbindpara unirlos al marco de datos original.
whuber

Respuestas:

20

Debe tener un poco de cuidado con los objetos del modelo en R. Por ejemplo, aunque los valores ajustados y las predicciones de los datos de entrenamiento deben ser los mismos en el glm()caso del modelo, no son los mismos cuando utiliza las funciones de extracción correctas:

R> fitted(md2)
        1         2         3         4         5         6 
0.4208590 0.4208590 0.4193888 0.7274819 0.4308001 0.5806112 
R> predict(md2)
         1          2          3          4          5          6 
-0.3192480 -0.3192480 -0.3252830  0.9818840 -0.2785876  0.3252830

Esto se debe a que el valor predeterminado para predict.glm()es devolver predicciones en la escala del predictor lineal. Para obtener los valores ajustados, queremos aplicar la inversa de la función de enlace a esos valores. fitted()hace eso por nosotros, y también podemos obtener los valores correctos usando predict():

R> predict(md2, type = "response")
        1         2         3         4         5         6 
0.4208590 0.4208590 0.4193888 0.7274819 0.4308001 0.5806112

Del mismo modo con residuals()(o resid()); es poco probable que los valores almacenados en md2$residualslos residuos de trabajo sean lo que desea. El resid()método le permite especificar el tipo de residuo que desea y tiene un valor predeterminado útil.

Para el glm()modelo, algo como esto será suficiente:

R> data.frame(Age = df$age, Won = df$won, Fitted = fitted(md2))
  Age Won    Fitted
1  18   0 0.4208590
2  18   0 0.4208590
3  23   1 0.4193888
4  50   1 0.7274819
5  19   1 0.4308001
6  39   0 0.5806112

Algo similar se puede hacer para el lm()modelo:

R> data.frame(Age = df$age, Income = df$income, Fitted = fitted(md1))
  Age Income    Fitted
1  18      5  7.893273
2  18      3  7.893273
3  23     47 28.320749
4  50      8 -1.389725
5  19      6  7.603179
6  39      5 23.679251
Gavin Simpson
fuente