QR Decomposition
Splitting a matrix into an orthogonal piece and a triangular piece — the numerically stable engine behind real-world least-squares regression.
Prerequisites: Gram-Schmidt Orthogonalization, Inner Products and Orthogonality
Fitting a regression by literally computing works on paper but is numerically fragile: squaring into squares any near-collinearity problems in the data before you even start inverting. QR decomposition sidesteps this entirely — it factors the design matrix directly, without ever forming , and is the actual method most serious regression libraries use under the hood.
An analogy: a rotate-then-stretch recipe
Any matrix's effect on space can be described as first rotating (and possibly reflecting) everything rigidly, without any distortion, and then stretching or shearing along the new axes. QR decomposition writes exactly this recipe down explicitly: is the pure rotation/reflection part — it preserves lengths and angles perfectly, like a rigid camera turn — and is the triangular "stretch" part that does all the actual distorting. Because never distorts anything, it never amplifies numerical errors, which is precisely why algorithms built on QR tend to be far more numerically trustworthy than ones that square the matrix first.
The mathematics, one symbol at a time
QR decomposition factors a matrix (say, with , a tall design matrix) as
where is an matrix with orthonormal columns (each column has length 1, and every pair of columns is orthogonal, so ) and is an upper-triangular matrix. In words: 's columns form a "clean," non-overlapping coordinate system for the same space 's columns span, built via Gram-Schmidt (see Gram-Schmidt Orthogonalization), and records how the original columns of combine those clean directions to reconstruct themselves. For solving least squares, becomes ; multiplying both sides by (which, crucially, exactly undoes since , with no numerical error introduced) gives — a small, easy, upper-triangular system, solved directly by back-substitution, with none of the error-amplifying squaring that requires.
Worked example 1: QR by hand via Gram-Schmidt
Take 's columns , — the same pair from the Gram-Schmidt example. Orthogonalizing gave , . Normalize: , so ; , so . These form . Then : , , (and by construction). So — upper-triangular, exactly as required.
Worked example 2: solving a small regression via QR
Reusing the earlier one-variable regression setup, , : , so , and (a matrix here, since there's only one column). Then . Solving : — matching the earlier pseudoinverse answer of exactly, but reached without ever squaring into .
What this means in practice
QR decomposition is the default method inside numpy.linalg.lstsq, R's lm(), and most production regression code precisely because it avoids ever forming , keeping numerical error manageable even with moderately collinear factors. It's also the standard way to compute an orthonormal basis for a subspace, and shows up as a building block inside eigenvalue algorithms and the singular value decomposition (see Singular Value Decomposition).
QR decomposition writes with orthonormal (a pure, error-free rotation) and upper-triangular; solving least squares via avoids ever forming , making it the numerically preferred alternative to the normal-equations formula .
Don't assume QR and the normal-equations formula always give meaningfully different numerical answers — on well-conditioned, nearly-orthogonal data they agree closely, and the difference only becomes practically important as predictors get more collinear (see The Matrix Condition Number). The mistake is picking the normal-equations formula out of habit for any regression pipeline that might later be fed correlated factors, rather than defaulting to QR (or SVD) as the numerically robust choice from the start.
Related concepts
Practice in interviews
Further reading
- Trefethen & Bau, Numerical Linear Algebra, lecture 7
- Golub & Van Loan, Matrix Computations, ch. 5