05 / 27 · Linear Regression
Least squares
Linear regression fitted by minimizing the sum of squared residuals: the normal equations and when their solution is unique, the fit as an orthogonal projection, the reading as maximum likelihood under Gaussian noise with the sampling distribution of the coefficients, collinearity and numerical conditioning, R² and its traps, and robust losses for data with outliers.
Nearest neighbours · Linear algebra ↗ · Maximum likelihood · Conditional expectation
On this page 13
The nearest-neighbours note ended with a model that answers every query from a handful of nearby points and learns nothing about the relationship as a whole; in many dimensions the nearby points disappear. This note takes the opposite bet. It assumes that the target is, up to noise, a weighted sum of the features, one weight per feature, and fits the weights to all the data at once by minimizing the squared errors. The fit has a closed form, a geometric meaning and a probabilistic meaning, and each of the three explains a different way it can fail: on collinear features, on badly scaled numbers and on outliers. The failures set up the rest of the section.
Notation. The training set is with and . The design matrix has the as rows and collects the targets. When the model has an intercept, the first feature is the constant 1, so counts the intercept. A weight vector predicts , all at once . The residuals are , the residual sum of squares is , and the mean squared error is . is the minimizer and .
A linear model#
The model is
Each weight says how much the prediction changes when one feature grows by one unit and the others stay fixed. The model is linear in , not necessarily in the original inputs: the features can be powers of a number, logarithms, products of two inputs or the one-hot columns of a category from the features note. Everything below holds for any such fixed set of features, because it only uses the matrix .
The loss is the squared error, averaged over the training set:
Why squares rather than absolute values or another penalty? Three answers follow in this note: the minimizer has a formula, it is an orthogonal projection, and it is the maximum-likelihood estimate when the noise is Gaussian. The last section shows the price.
The normal equations#
Expand the residual sum of squares: . The gradient of the linear term is and that of the quadratic form, with symmetric, is , so
The Hessian is , and for every : the function is convex, and every point where the gradient vanishes is a global minimum. Setting the gradient to zero gives the normal equations
If the columns of are linearly independent (which needs ), then for every , the matrix is positive definite and invertible, and the minimizer is unique:
If the columns are dependent, for example when one feature is the sum of two others or when , the normal equations have infinitely many solutions, all with the same fitted values; the section on stability returns to that case.
Worked example. Four points: and , model . The design matrix has columns and , so
The determinant is , and . The fitted line is , the residuals are and .
Solving the normal equations costs to form and to solve the system. For ten features that is nothing; for a million sparse text features it is impossible, which is where the next note starts.
The geometry: a projection#
The normal equations can be rewritten as : the residual vector is orthogonal to every column of . Read the targets as one point . As varies, the predictions sweep the column space , a -dimensional subspace of . Least squares picks the point of that subspace closest to , and the closest point is the foot of the perpendicular.
Least squares as a projection
The orthogonality gives a proof of optimality without calculus. For any , split . The first term is orthogonal to the column space and the second lies in it, so by Pythagoras
with equality exactly when . In the three-point example of the figure the extra term is for .
The map from to is linear: with the hat matrix . It is the orthogonal projection onto , so it is symmetric and idempotent (: projecting twice changes nothing), and its trace is , the dimension of the subspace. The diagonal entry , the leverage of point , is how much moves when moves by one. In the four-point example the leverages are , summing to : the end points pull on the line more than the middle ones.
Two consequences of orthogonality are used constantly. When the model has an intercept, the constant column is one of the columns, so : the residuals average to zero and the mean of equals the mean of . In the worked example, , and also . And with , so the total variation splits into an explained and an unexplained part, which is what below measures.
The probability: Gaussian noise and the conditional mean#
Suppose the data come from with independent and . The negative log-likelihood is plus a constant, as derived in the maximum likelihood note, so minimizing squared error is maximizing the likelihood. Without assuming a model at all, squared error has another justification: its population minimizer over all functions is the conditional mean (the best predictor). Least squares restricted to linear functions estimates the linear function closest to in mean square, which is itself when that is linear.
The distribution of the coefficients. Here the design is treated as fixed and only the noise is random: the statements below are about repeated draws of for the same inputs. Substitute into the formula:
The estimate is the true weight plus a fixed linear map of the noise. Three facts follow, each under its own assumption:
- Unbiased if : .
- Covariance if the noise is uncorrelated with equal variances, : with , .
- Gaussian if the noise is Gaussian, since an affine map of a Gaussian vector is Gaussian: . For other independent noise with finite variance, the distribution is approximately Gaussian for large by the central limit theorem, provided no single point dominates the fit: the largest leverage (defined above) must tend to 0.
The noise variance is unknown and is estimated from the residuals. Since (because ), and . So
is unbiased: degrees of freedom are spent on the fit, as the of the sample variance spends one on the mean. The square roots of the diagonal of are the standard errors of the coefficients.
Worked example. In the four-point example and , so the slope has standard error and the intercept . With four points the slope is barely two standard errors from zero. A simulation confirms the formula: 30 equally spaced points on , true , and 20,000 noise draws give coefficient means and standard deviations , against from (the Code section).
The Gauss–Markov theorem adds that, with uncorrelated equal-variance noise, no other estimator that is linear in and unbiased has a smaller variance for any linear combination of the coefficients (Hastie, Tibshirani and Friedman, 2009, section 3.2.2). The qualifier matters: estimators that accept a little bias can have a much smaller variance and a smaller mean squared error, the trade-off of the estimators note. The regularization note builds such estimators.
When the solution is unstable#
The covariance is large in the directions where has small eigenvalues, that is, where some combination of features is nearly constant across the data. Two features that almost repeat each other produce exactly that.
Collinearity. Take 100 points with , where is standard normal noise, and with . The correlation of the two features is and the condition number of is . Three draws of the noise give the weights , and , with sums , and . The data pin down the sum , the direction in which the features vary, and say almost nothing about the difference, the direction in which they do not. The standard error of each weight is , against for a model with one of the two features alone. The predictions on data like the training data hardly change from draw to draw; the coefficients, and any interpretation of them, are noise. A weight of on a feature that helps the target is the typical symptom.
Rank deficiency. When the columns are exactly dependent, or , is singular and the normal equations have a whole affine set of solutions. The standard choice is the one with the smallest norm, with the Moore–Penrose pseudoinverse , which is what numpy.linalg.lstsq returns. The choice is a preference, not something the data decide, and the regularization note makes the preference explicit.
Numerical conditioning. Even when is invertible in exact arithmetic, forming it squares the condition number: . Double precision carries about 16 significant digits, and a linear solve loses roughly of them. For polynomial features on 50 points of , and . Solving the normal equations recovers coefficients that are all equal to 1 with an error of ; an SVD-based solver applied to directly, as lstsq does, gets (Trefethen and Bau, 1997, lectures 11 and 19). The formula is for derivations; numerical code factorizes . Centring and scaling the features, as in the features note, also lowers the condition number, and the next note shows that the same number governs the speed of gradient descent.
Measuring a regression#
The mean squared error is in squared units of the target; its root, the RMSE, is in the target’s units. The coefficient of determination compares the fit with the best constant, the mean :
On the training data of a model with an intercept, the Pythagorean split of the previous sections puts between 0 and 1, the share of the variation of that the fit explains. In the four-point example , the total sum of squares is , and .
On the diabetes data bundled with scikit-learn (442 patients, 10 centred and scaled measurements, the target a measure of disease progression after a year), least squares has a training of and a 5-fold cross-validated of . Nearest neighbours on standardized features reach at best (at ; , and for , 10 and 40). Eleven coefficients fitted to all the data beat the local vote here, because the relationship is close to additive and 442 points are few for neighbourhoods in ten dimensions.
has three traps:
- Training never decreases with features. Adding a column can only keep or enlarge the column space, so the projection’s residual never grows. With 50 training points, one useful feature and columns of pure noise, the training goes , , , for , while on 50 fresh points it goes , , , . A negative means worse than predicting the mean, and it only appears on data the model did not see. Report on validation data, as the validation note requires of every metric.
- depends on the spread of . For with , the same model with the same noise has when is uniform on and when it is uniform on ; the RMSE is 1 in both cases. compares with the mean, and the mean is a worse predictor when varies more.
- A high does not mean a correct model. A straight line through points on a parabola can have near 1 and residuals that are all positive at the ends and negative in the middle. Look at the residuals.
Squared error and outliers#
Squared error estimates the conditional mean, and a mean follows its largest values. Other losses estimate other targets (other losses, other targets): the best constant under absolute error is the median. For the five values the best constant under squared error is their mean , under absolute error their median . One wrong value can therefore move a least-squares fit arbitrarily far, while it moves the median-based fit only until it crosses the other points.
One outlier and three losses
The outlier in the figure has a least-squares residual of ; squared, , it is larger than the squared residuals of the other nine points together. Least squares tilts the line towards it, from slope without the point to with it. Two losses limit the influence of large residuals:
- Absolute error, , least absolute deviations. Each point pulls with the same force whatever its distance. The fitted line here is ; the minimizer is not always unique, and the loss is not differentiable at 0.
- The Huber loss (Huber, 1964): for and beyond. Quadratic for small residuals, so it keeps the efficiency of least squares on clean Gaussian data; linear for large ones, so an outlier’s pull is capped at . With the line is .
The cap is on the derivative with respect to the residual. The gradient with respect to the weights multiplies that derivative by , so a point with an extreme input, a high-leverage point, still pulls hard. Ten points on the line and one gross error at flatten all three fits alike: the slopes of least squares, Huber and least absolute deviations are all . These losses protect against outliers in , not in .
Neither has a closed form. Both can be fitted by repeatedly solving weighted least squares with weights that shrink for large residuals, which is how the figure computes them, or by the general method of the next note.
What changed#
| Nearest neighbours | Least squares | |
|---|---|---|
| Model | the average of nearby targets | a global linear function with coefficients |
| Training | store the data | solve , |
| Prediction | search the training set | one dot product, |
| Diabetes, cross-validated | at best () | |
| Uncertainty | none built in | , standard errors |
| Interpretation | none | one weight per feature, if the features are not collinear |
| Weak point | many dimensions, scaling | nonlinear relationships, collinearity, outliers, close to |
Limitations#
- Linear in the chosen features. The model sees interactions and curvature only if someone puts them into ; the trees section and the networks section learn them instead.
- Unstable with correlated features or close to . The coefficients’ variance blows up along nearly constant directions; with and the training error is zero, so the fit on the training data is no evidence of generalization. Which of the many interpolating solutions is chosen (the minimum-norm one, for example) and the geometry of the data still decide whether its predictions are useful, as the double-descent caveat shows.
- Sensitive to outliers. A single gross error can turn the line, because the squared loss weighs residuals by their size; robust losses help against outliers in , not against extreme inputs.
- The variance formula assumes uncorrelated, equal-variance noise. With heteroscedastic or correlated errors (time series, grouped data) the coefficients stay unbiased but the standard errors are wrong.
- The closed form costs and exists only for squared error.
What you should remember#
- Least squares minimizes ; the normal equations have the unique solution when the columns of are independent.
- Geometrically, is the orthogonal projection of onto the column space; the residual is orthogonal to every feature, and with an intercept the residuals sum to zero.
- Under Gaussian noise least squares is maximum likelihood, and ; estimate by .
- Nearly collinear features make individual coefficients meaningless while the predictions stay stable; this is the opening for regularization.
- Never solve the normal equations numerically for ill-conditioned features: forming squares the condition number. Use QR or SVD (
lstsq). - compares with predicting the mean; on training data it never decreases as features are added, so report it on validation data.
- Squared error estimates the conditional mean and follows outliers; absolute error estimates the median, and the Huber loss interpolates between the two.
Code#
The worked examples, the sampling distribution of the coefficients, the diabetes comparison with nearest neighbours, the traps of , collinearity, conditioning and robust fits:
import numpy as np
from scipy import optimize
from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import KFold, cross_val_score
from sklearn.neighbors import KNeighborsRegressor
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
rng = np.random.default_rng(0)
r2 = lambda y, p: 1 - ((y - p) ** 2).sum() / ((y - y.mean()) ** 2).sum()
# the worked example: four points, the normal equations, residuals orthogonal to the columns
x = np.array([0., 1, 2, 3]); y = np.array([1., 3, 2, 5])
X = np.column_stack([np.ones(4), x])
w = np.linalg.solve(X.T @ X, X.T @ y)
r = y - X @ w
H = X @ np.linalg.inv(X.T @ X) @ X.T
print(w, r.round(2), (X.T @ r).round(12) + 0, round(r @ r, 2), round(r2(y, X @ w), 3), np.diag(H).round(2))
# [1.1 1.1] [-0.1 0.8 -1.3 0.6] [0. 0.] 2.7 0.691 [0.7 0.3 0.3 0.7]
s2 = r @ r / (4 - 2) # unbiased noise variance, n - d = 2
print(round(s2, 2), np.sqrt(s2 * np.diag(np.linalg.inv(X.T @ X))).round(3)) # 1.35 [0.972 0.52 ]
# the sampling distribution of w-hat: 30 points on [0, 1], w = (1, 2), sigma = 0.5, 20,000 noise draws
Xs = np.column_stack([np.ones(30), np.linspace(0, 1, 30)])
W = np.array([np.linalg.lstsq(Xs, Xs @ [1, 2] + 0.5 * rng.normal(size=30), rcond=None)[0] for _ in range(20_000)])
print(W.mean(0).round(3), W.std(0).round(3), (0.5 * np.sqrt(np.diag(np.linalg.inv(Xs.T @ Xs)))).round(3))
# [1.001 2. ] [0.177 0.303] [0.178 0.306]: simulated means, simulated and theoretical standard deviations
# diabetes (442 patients, 10 features): the closed form is what scikit-learn computes; linear model against kNN
Xd, yd = load_diabetes(return_X_y=True)
A = np.column_stack([np.ones(len(yd)), Xd])
wd = np.linalg.lstsq(A, yd, rcond=None)[0]
lr = LinearRegression().fit(Xd, yd)
print(f'{np.abs(wd - np.r_[lr.intercept_, lr.coef_]).max():.0e}', round(r2(yd, A @ wd), 3)) # 2e-12 0.518
cv = KFold(5, shuffle=True, random_state=0)
print(round(cross_val_score(LinearRegression(), Xd, yd, cv=cv, scoring='r2').mean(), 3),
[round(float(cross_val_score(make_pipeline(StandardScaler(), KNeighborsRegressor(k)), Xd, yd, cv=cv, scoring="r2").mean()), 3) for k in (5, 10, 20, 40)])
# 0.489 [0.382, 0.444, 0.454, 0.428]
# R² on the training data never decreases with useless features; on fresh data it collapses (50 + 50 points)
z = rng.normal(size=(100, 1)); t = z[:, 0] + rng.normal(size=100)
for k in (0, 10, 20, 40):
Z = np.column_stack([np.ones(100), z, rng.normal(size=(100, k))])
v = np.linalg.lstsq(Z[:50], t[:50], rcond=None)[0]
print(k, round(r2(t[:50], Z[:50] @ v), 3), round(r2(t[50:], Z[50:] @ v), 3))
# 0 0.572 0.325 | 10 0.649 0.154 | 20 0.747 -0.158 | 40 0.921 -0.71
# two nearly identical features: the coefficients swing, their sum and the predictions do not
x1 = rng.normal(size=100); x2 = x1 + 0.01 * rng.normal(size=100); X2 = np.column_stack([x1, x2])
print(round(np.corrcoef(x1, x2)[0, 1], 5), f'{np.linalg.cond(X2.T @ X2):.1e}') # 0.99994 3.5e+04
for _ in range(3):
v = np.linalg.lstsq(X2, x1 + x2 + rng.normal(size=100), rcond=None)[0]
print(v.round(2), round(v.sum(), 2))
# [-5. 6.88] 1.88 | [11.88 -9.9 ] 1.98 | [-8.83 10.94] 2.11
print(np.sqrt(np.diag(np.linalg.inv(X2.T @ X2))).round(2), round(1 / np.sqrt(x1 @ x1), 2)) # [9.74 9.73] 0.1: standard errors for sigma = 1
# conditioning: polynomial features of degree 10 on 50 points; normal equations against QR/SVD (lstsq)
V = np.vander(np.linspace(0, 1, 50), 11, increasing=True); yv = V @ np.ones(11)
print(f'{np.linalg.cond(V):.1e} {np.linalg.cond(V.T @ V):.1e}',
f'{np.abs(np.linalg.solve(V.T @ V, V.T @ yv) - 1).max():.0e} {np.abs(np.linalg.lstsq(V, yv, rcond=None)[0] - 1).max():.0e}')
# 2.0e+07 4.1e+14 4e-03 4e-10
# one outlier: least squares, Huber (delta = 1) and least absolute deviations
xo = np.arange(10.); yo = np.array([1.3, 1.1, 2.2, 3.0, 2.7, 3.6, 3.5, 4.9, 13.0, 5.3]); Xo = np.column_stack([np.ones(10), xo])
huber = lambda r: np.where(np.abs(r) <= 1, 0.5 * r ** 2, np.abs(r) - 0.5)
fits = {'ls': np.linalg.lstsq(Xo, yo, rcond=None)[0],
'ls without x=8': np.linalg.lstsq(np.delete(Xo, 8, 0), np.delete(yo, 8), rcond=None)[0],
'huber': optimize.minimize(lambda v: huber(yo - Xo @ v).sum(), [0, 0], method='BFGS', options={'gtol': 1e-10}).x,
'lad': optimize.linprog(np.r_[0, 0, np.ones(10)], A_ub=np.block([[Xo, -np.eye(10)], [-Xo, -np.eye(10)]]),
b_ub=np.r_[yo, -yo], bounds=[(None, None)] * 2 + [(0, None)] * 10).x[:2]}
for k, v in fits.items(): print(k, v.round(3))
# ls [0.373 0.819] | ls without x=8 [1.107 0.477] | huber [0.986 0.533] | lad [1.267 0.467]
# a gross error at an extreme input: ten points on y = x and one at (100, 0)
xl = np.r_[np.arange(10.), 100]; yl = np.r_[np.arange(10.), 0]; Xl = np.column_stack([np.ones(11), xl])
print(round(float(np.linalg.lstsq(Xl, yl, rcond=None)[0][1]), 2),
round(float(optimize.minimize(lambda v: huber(yl - Xl @ v).sum(), [0, 1], method='BFGS', options={'gtol': 1e-10}).x[1]), 2),
round(float(optimize.linprog(np.r_[0, 0, np.ones(11)], A_ub=np.block([[Xl, -np.eye(11)], [-Xl, -np.eye(11)]]),
b_ub=np.r_[yl, -yl], bounds=[(None, None)] * 2 + [(0, None)] * 11).x[1]), 2))
# -0.04 -0.04 -0.04: the slopes of least squares, Huber and least absolute deviations
Next#
The normal equations need the whole matrix and a solve, which is out of reach for a million features, and they exist only for squared error: the Huber and absolute losses of the last section, and the logistic loss of the classification section, have no closed form at all. The next note replaces the formula by an iteration that only needs the gradient, here, and shows that its speed is set by the same condition number that made the normal equations inaccurate.
Least squares reappears across the courses: GloVe word vectors are fitted by weighted least squares on log co-occurrence counts, the least-squares GAN replaces the discriminator’s cross-entropy by squared error, and alternating least squares fits the matrix factorization of recommender systems.
References#
- E. Sokolov et al. Машинное обучение (HSE), lecture notes, lecture 2: linear models, loss functions and quality measures for regression and lecture 3: overfitting, training linear regression.
- T. Hastie, R. Tibshirani, J. Friedman. The Elements of Statistical Learning, 2nd ed. Springer, 2009. Section 3.2 (least squares, its geometry and the sampling distribution of the coefficients), Section 3.2.2 (the Gauss–Markov theorem).
- C. M. Bishop. Pattern Recognition and Machine Learning. Springer, 2006. Section 3.1.1 (maximum likelihood and least squares), Section 3.1.2 (the geometry of least squares).
- M. P. Deisenroth, A. A. Faisal, C. S. Ong. Mathematics for Machine Learning. Cambridge University Press, 2020. Chapter 9 (linear regression), Section 3.8 (orthogonal projections).
- L. N. Trefethen, D. Bau III. Numerical Linear Algebra. SIAM, 1997. Lecture 11 (least squares problems), Lecture 19 (stability of least squares algorithms: the normal equations against QR and SVD).
- P. J. Huber. Robust estimation of a location parameter. Annals of Mathematical Statistics, 35(1), 1964.