Least squares by hand: normal equations, QR, and what standardized residuals really are
How a linear regression is actually computed, why QR is preferred over inverting X'X, how the coefficient standard errors come out, and why standardized residuals need the leverage of each point.
University lab From my coursework in the MSc in Statistics and Machine Learning at Linköping University, rewritten as a note to review later.
lm() hides a lot. In my Advanced R course we rebuilt it as a small package (pair work): fit the coefficients, compute standard errors, t-values and p-values, and draw the two classic diagnostic plots. Doing it by hand made me see which parts are just algebra and which parts are easy to get subtly wrong. Two things stuck: how you solve the least-squares problem matters numerically, and “standardized residuals” means something more specific than “residuals divided by their standard deviation”.
The model
where is the vector of responses, the design matrix (a column of ones for the intercept plus one column per predictor, or per dummy level for a factor), the vector of unknown coefficients, and the errors, assumed independent with mean 0 and variance . After fitting we get the estimate , fitted values and residuals .
In our vignette I wrote the model as . That mixes things up: the observed equals plus error, while the fitted is exactly with no error term.
Way 1: normal equations
Least squares minimizes . Setting the gradient to zero gives the normal equations
That’s what we implemented with solve(t(X) %*% X). It’s fine for small, well-behaved problems. The issue is numerical: the condition number (how much rounding errors get amplified) of is the square of that of . If predictors are nearly collinear, might have condition number , so has , and with double precision (about 16 digits) you’ve thrown away most of your accuracy.
Way 2: QR decomposition
Factor , where is with orthonormal columns () and is upper triangular. Then
Since is triangular, you solve it by back-substitution: last coefficient first, then work upwards. You never form , so you never square the condition number. This is what lm() does internally. As a bonus, , which you need for the standard errors.
X <- model.matrix(Petal.Length ~ Species, data = iris)
y <- iris$Petal.Length
qx <- qr(X)
beta <- backsolve(qr.R(qx), crossprod(qr.Q(qx), y)) # solves R beta = Q'y
n <- nrow(X); p <- ncol(X)
e <- y - X %*% beta
sigma2 <- sum(e^2) / (n - p) # residual variance
XtX_inv <- chol2inv(qr.R(qx)) # (X'X)^{-1} from R
se <- sqrt(diag(XtX_inv) * sigma2)
cbind(beta, se, t = beta / se) # matches summary(lm(...))
Standard errors, t and p
The residual variance estimate is ; dividing by the degrees of freedom (not ) makes it unbiased, because fitting coefficients uses up directions of freedom. Then
and the two-sided p-value is , with a Student-t variable with degrees of freedom. Our code got this part right.
Standardized residuals need leverage
For the Scale-Location plot, R plots against the fitted values, where is the standardized (internally studentized) residual. We computed it as a z-score of the residuals, . That’s not the same thing, and the difference is the useful part.
Residuals don’t all have the same variance, even if the errors do. With the hat matrix (it “puts the hat on” : ), the residuals are and
where , the -th diagonal element of , is the leverage of point : how unusual its predictor values are. A point with high leverage pulls the fitted line towards itself, so its residual is smaller than its error. The standardized residual corrects for that:
With a z-score, high-leverage points look harmless exactly when you most want to notice them. Also, with an intercept the residuals already sum to zero, so subtracting does nothing. In R, rstandard(fit) gives , and hatvalues(fit) gives ; with QR, is the squared length of row of , rowSums(qr.Q(qx)^2).
Key takeaways
- Model: ; fit: , residuals .
- Normal equations square the condition number; QR solves and is what
lm()uses. - and give the t-tests.
- Standardized residuals divide by , not by the sample sd of the residuals. Leverage matters.
Resources
- 732A94 Advanced R Programming, Linköping University, lab 4 (2019).
- Julian J. Faraway, Linear Models with R, 2nd ed., Chapter 2 (estimation, QR) and Chapter 6 (diagnostics, leverage, standardized residuals).
- Lloyd N. Trefethen and David Bau III, Numerical Linear Algebra, Lectures 7–8 (QR) and 11 (least squares).
- R documentation, influence.measures / rstandard / hatvalues.