Como precuela de una pregunta sobre modelos lineales mixtos en R, y para compartir como referencia para principiantes / intermedios aficionados a la estadística, decidí publicar como un "estilo de preguntas y respuestas" independiente los pasos involucrados en el cálculo "manual" del coeficientes y valores predichos de una regresión lineal simple.
El ejemplo es con el conjunto de datos R incorporado mtcars
, y se configuraría como millas por galón consumido por un vehículo que actúa como la variable independiente, retrocediendo sobre el peso del automóvil (variable continua) y el número de cilindros como un factor con tres niveles (4, 6 u 8) sin interacciones.
EDITAR: Si está interesado en esta pregunta, definitivamente encontrará una respuesta detallada y satisfactoria en esta publicación de Matthew Drury fuera de CV .
fuente
Respuestas:
Nota : publiqué una versión ampliada de esta respuesta en mi sitio web .
¡Seguro! Bajamos por la madriguera del conejo.
La primera capa es
lm
la interfaz expuesta al programador R. Puede ver la fuente de esto simplemente escribiendolm
en la consola R. La mayor parte (como la mayoría de la mayoría del código de nivel de producción) está ocupado revisando entradas, configurando atributos de objeto y arrojando errores; pero esta línea sobresalelm.fit
es otra función R, puedes llamarla tú mismo. Silm
bien funciona convenientemente con fórmulas y marcos de datos,lm.fit
desea matrices, por lo que ese es un nivel de abstracción eliminado. Verificando la fuentelm.fit
, más trabajo ocupado y la siguiente línea realmente interesanteAhora estamos llegando a alguna parte.
.Call
es la forma en que R llama al código C. Hay una función C, C_Cdqrls en la fuente R en alguna parte, y necesitamos encontrarla. Aqui esta .Mirando la función C, de nuevo, encontramos en su mayoría comprobación de límites, limpieza de errores y trabajo ocupado. Pero esta linea es diferente
Así que ahora estamos en nuestro tercer idioma, R ha llamado C, que está llamando a fortran. Aquí está el código fortran .
El primer comentario lo dice todo
(Curiosamente, parece que el nombre de esta rutina se cambió en algún momento, pero alguien olvidó actualizar el comentario). Así que finalmente estamos en el punto donde podemos hacer algo de álgebra lineal, y en realidad resolver el sistema de ecuaciones. Este es el tipo de cosas en las que fortran es realmente bueno, lo que explica por qué pasamos por tantas capas para llegar aquí.
El comentario también explica qué va a hacer el código
Entonces fortran va a resolver el sistema encontrando la descomposición .Q R
Lo primero que sucede, y con mucho lo más importante, es
Esto llama a la función fortran
dqrdc2
en nuestra matriz de entradax
. ¿Qué es esto?Así que finalmente hemos llegado a linpack . Linpack es una biblioteca de álgebra lineal fortran que existe desde los años 70. El álgebra lineal más grave eventualmente encuentra su camino hacia linpack. En nuestro caso, estamos utilizando la función dqrdc2
Aquí es donde se realiza el trabajo real. Me llevaría un buen día completo descubrir qué está haciendo este código, es tan bajo como es posible. Pero genéricamente, tenemos una matriz y queremos factorizarla en un producto X = Q R donde Q es una matriz ortogonal y R es una matriz triangular superior. Es algo inteligente, porque una vez que tienes Q y R puedes resolver las ecuaciones lineales para la regresiónX X= Q R Q R Q R
muy facilmente. En efecto
entonces todo el sistema se convierte
pero es triangular superior y tiene el mismo rango que X t X , por lo que mientras nuestro problema esté bien planteado, es un rango completo, y también podríamos resolver el sistema reducidoR XtX
Pero aquí está lo asombroso. es triangular superior, por lo que la última ecuación lineal aquí es justa , por lo que la resolución de β n es trivial. Luego puede subir las filas, una por una, y sustituirlas en las β que ya conoce, obteniendo cada vez una ecuación lineal variable simple para resolver. Entonces, una vez que tienes Q y R , todo se derrumba a lo que se llama sustitución hacia atrás , lo cual es fácil. Puede leer sobre esto con más detalle aquí , donde se elabora un pequeño ejemplo explícito.R βnorte β Q R
constant * beta_n = constant
fuente
Los cálculos reales paso a paso en R están bellamente descritos en la respuesta de Matthew Drury en este mismo hilo. En esta respuesta, quiero caminar a través del proceso de probarse a sí mismo que los resultados en R con un ejemplo simple se pueden alcanzar siguiendo el álgebra lineal de proyecciones en el espacio de la columna y el concepto de errores perpendiculares (producto de puntos), ilustrado en diferentes publicaciones , y bien explicado por el Dr. Strang en Álgebra lineal y sus aplicaciones , y fácilmente accesible aquí .
lm
Continuando entonces, para calcular los coeficientes (β PAGSr o j Ma t r i x = ( XTX)- 1XT [ Pr o j Ma t r i x ][ y]=[ R e gr Co e f′s ] ( XTX)- 1XTy= β
Idéntico a:
coef(lm(mpg ~ wt + as.factor(cyl)-1))
.y_hat <- HAT %*% mpg
cyl <- as.factor(cyl); OLS <- lm(mpg ~ wt + cyl); predict(OLS)
:fuente
beta = solve(t(X) %*% X, t(X) %*% y)
en la práctica es más preciso quesolve(t(X) %*% X) %*% t(X) %*% y
.R
cálculos importantes, me gustaría sugerir que considere convertirlo en una contribución a nuestro blog.