BRAGA

02 Writing02-02 Notes02-02-145

Least Squares Solution (underdetermined)

Published 16 Apr 20269 min read
Contents
  1. 01Deep Breakdown
  2. 02Flowchart
  3. 03Real-world use
  4. 04The formula, piece by piece
  5. 05The formula in words
  6. 06Critical Concepts
  7. 07Step-by-step calculation (tiny example)
  8. 08Code examples
θ=(BTB)−1BTx\theta = (B^T B)^{-1} B^T x
(1)

Deep Breakdown

What it tells me (Situation Awareness): This is the Ordinary Least Squares (OLS) closed-form solution: given a design matrix BB and an observation vector xx, the parameter vector θ\theta that minimizes ∥Bθ−x∥2\|B\theta - x\|^2 is (BTB)−1BTx(B^T B)^{-1} B^T x. The term (BTB)−1BT(B^T B)^{-1} B^T is called the Moore-Penrose pseudo-inverse (or left pseudo-inverse) of BB when BB is tall and full column rank. In DA/DS you use this every time you train a linear regression model: sklearn's LinearRegression, R's lm(), and Excel's LINEST all solve this equation under the hood.

Flowchart

NoYesInput: designmatrix B (n x p)andobservations x(n x 1)Check: n p(moreobservationsthanparameters)Check: columnsof B are linearlyindependent (fullcolumn rank)Is B^T Binvertible (alleigenvalues 0)?Matrix issingular ornear-singular:use ridgeregression orpseudo-inverseCompute B^T B(p x p symmetricmatrix)Compute B^T x(p x 1 vector)Solve (B^T B)theta = B^T xtheta = (B^TB)^{-1} B^T xComputeresiduals: r = x -B * thetaReportR-squared,residual std, andcoefficientsignificance

Real-world use

Where it is used

Used every time you run OLS linear regression: fitting a trend line to revenue time series, modeling click-through rate as a function of bid price and ad quality score, or attributing sales lift to each marketing channel in a media mix model. Also the foundation of multiple regression, ANOVA, and many econometric models.

Problem it solves

You have nn observations and p<np < n unknown parameters. The system Bθ=xB\theta = x is overdetermined (more equations than unknowns) and generally has no exact solution. The least squares formula finds the θ\theta that minimizes the sum of squared residuals, giving the best linear unbiased estimate (BLUE) under Gauss-Markov conditions.

How it solves the problem

Setting the gradient of ∥Bθ−x∥2\|B\theta - x\|^2 with respect to θ\theta to zero gives the normal equations: BTBθ=BTxB^T B \theta = B^T x. If BB is full column rank, BTBB^T B is invertible and the unique solution is θ=(BTB)−1BTx\theta = (B^T B)^{-1} B^T x. Geometrically, BθB\theta is the projection of xx onto the column space of BB; the residual x−Bθx - B\theta is orthogonal to every column of BB.

Example in a business

A marketing analyst runs a media mix model: they have 52 weeks of total sales xx and a 52×452 \times 4 design matrix BB with columns for TV, digital, print spend, and a constant term. They solve θ=(BTB)−1BTx\theta = (B^T B)^{-1} B^T x to get 4 coefficients: the marginal return per euro spent in each channel plus the baseline. The result lets them reallocate budget toward the channels with the highest marginal return.

The formula, piece by piece

  • θ\theta: the parameter vector (p×1p \times 1) containing the regression coefficients to estimate
  • (BTB)−1(B^T B)^{-1}: the inverse of the p×pp \times p Gram matrix BTBB^T B; exists only if BB has full column rank
  • BTB^T: transpose of the design matrix BB (p×np \times n); left-multiplying by BTB^T projects the data into the parameter space
  • xx: the n×1n \times 1 observation/response vector
  • BTxB^T x: the p×1p \times 1 vector of dot products between each predictor column and the response; the "sufficient statistics" for OLS
  • (BTB)−1BT(B^T B)^{-1} B^T: called the left pseudo-inverse of BB; when applied to xx, it gives the least-squares coefficient vector Full formula: θ=(BTB)−1BTx\theta = (B^T B)^{-1} B^T x

The formula in words

"The least-squares regression coefficients are found by projecting the observations onto the column space of the design matrix, then scaling by the inverse of the feature covariance matrix." Tiny numeric example: B=[111213]B = \begin{bmatrix}1 & 1 \\ 1 & 2 \\ 1 & 3\end{bmatrix} (intercept + 1 predictor), x=[124]x = \begin{bmatrix}1 \\ 2 \\ 4\end{bmatrix}. BTB=[36614]B^T B = \begin{bmatrix}3 & 6 \\ 6 & 14\end{bmatrix}, BTx=[717]B^T x = \begin{bmatrix}7 \\ 17\end{bmatrix}. (BTB)−1=16[14−6−63](B^T B)^{-1} = \frac{1}{6}\begin{bmatrix}14 & -6 \\ -6 & 3\end{bmatrix}. θ=(BTB)−1BTx=16[14⋅7−6⋅17−6⋅7+3⋅17]=16[−49]=[−2/33/2]\theta = (B^T B)^{-1} B^T x = \frac{1}{6}\begin{bmatrix}14 \cdot 7 - 6 \cdot 17 \\ -6 \cdot 7 + 3 \cdot 17\end{bmatrix} = \frac{1}{6}\begin{bmatrix}-4 \\ 9\end{bmatrix} = \begin{bmatrix}-2/3 \\ 3/2\end{bmatrix}. Fitted line: x^i=−2/3+3/2⋅ti\hat{x}_i = -2/3 + 3/2 \cdot t_i.

Critical Concepts

  • Normal equations: (BTB)θ=BTx(B^T B)\theta = B^T x are the normal equations; the formula is just their explicit solution. In practice, never invert BTBB^T B directly; use np.linalg.lstsq or QR decomposition which are more numerically stable.
  • Invertibility requirement: BTBB^T B is invertible if and only if BB has full column rank (pp independent columns). Multicollinear features cause BTBB^T B to be singular or near-singular.
  • Geometric meaning: the fitted values x^=Bθ\hat{x} = B\theta are the orthogonal projection of xx onto the column space of BB; the residuals r=x−x^r = x - \hat{x} are perpendicular to every column of BB, i.e., BTr=0B^T r = 0.
  • Gauss-Markov theorem: if errors are zero-mean, uncorrelated, and equal-variance, OLS is BLUE (Best Linear Unbiased Estimator). Violation of these conditions calls for GLS, WLS, or robust regression.
  • Ridge regression regularization: (BTB+λI)−1BTx(B^T B + \lambda I)^{-1} B^T x is the ridge regression solution; it adds λ\lambda to all eigenvalues of BTBB^T B, ensuring invertibility and reducing variance at the cost of some bias.
  • Never use np.linalg.inv(B.T @ B): direct inversion amplifies condition number squared; always use np.linalg.lstsq(B, x) or scipy.linalg.lstsq which use QR or SVD internally.

Step-by-step calculation (tiny example)

Step 1: Set up B and x, then compute B^T B and B^T x B=[121315]B = \begin{bmatrix}1 & 2 \\ 1 & 3 \\ 1 & 5\end{bmatrix}, x=[347]x = \begin{bmatrix}3 \\ 4 \\ 7\end{bmatrix}. BTB=[1+1+12+3+52+3+54+9+25]=[3101038]B^T B = \begin{bmatrix}1+1+1 & 2+3+5 \\ 2+3+5 & 4+9+25\end{bmatrix} = \begin{bmatrix}3 & 10 \\ 10 & 38\end{bmatrix}. BTx=[3+4+76+12+35]=[1453]B^T x = \begin{bmatrix}3+4+7 \\ 6+12+35\end{bmatrix} = \begin{bmatrix}14 \\ 53\end{bmatrix}.

Step 2: Invert B^T B det⁡(BTB)=3⋅38−10⋅10=114−100=14\det(B^T B) = 3 \cdot 38 - 10 \cdot 10 = 114 - 100 = 14. (BTB)−1=114[38−10−103](B^T B)^{-1} = \frac{1}{14}\begin{bmatrix}38 & -10 \\ -10 & 3\end{bmatrix}.

Step 3: Compute theta and verify with residuals θ=(BTB)−1BTx=114[38⋅14+(−10)⋅53(−10)⋅14+3⋅53]=114[532−530−140+159]=114[219]=[1/719/14]\theta = (B^T B)^{-1} B^T x = \frac{1}{14}\begin{bmatrix}38 \cdot 14 + (-10) \cdot 53 \\ (-10) \cdot 14 + 3 \cdot 53\end{bmatrix} = \frac{1}{14}\begin{bmatrix}532 - 530 \\ -140 + 159\end{bmatrix} = \frac{1}{14}\begin{bmatrix}2 \\ 19\end{bmatrix} = \begin{bmatrix}1/7 \\ 19/14\end{bmatrix}. Fitted: x^1=1/7+2⋅19/14=1/7+19/7=20/7≈2.857\hat{x}_1 = 1/7 + 2 \cdot 19/14 = 1/7 + 19/7 = 20/7 \approx 2.857. Residual r1=3−20/7=1/7≈0.143r_1 = 3 - 20/7 = 1/7 \approx 0.143. The residuals are small.

Code examples

Beginner example (Python)

python
import numpy as np   # -- OLS closed-form solution: theta = (B^T B)^{-1} B^T x -------------
# Simple regression: one predictor + intercept
# Design matrix: column of 1s (intercept) + predictor values
B = np.array([ [1.0, 2.0], [1.0, 3.0], [1.0, 5.0], [1.0, 7.0],
])
x = np.array([3.0, 4.0, 7.0, 9.0])   # OLS via normal equations (for illustration; use lstsq in practice)
btb = B.T @ B
btx = B.T @ x
theta = np.linalg.solve(btb, btx)   # solve (B^T B) theta = B^T x (safer than explicit inverse)
x_hat = B @ theta
residuals = x - x_hat
r_squared = float(1 - np.sum(residuals**2) / np.sum((x - x.mean())**2))
print(f"theta (intercept, slope) = {theta.round(4)}")
print(f"Fitted values: {x_hat.round(4)}")
print(f"Residuals: {residuals.round(4)}")
print(f"R-squared: {r_squared:.4f}")   # Compare against np.linalg.lstsq
theta_lstsq, _, _, _ = np.linalg.lstsq(B, x, rcond=None)
print(f"\nnp.linalg.lstsq result: {theta_lstsq.round(6)}")
print(f"Max difference: {np.max(np.abs(theta - theta_lstsq)):.2e}")

Beginner example (R)

r
# -- OLS closed-form solution:
theta = (B^T B)^{-1} B^T x -------------
B <- matrix(c( 1, 2, 1, 3, 1, 5, 1, 7
), nrow = 4, byrow = TRUE)
x <- c(3.0, 4.0, 7.0, 9.0)  # Normal equations solution
btb <- t(B) %*% B
btx <- t(B) %*% x
theta <- solve(btb, btx)  # solve (B^T B)
theta = B^T x
x_hat <- B %*% theta
residuals <- x - x_hat
r_squared <- 1 - sum(residuals^2) / sum((x - mean(x))^2)
cat(sprintf("theta (intercept, slope) = [%.4f, %.4f]\n", theta[1], theta[2]))
cat(sprintf("R-squared = %.4f\n", r_squared))  # Compare against lm()
fit <- lm(x ~ B[, 2])
cat(sprintf("\nlm() coefficients: intercept = %.4f, slope = %.4f\n", coef(fit)[1], coef(fit)[2]))
cat(sprintf("Max difference: %.2e\n", max(abs(theta - coef(fit)))))

Professional example (Python)

python
import numpy as np
import pandas as pd
np.random.seed(42)   # -- Business scenario: media mix model via OLS (4 channels + intercept)
# Estimate the revenue contribution of TV, digital, print, and radio.
N_WEEKS = 104   # 2 years of weekly data
CHANNEL_NAMES = ["tv", "digital", "print", "radio"]
TRUE_COEFS = np.array([50.0, 1.2, 0.8, 0.5, 0.3])   # intercept + 4 channel returns (EUR per EUR spent) # Simulate spend and revenue
spend_raw = np.abs(np.random.normal(loc=20_000, scale=5_000, size=(N_WEEKS, 4)))
spend_df = pd.DataFrame(spend_raw, columns=CHANNEL_NAMES)
B = np.column_stack([np.ones(N_WEEKS), spend_raw])   # design matrix with intercept
noise = np.random.normal(0, 2_000, size=N_WEEKS)
revenue = B @ TRUE_COEFS + noise   # true signal + noise # OLS solution via normal equations (using solve, not inv, for numerical stability)
btb = B.T @ B
btx = B.T @ revenue
theta = np.linalg.solve(btb, btx)   # Evaluate fit
revenue_hat = B @ theta
residuals = revenue - revenue_hat
ss_res = float(np.sum(residuals**2))
ss_tot = float(np.sum((revenue - revenue.mean())**2))
r_squared = 1.0 - ss_res / ss_tot
residual_std = float(np.sqrt(ss_res / (N_WEEKS - len(theta))))   # Condition number of B^T B (diagnose multicollinearity)
cond_btb = float(np.linalg.cond(btb))
param_names = ["intercept"] + CHANNEL_NAMES
results_df = pd.DataFrame({ "parameter": param_names, "true_coef": TRUE_COEFS.round(3), "estimated_coef": theta.round(3), "error": (theta - TRUE_COEFS).round(3),
})
print(results_df.to_string(index=False))
print(f"\nR-squared: {r_squared:.4f}")
print(f"Residual std (EUR): {residual_std:.2f}")
print(f"Condition number of B^T B: {cond_btb:.1f}")
print("\nInterpretation: coefficients estimate EUR revenue per EUR spent per channel; high condition number signals multicollinearity risk.")

Source: AIO

#linear-algebra#advanced-linear-algebra-and-decompositions#linear-transformations-and-least-squares

Keyboard shortcuts

Single keys, ignored while typing in a field or with Cmd, Ctrl or Alt held.

0
Home
1 2 3 4
Work, Writing, Tools, About
j / k
Next / previous section on this page
n / p
Next / previous project or essay
u
Up one level
l
Deutsch
t
Light or dark theme
?
This list
Esc
Close