linearly

Lecture 12

Least Squares & Linear Regression

No line goes through all the data. Least squares picks the one that misses by the least, and it is the projection from the last chapter wearing different clothes.

65 slides / MIT 18.06, Lecture 16 / Strang §4.3

Slide 1 of 65
1 / 65

The idea in one sentence

When no exact answer exists, take the one whose leftover error is as small as it can be, and that answer is the projection from the last chapter read as a list of weights.

Five equations, two knobs

Here is the measurements table one last time, with all five rows asking for the same pair of coefficients u1u_1 and u2u_2:

5u1+2u2=33u1+4u2=82u1+8u2=71u1+5u2=94u1+7u2=2\begin{aligned} 5u_1 + 2u_2 &= 3 \\ 3u_1 + 4u_2 &= 8 \\ 2u_1 + 8u_2 &= 7 \\ 1u_1 + 5u_2 &= 9 \\ 4u_1 + 7u_2 &= 2 \end{aligned}

Lecture 11 showed there is no answer. Rank 2 for the matrix of coefficients, rank 3 once the target joins as a third column, so the target points somewhere the two columns cannot go. That is the normal situation for data, and a chapter that stops there has taught you nothing you can use. This one solves it anyway.

The same numbers, read two ways

Before solving, look at the failure from both sides, because the two views explain each other.

Two features span a plane, and a plane inside five-dimensional space is hard to draw. So for the pictures, use one feature and an intercept: keep the weight column and the target column. Write wiw_i for the weight in row ii and bib_i for its target, and fit the two unknowns CC and DD in

bi    C+Dwi.b_i \;\approx\; C + D\,w_i .

Every argument below works for any number of columns. The two-feature answer arrives at the end of the next section.

Now the two readings. Read a row as a point. Row one says the pair (w1,b1)=(5,3)(w_1, b_1) = (5, 3) was measured, and a candidate line either passes near it or does not. Five rows are five dots on a page, and the unknowns CC and DD pick out one line among all lines. That is data space.

Read the same row as a constraint instead. Row one demands C+5D=3C + 5D = 3, and the pairs (C,D)(C, D) that satisfy it form a straight line in a plane whose axes are the unknowns. Five rows are five lines, and a candidate line in data space is a single dot here. That is weight space.

24651081012140−1−2−3data space: a line among pointsweight space: a point among lineswtargetCDtarget = 11 − 2w(11, −2)
Fig. 1 

The same five rows in two rooms. On the left each row is a dot and a candidate model is a line. On the right each row is a line and a candidate model is a dot. The bold line and the bold dot are the same candidate. No dot sits on all five lines, so no line passes through all five dots.

The two rooms hold the same information turned inside out. A line over there is a point over here. Fitting the data exactly would mean finding one point that sits on all five weight-space lines at once, and the picture says there is no such point. Every pair of lines crosses somewhere different, which is another way of saying the first two rows and the third row want different coefficients.

Choosing what best means

No point sits on all five lines, so pick a rule for scoring the ones that do not. Write the model as Ax=bAx = b, where AA holds the columns, xx holds the unknown coefficients, and bb holds the targets. Any candidate xx leaves a leftover bAxb - Ax, one number per row, and the score is the total of their squares:

E(x)  =  bAx2  =  i(bi(Ax)i)2.E(x) \;=\; \norm{b - Ax}^2 \;=\; \sum_i \left( b_i - (Ax)_i \right)^2 .

Squaring is a choice, and absolute values would also measure the leftovers. Two reasons pick squares. The first is geometric. That sum is the ordinary squared distance from the point bb to the point AxAx, so making it small means finding the reachable point closest to bb, which is the projection Lecture 11 already built. The second is practical: squares make the problem linear, so a formula exists. Absolute values give a perfectly sensible score with no closed form.

Squaring has a cost. A leftover of 4 counts as much as sixteen leftovers of 1, so one bad outlier can drag the whole fit toward itself. Every model fit with squares carries that sensitivity.

The score has a second reading, back in weight space. Write aia_i for row ii of AA, so row ii asks for aiTx=bia_i\T x = b_i and draws one line in the picture of unknowns. The distance from a candidate point xx to that line is biaiTx/ai\lvert b_i - a_i\T x \rvert / \norm{a_i}, which is the leftover divided by the length of the row. Squaring and adding gives

E(x)  =  iai2di(x)2,E(x) \;=\; \sum_i \norm{a_i}^2 \, d_i(x)^2 ,

where di(x)d_i(x) is that distance. So the answer settles at the point closest to all five lines at once, with each line pulling in proportion to the squared length of its row. A row of big numbers is a line that insists.

So the least-squares answer x^\hat{x} is the coefficient list of the projection, and p=Ax^p = A\hat{x} is the shadow of the data on what the model can reach. Nothing new has happened yet. The coefficients now have a meaning, and the leftover has a name: the residual.

The normal equations, twice

Two roads lead to the same equation. Take both, because each answers a question the other leaves open.

By perpendicularity. This is the argument from Lecture 11, one line long. At the closest point, the residual e=bAx^e = b - A\hat{x} is perpendicular to every column of AA, and stacking those conditions is what ATA\T does:

AT(bAx^)=0ATAx^=ATb.A\T (b - A\hat{x}) = 0 \qquad\Longrightarrow\qquad A\T A\, \hat{x} = A\T b .

That pair of equations is called the normal equations, from the old word normal meaning perpendicular. They are the whole of least squares.

By algebra. The first road shows that x^\hat{x} is a special point. It does not show that x^\hat{x} beats every other point, and it does not show that no second point ties with it. Expand the score instead. For any xx,

E(x)=(bAx)T(bAx)=bTb2xTATb+xTATAx.E(x) = (b - Ax)\T (b - Ax) = b\T b - 2x\T A\T b + x\T A\T A x .

Let x^\hat{x} be a solution of ATAx^=ATbA\T A \hat{x} = A\T b and write any other candidate as x=x^+dx = \hat{x} + d. Substitute and collect terms. The cross terms combine into a single bracket:

E(x^+d)=E(x^)+2dT(ATAx^ATb)+dTATAd.E(\hat{x} + d) = E(\hat{x}) + 2\,d\T \left( A\T A \hat{x} - A\T b \right) + d\T A\T A d .

The bracket is zero, by the choice of x^\hat{x}. And dTATAd=(Ad)T(Ad)=Ad2d\T A\T A d = (Ad)\T (Ad) = \norm{Ad}^2. So

E(x^+d)=E(x^)+Ad2    E(x^).E(\hat{x} + d) = E(\hat{x}) + \norm{Ad}^2 \;\ge\; E(\hat{x}) .

Every other candidate scores worse by exactly Ad2\norm{Ad}^2, the squared length of the change that move makes inside the column space. Equality needs Ad=0Ad = 0, and with independent columns that forces d=0d = 0. So x^\hat{x} is the winner and it is the only one. Lecture 11 proved N(ATA)=N(A)N(A\T A) = N(A), which is the same independence condition seen from the other end, and it is what lets you write x^=(ATA)1ATb\hat{x} = (A\T A)^{-1} A\T b when you want the formula spelled out.

The answer, in numbers

For the line fit, AA has a column of ones and the weight column. Then ATAA\T A counts, sums, and sums of squares:

ATA=[5151555],ATb=[2970].A\T A = \begin{bmatrix} 5 & 15 \\ 15 & 55 \end{bmatrix}, \qquad A\T b = \begin{bmatrix} 29 \\ 70 \end{bmatrix}.

The 5 is the number of rows, the 15 is wi\sum w_i, the 55 is wi2\sum w_i^2, the 29 is bi\sum b_i, and the 70 is wibi\sum w_i b_i. The determinant is 275225=50275 - 225 = 50, and solving gives C=10.9C = 10.9 and D=1.7D = -1.7 exactly.

+2.2−2.1123456510wtargettarget ≈ 10.9 − 1.7wdashed = residual, and 9.9 is their total
Fig. 2 

The line that least squares picks, with every residual drawn. The circles on the line are what the model predicts, the filled dots are what was measured, and the dashed gaps between them are what the fit could not explain.

The five fitted values are 2.42.4, 5.85.8, 7.57.5, 9.29.2, 4.14.1, and the residuals are 0.60.6, 2.22.2, 0.5-0.5, 0.2-0.2, 2.1-2.1. Squared and added they come to 9.99.9. Try any other line and you get a bigger number, which the lab below lets you test for yourself.

Two facts about those residuals are not luck.

150.6132.212−0.511−0.214−2.100=oneswAᵀe0.6 + 2.2 − 0.5 − 0.2 − 2.1 = 03 + 6.6 − 1 − 0.2 − 8.4 = 0the residual leans on neither column,so no line can use it to improve
Fig. 3 

Perpendicularity in numbers. The first row of ATA\T is the intercept column, so its dot product with the residual is the plain sum. The second row is the weight column, so its dot product is the weighted sum. Both come out zero.

They add to zero, and their weighted total wiei\sum w_i e_i is zero as well. Both are just ATe=0A\T e = 0 read one row at a time. The first row of ATA\T is the row of ones, so its dot product with ee is the plain sum. The second row is ww, so its dot product is the weighted sum. Any model with an intercept column has residuals summing to zero, and that comes from perpendicularity alone. The data has no say in it.

It also explains why no better line exists. To improve the fit you would tilt or shift the line, which changes the prediction by some combination of the two columns. But the residual leans on neither column, so every such change moves you away from bb.

Watch what one move costs. Hold the slope at 1.7-1.7 and slide the intercept away from 10.910.9 by an amount tt, which is the direction d=(1,0)d = (1, 0). The algebra above says the score becomes 9.9+Ad2t29.9 + \norm{Ad}^2 t^2, and Ad2\norm{Ad}^2 for this dd is the top left entry of ATAA\T A, which is 5. So one full unit of shift costs exactly 5.

910111213102030C, with the slope held at −1.7total squared error9.9 at C = 10.9+514.9 after a shift of 1
Fig. 4 

One straight walk away from the answer. Sliding the intercept by tt raises the score by 5t25t^2, so the bottom of this parabola sits exactly where the normal equations put it.

Here is the whole story as one surface. Score every possible pair (C,D)(C, D) by its total squared error, and the result is a bowl. The algebra above already told you its shape: E(x^+d)=9.9+dTATAdE(\hat{x} + d) = 9.9 + d\T A\T A d, so the level sets are ellipses centered on the answer.

791113150−1−2−3CDthe dot is (10.9, −1.7), where the error is 9.9error 27.9
Fig. 5 

The same story in two dimensions. Each ellipse collects the lines with one fixed total squared error, and the dot at the center is the winner. The long thin shape means the score hardly changes along one direction, which is the direction a fitted model is least sure about.

The ellipses are long and thin, and that ratio matters later. It says the score barely changes along one direction and changes fast along another, so a fit can be confidently wrong about the individual coefficients while being right about their combination.

Try it. Move the data, then try to beat the fit
wtarget

best line: 10.9 1.7w
its error: 9.90
your error: 21.30

Drag any dot to change the data. Green is the line the normal equations name, warm is yours, and the blue springs are the residuals it has to live with.

Now the original two-feature question, with ww and hh as the columns and no intercept:

ATA=[557171158],ATb=[70153],det=3649.A\T A = \begin{bmatrix} 55 & 71 \\ 71 & 158 \end{bmatrix}, \qquad A\T b = \begin{bmatrix} 70 \\ 153 \end{bmatrix}, \qquad \det = 3649 .

Solving gives x^=(197/3649,  3445/3649)\hat{x} = (197/3649,\; 3445/3649), which is about (0.0540,  0.9441)(0.0540,\; 0.9441). The fitted values are 2.162.16, 3.943.94, 7.667.66, 4.774.77, 6.826.82, and the squared residuals add to 58.7758.77. The code below computes it, checks it against np.linalg.lstsq, and confirms that the residual dots to zero against both columns. The fit is poor, and it should be: the numbers in the table were never generated by a rule. Least squares always returns an answer. Reading whether that answer means anything is your job, and the formula will not do it for you.

python
import numpy as np

w = np.array([5., 3., 2., 1., 4.])
h = np.array([2., 4., 8., 5., 7.])
b = np.array([3., 8., 7., 9., 2.])

A = np.column_stack([w, h])
print(A.T @ A)                      # [[ 55.  71.] [ 71. 158.]]
print(A.T @ b)                      # [ 70. 153.]
x_hat = np.linalg.solve(A.T @ A, A.T @ b)
print(np.round(x_hat, 4))           # [0.054  0.9441]
print(np.round(np.linalg.lstsq(A, b, rcond=None)[0], 4))   # the same numbers
e = b - A @ x_hat
print(bool(abs(A.T @ e).max() < 1e-6))     # True   e leans on neither column
print(round(float(e @ e), 4))              # 58.7745

M = np.column_stack([np.ones(5), w])      # intercept column, then one feature
print(M.T @ M)                      # [[ 5. 15.] [15. 55.]]
print(M.T @ b)                      # [29. 70.]
c, d = np.linalg.solve(M.T @ M, M.T @ b)
print(round(c, 10), round(d, 10))   # 10.9 -1.7
r = b - M @ np.array([c, d])
print(np.round(M @ np.array([c, d]), 4))   # [2.4 5.8 7.5 9.2 4.1]
print(np.round(r, 4))                      # [ 0.6  2.2 -0.5 -0.2 -2.1]
print(bool(abs(r.sum()) < 1e-6), bool(abs(w @ r) < 1e-6))    # True True
print(round(float(r @ r), 4))              # 9.9
for C, D in [(11.0, -1.7), (10.9, -1.6), (10.0, -1.5)]:
    print(C, D, round(float(((b - (C + D * w)) ** 2).sum()), 4))
# 11.0 -1.7 9.95 / 10.9 -1.6 10.45 / 10.0 -1.5 10.75: all worse than 9.9

More columns, and the trap that comes with them

Nothing in the derivation cared what the columns held. They can hold anything computed from the input, and the fit is still linear in the unknowns, which is all least squares ever needed. Put 11, tt, and t2t^2 in three columns and you are fitting a parabola with the same machinery.

Take five readings of something that bends: t=2,1,0,1,2t = -2, -1, 0, 1, 2 with values 7,1,0,3,97, 1, 0, 3, 9. With two columns the best line is 4+0.6t4 + 0.6t and the error is 56.456.4. Add the t2t^2 column and the best parabola is 2t2+0.6t2t^2 + 0.6t, with error 0.40.4.

−2−10120510tythe dashed line: error 56.4the solid parabola: error 0.4
Fig. 6 

Five readings that bend. The dashed line is the best a straight fit can do, and the solid curve is the best parabola, found by the same normal equations with one more column.

A curve is the same projection as before, onto a column space that now happens to contain curved shapes.

Adding columns can only lower the error, since the old fit is still available with a zero coefficient on the new column. That sounds like good news until you follow it to the end. The measurements table has five rows and five distinct weights, so five columns of powers reach every possible target vector, and the error drops to exactly zero.

12345051015wtargetsolid curve, five columns: error exactly 0dashed line, two columns: error 9.9
Fig. 7 

Five points and five columns of powers. The curve hits every point exactly, so the error is zero, and it tells you nothing about a weight it has not seen.

The curve through all five points is not a discovery. It is the data written in a different alphabet. It dips below 00 between points that never left the range 22 to 99, and asked about a weight of 66 it answers 4949 with total confidence. The error went to zero because the model ran out of things to be wrong about.

This is the training step

Nothing in this chapter mentioned learning, and yet this is what fitting a linear model is. The columns are features, the unknowns are weights, the score is the loss, and the answer is the trained model. When a library fits a linear regression it forms the normal equations, or it does something numerically better that lands in the same place.

Gradient descent lands there too. The gradient of the score is

E(x)=2AT(Axb),\nabla E(x) = 2 A\T (Ax - b),

and setting it to zero is the normal equations again, rearranged. So descent walks downhill on the bowl from Figure 5 toward the point the normal equations name. It gets there slowly when the bowl is long and thin, because the step that suits one direction overshoots the other, and that zigzag has a name and a cure that arrive in Lecture 15.

681012140−1−2−3CDstart herethe answer80 steps, and still bouncing across the valley
Fig. 8 

Gradient descent on the same bowl, started at the open circle. Every step points straight downhill, and the steepest direction points across the valley, so the walk zigzags toward the point the normal equations name in one shot.

python
import numpy as np

t = np.array([-2., -1., 0., 1., 2.])
y = np.array([7., 1., 0., 3., 9.])
line = np.column_stack([np.ones(5), t])
para = np.column_stack([np.ones(5), t, t ** 2])
c_line = np.linalg.solve(line.T @ line, line.T @ y)
c_para = np.linalg.solve(para.T @ para, para.T @ y)
sse = lambda X, c: round(float(((y - X @ c) ** 2).sum()), 2)
print(np.round(c_line, 4), sse(line, c_line))
print(np.round(c_para, 4), sse(para, c_para))
# [4.  0.6] 56.4        a line cannot bend
# [0.  0.6 2. ] 0.4     one more column, and it can

w = np.array([5., 3., 2., 1., 4.])
b = np.array([3., 8., 7., 9., 2.])
for k in (2, 3, 5):                     # k columns of powers of w
    V = np.vander(w, k)
    c = np.linalg.lstsq(V, b, rcond=None)[0]
    print(k, round(float(((b - V @ c) ** 2).sum()), 2))
# 2 9.9 / 3 9.83 / 5 0.0   five columns, five rows, nothing left to get wrong
print(f"{float(np.linalg.cond(np.vander(w, 5))):.1e}")     # 2.6e+04

A = np.column_stack([np.ones(5), w])   # gradient descent finds the same point
x = np.zeros(2)
for step in range(3000):
    x = x - 0.008 * (2 * A.T @ (A @ x - b))
print(np.round(x, 4))                   # [10.9 -1.7]

Where this is going

Least squares is the first honest answer this course has given to a question with no answer. It came from one geometric fact, that the shortest distance to a subspace is measured along a perpendicular, and it produced a formula you can compute.

Two threads run onward. The first is numerical. Forming ATAA\T A is the wrong way to compute x^\hat{x}, and Lecture 13 shows the right way by building orthonormal columns first, which turns the normal equations into back substitution and stops the condition number from being squared. The second is what happens when the columns are dependent, so ATAA\T A has no inverse and the best answer is a whole flat set of them. Choosing sensibly among that set is what the pseudoinverse does, and Part VI cashes it in with the singular value decomposition.