A system with no solution
Lesson 3.3.2 solved a tall system, three equations in two unknowns. Change its last right-hand side from 4 to 5:
The first two equations give , and then the third reads . As a matrix equation this is with . Lesson 3.5.1 found that is not in the column space of , so no solves it.
A system with more equations than unknowns is overdetermined. Data gives such systems all the time: many measurements, few unknowns, and a little error in each measurement.
The best answer
When no makes , look for the that makes as close to as possible. The gap has one entry per equation, the amount by which that equation misses. Its squared length is the sum of the squared misses.
| 1 | |||
| 0.5 | |||
| 0.75 | |||
| 0.2857 |
The first row meets two equations exactly and misses the third by 1. The last row meets none of them exactly, yet its total is the smallest. It is the least-squares solution, found below.
Rule: Least squares
, read "x hat", is the least-squares solution of . The squared length adds the squares of the misses. When the system has a solution, is that solution, with every miss 0.
The normal equations
Every product lies in the column space of . The point of the column space closest to is its projection (lesson 3.5.2). So , and the residual is orthogonal to every column of .
Rule: The normal equations
"Normal" means at right angles. When the columns of are independent, has an inverse and , exactly the projection formula of lesson 3.5.2.
For the system above:
Three times the first equation minus the second gives . So .
The residual is . It is orthogonal to both columns: and . Its squared length is , the smallest in the table.
Try it
The cell forms the normal equations for , solves them, and prints the residual, and the sum of squares.
The loop is the table above. round keeps the last digits from showing rounding.
Fitting a line to points
Lesson 1.2.1 drew the line through two points. Points that do not lie on one line have no line through them all, but least squares finds the line that comes closest.
Take five points: , , , and . Look for a line , with intercept and slope . Each point asks for , so there are five equations in two unknowns:
The column of ones carries the intercept, and the column of values the slope. The normal equations hold the sums of the data:
Here 5 is the number of points, 10 the sum of the and 30 the sum of their squares. On the right, 17 is the sum of the and 46 the sum of the products .
Solving gives and : the line .
| 0 | 1 | 2 | 3 | 4 | |
|---|---|---|---|---|---|
| 1 | 2 | 4 | 4 | 6 | |
| fitted | 1 | 2.2 | 3.4 | 4.6 | 5.8 |
| residual | 0 | 0.6 | 0.2 |
The squared residuals add up to 0.8. No other line does better: the line through the first and last points leaves 0.875, and leaves 2.
Two lines through five points, with each residual drawn as a vertical gap. Least squares makes the squared gaps add up to the least possible, 0.8; the line through the end points leaves 0.875.
Each residual is a vertical gap, a miss in , not the distance from the point to the line at right angles. The right angle of lesson 3.5.2 lives in : the residual vector is orthogonal to the two columns of .
That right angle says two things you can check. The residuals add up to 0, since they are orthogonal to the column of ones. And the line passes through the mean point : .
The slope as a projection
Centre the data as in case study 3.1.4: subtract the means to get and . The slope is the coefficient of the projection of onto (lesson 3.5.2), and the intercept puts the line through the mean point.
Rule: Least-squares line
and are the centred data. Here and , so , and .
Case study 3.5.5 uses exactly this projection to find a hedge.
Try it
The first lines build from a column of ones and the values, form the normal equations and solve them.
Then the residuals, their sum of squares, their sum and their dot product with . The last lines are the slope from the centred data, and NumPy's own polyfit, which lists the slope first.
A noisy line
Real data has more points and more noise. The next cell makes 20 points from the line , adds a random error to each, and fits a line. The data is invented with a fixed seed, so every run gives the same points.
The fit is : close to the line the points came from, but not on it, because of the noise. How far off a fit like this can be is a question of statistics, which module 5.10 adds.
Try it
rng.normal(0, 1, 20) draws 20 random errors of typical size 1 (Level 5 explains it).
np.linalg.lstsq returns four things: , the sum of squared residuals, the rank of , and numbers called singular values (lesson 3.8.1). The last line solves the normal equations instead, for comparison.
Solve with lstsq, not with AᵀA
The normal equations are the idea; np.linalg.lstsq(A, b, rcond=None) is the tool. It works on itself and never forms .
Forming squares the condition number of lesson 3.3.2, which measures how much a system can magnify small errors such as rounding. A computer keeps about 16 significant digits, and a condition number of can cost about of them.
Calendar years. Fit a trend against the years 2015 to 2024. The column of ones and the column of years point almost the same way: the angle between them is 0.08°. Then , but , which leaves only about 4 safe digits.
Centring the years first, as for the slope above, makes the two columns orthogonal. The condition number drops to 2.8723. Centring helps lstsq too: practice set 3.5.4 meets values so large that it loses the slope without it.
Columns that differ in the eighth decimal. Take columns and . Each diagonal entry of is , which a computer rounds to exactly 1. So the computed is , singular, and solve stops with an error.
lstsq still finds for .
Rule: In code
Use it for least squares rather than solving , which squares the condition number. rcond=None sets how small a singular value counts as zero; it is the setting NumPy recommends.
Try it
The first lines compare the condition numbers for the years, before and after centring, and print the angle between the two columns.
Then the second example: the computed is exactly singular, solve raises LinAlgError, and lstsq returns .
When the columns are dependent
If the columns of are dependent (lesson 3.5.1), has no inverse. The projection is still unique: it is the nearest point of the column space. But many give that same .
Fit the five points with a third column that is twice the second, . Every choice with and gives the fitted values : , and among them.
lstsq does not fail here. It reports rank 2 instead of 3, returns the shortest , here , and leaves its sum of squares empty. Read the rank before reading the answer.
The same happens when every is the same: the column of values is a multiple of the column of ones. For points , , , a best line would be vertical, which has no slope (lesson 1.2.1). lstsq reports rank 1 and returns , which means nothing as an intercept and slope.
Rule: Dependent columns
When the rank is below the number of columns, many give . Each is one of them plus a vector of the null space (lesson 3.5.1). Check the rank that lstsq returns.
Try it
D has the columns , and . lstsq returns its shortest answer and rank 2; the loop shows that three different answers give the same fitted values.
The last lines are the three points with the same .
Case study 3.5.5 uses least squares twice: for the minimum-variance hedge, and for the closest copy of a payoff that cannot be copied exactly. Module 5.10 adds the statistics: how far may be from the truth.
Common mistakes
- Least squares counts squared misses, not equations met. meets two of the three equations exactly, but its total, 0.5, is larger than the least-squares 0.2857.
- Residuals are vertical gaps, misses in . They are not the distances from the points to the line at right angles.
- Keep the column of ones. Without it the line must pass through the origin: gives and a sum of squares of 2.4667, not 0.8.
- The order of the columns is the order of . With the ones first, the intercept comes first;
np.polyfitlists the slope first. - Do not form for real data. It squares the condition number; use
lstsq, and centre data such as calendar years. - Check the rank. With dependent columns
lstsqstill returns an answer, but not the only one.
Least squares
0 of 11 correct
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
How to type answers
- Powers with
^:x^7,2^(1/3),a^-2. - Multiply with
*or by writing side by side:3x^2,2(x+1). ln(x)is the natural log,log(x, 2)is log base 2,eis Euler's number,sqrt(x)is a square root.sin(x),cos(x)andtan(x)take radians; writepifor π andsin(x)^2for sin²x.- Your first answer to each question is saved: it counts towards your score and brings the question back for review.
- Exact answers like
ln(20)/ln(3)are best. Decimals need about 4 significant figures.
Summary card
- An overdetermined system usually has no solution. The least-squares solution makes the sum of squared misses smallest.
- is the projection of onto the column space, so the residual is orthogonal to the columns: the normal equations .
- A line through points uses . The residuals are vertical gaps, add up to 0, and the line passes through ; the slope is .
- Use
np.linalg.lstsq(A, b, rcond=None): forming squares the condition number. - With dependent columns, is unique but is not;
lstsqreturns the shortest and reports the rank.