Tengo un ejemplo trabajado (en R), que estoy tratando de entender más. Estoy usando Limma para crear un modelo lineal y estoy tratando de entender lo que sucede paso a paso en los cálculos de cambio de pliegue. Principalmente estoy tratando de averiguar qué sucede para calcular los coeficientes. Por lo que puedo entender, la descomposición QR se usa para obtener los coeficientes, por lo que esencialmente estoy buscando una explicación o una forma de ver paso a paso las ecuaciones que se están calculando, o el código fuente de qr () en R para rastrearlo yo mismo.
Usando los siguientes datos:
expression_data <- c(1.27135202935009, 1.41816160331787, 1.2572772420417, 1.70943398046296, 1.30290218641586, 0.632660015122616, 1.73084258791384, 0.863826352944684, 0.62481665344628, 0.356064235030147, 1.31542028558644, 0.30549909383238, 0.464963176430548, 0.132181421105667, -0.284799809563931, 0.216198538884642, -0.0841133304341238, -0.00184472290008803, -0.0924271878885008, -0.340291804468472, -0.236829711453303, 0.0529690806587626, 0.16321956624511, -0.310513510587778, -0.12970035111176, -0.126398635780533, 0.152550803185228, -0.458542514769473, 0.00243517688116406, -0.0190192219685527, 0.199329876859774, 0.0493831375210439, -0.30903829000185, -0.289604319193543, -0.110019942085281, -0.220289950537685, 0.0680403723818882, -0.210977291862137, 0.253649629045288, 0.0740109953273042, 0.115109148186167, 0.187043445057404, 0.705155251555554, 0.105479342752451, 0.344672919872447, 0.303316487542805, 0.332595721664644, 0.0512213943473417, 0.440756755046719, 0.091642538588249, 0.477236022595909, 0.109140019847968, 0.685001267317616, 0.183154080053337, 0.314190891668279, -0.123285017407119, 0.603094973500324, 1.53723917249845, 0.180518835745199, 1.5520102749957, -0.339656677699664, 0.888791974821514, 0.321402618155527, 1.31133008668306, 0.287587853884556, -0.513896569786498, 1.01400498573403, -0.145552182640197, -0.0466811491949621, 1.34418631328095, -0.188666887863983, 0.920227741574566, -0.0182196762358299, 1.18398082848213, 0.0680539755381465, 0.389472802053599, 1.14920099633956, 1.35363045061024, -0.0400907708395635, 1.14405154287124, 0.365672853509181, -0.0742688460368051, 1.60927415300638, -0.0312210890874907, -0.302097025523754, 0.214897201115632, 2.029775196118, 1.46210810601113, -0.126836819148653, -0.0799005522761045, 0.958505775644153, -0.209758749029421, 0.273568395649965, 0.488150388217536, -0.230312627718208, -0.0115780974342431, 0.351708198671371, 0.11803520077305, -0.201488605868396, 0.0814169684941098, 1.32266103732873, 1.9077004570343, 1.34748531668521, 1.37847539147601, 1.85761827653095, 1.11327229058024, 1.21377936983249, 1.167867701785, 1.3119314966728, 1.01502530573911, 1.22109375841952, 1.23026951795161, 1.30638557237133, 1.02569437924906, 0.812852833149196)
treatment <- c('A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'B', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'A', 'B', 'A', 'C', 'A', 'C', 'A', 'B', 'C', 'B', 'C', 'C', 'A', 'C', 'A', 'B', 'A', 'C', 'B', 'B', 'A', 'C', 'A', 'C', 'C', 'A', 'C', 'B', 'C', 'A', 'A', 'B', 'C', 'A', 'C', 'B', 'B', 'C', 'C', 'B', 'B', 'C', 'C', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A')
variation <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3)
... y el siguiente diseño de modelo
design <- model.matrix(~0 + factor(treatment,
levels=unique(treatment)) +
factor(variation))
colnames(design) <- c(unique(treatment),
paste0("b",
unique(variation)[-1]))
#expression_data consists of more than the data given. The data given is just one row from the object
fit <- lmFit((expression_data), design)
cont_mat <- makeContrasts(B-A,
levels=design)
fit2 <- contrasts.fit(fit,
contrasts=cont_mat)
fit2 <- eBayes(fit2)
Me da un cambio de pliegue de -0.8709646.
Obtener los coeficientes se puede hacer a través de:
qr.solve(design, expression_data)
Entonces es un caso simple de BA para obtener el cambio de pliegue.
Ahora, lo que me deja perplejo es cómo qr.solve
funciona realmente, llama a la qr
función, pero parece que no puedo encontrar la fuente para eso.
¿Alguien tiene una buena explicación de la descomposición qr, o una forma de rastrear exactamente lo que está sucediendo para derivar los coeficientes?
¡Gracias por cualquier ayuda!
fuente
Respuestas:
La idea de la descomposición QR como un procedimiento para obtener estimaciones de OLS ya se explica en la publicación vinculada por @MatthewDrury.
El código fuente de la función
qr
está escrito en Fortran y puede ser difícil de seguir. Aquí muestro una implementación mínima que reproduce los resultados principales de un modelo ajustado por OLS. Esperemos que los pasos sean más fáciles de seguir.Podemos comprobar que
lm
se obtienen las mismas estimaciones que las obtenidas.También podemos obtener la matrizQ
Los residuos se pueden obtener como
y - X %*% res$beta
.Referencias
DSG Pollock (1999) Un manual de análisis de series temporales, procesamiento de señales y dinámica. , Academic Press.
fuente
QR.regression
como función la llamada en lugar deQR.Householder
. Aparte de eso, no puedo agradecerles lo suficiente por una explicación tan perspicaz.