Contents
Deep Breakdown
What it tells me (Situation Awareness): projects a vector onto an arbitrary subspace spanned by the columns of (a basis matrix). The result is the closest point in to . This generalizes the 1D formula: when is a single column , it reduces to . When is an orthonormal matrix (), it simplifies to . This is the core of orthogonal projection theory and appears directly in ordinary least squares regression (OLS), which is projection of the response vector onto the column space of .
Flowchart
Real-world use
Where it is used
OLS regression: is projection of onto . PCA: project data matrix onto the subspace of top principal components. Any dimensionality reduction that fits a low-dimensional subspace. Signal processing: project a signal vector onto a subspace spanned by basis functions.
Problem it solves
Given a subspace and a point , find the point in closest to . Equivalently: find coefficients such that is minimized. This is the least squares problem.
How it solves the problem
The projection where minimizes . Setting the gradient to zero: . This is the normal equation. Solving: (assuming has full column rank, so is invertible). The projection is .
Example in a business
In OLS regression: (design matrix), (response vector). is exactly , the projection of onto . The fitted values are the closest values to achievable by any linear combination of the predictors.
The formula, piece by piece
- : basis matrix; its columns are the basis vectors of ; must have full column rank ()
- : transpose of
- : Gram matrix; measures inner products between all pairs of basis vectors; invertible iff has full column rank
- : inverse of the Gram matrix; exists when columns of are linearly independent
- : the left pseudo-inverse of ; maps to (coordinate vector)
- : the projection matrix ; symmetric, idempotent, rank
- : the projection of onto
The formula in words
"Solve the normal equations: find the coefficients such that is closest to . The projection is times those coefficients. The matrix does this automatically for any ." Tiny example: , . . . . . . .
Critical Concepts
- Requires full column rank: must be invertible. If columns of are linearly dependent, use the pseudoinverse instead.
- Idempotent: . Projecting twice = projecting once.
- Symmetric: .
- Rank: .
- Orthonormal shortcut: if (columns are orthonormal), then (no inversion needed).
- OLS: , .
- Residual: is always orthogonal to every column of : .
Step-by-step calculation (tiny example)
Step 1: Set up B and x (two basis vectors in ), .
Step 2: Compute Gram matrix and its inverse . .
Step 3: Compute coordinates and projection . . . Residual: . .
Code examples
Beginner example (Python)
import numpy as np
# -- Projection onto general subspace: pi_U(x) = B(B^T B)^{-1} B^T x ---
B = np.array([[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
x = np.array([2.0, 3.0, 4.0])
gram_matrix = B.T @ B # B^T B
gram_inv = np.linalg.inv(gram_matrix) # (B^T B)^{-1}
coords = gram_inv @ B.T @ x # hat_lambda
projection = B @ coords # pi_U(x)
residual = x - projection
print(f"Gram matrix B^T B:\n{gram_matrix}")
print(f"\nCoordinates lambda_hat: {coords.round(4)}")
print(f"Projection pi_U(x): {projection.round(4)}")
print(f"Residual r: {residual.round(4)}")
print(f"B^T r (should be 0): {(B.T @ residual).round(10)}")
# Projection matrix
P_U = B @ gram_inv @ B.T
print(f"\nProjection matrix P_U (symmetric: {np.allclose(P_U, P_U.T)}, idempotent: {np.allclose(P_U @ P_U, P_U)})")Beginner example (R)
# -- Projection onto general subspace ---
B <- matrix(c(1,0,1, 0,1,1), nrow=3, ncol=2)
x <- c(2, 3, 4)
gram_matrix <- t(B) %*% B
gram_inv <- solve(gram_matrix)
coords <- gram_inv %*% t(B) %*% x
projection <- B %*% coords
residual <- x - projection
cat("Coordinates (lambda_hat):", round(coords, 4), "\n")
cat("Projection pi_U(x):", round(projection, 4), "\n")
cat("B^T r (should be 0):", round(t(B) %*% residual, 10), "\n")Professional example (Python)
import numpy as np
import pandas as pd
np.random.seed(42)
# -- Business scenario: OLS regression as projection ---
# Fitted values = projection of y onto col(X).
# Show that this minimizes ||y - y_hat||^2 (closest point in col(X) to y).
N = 100
# Design matrix X (intercept + 2 predictors)
X = np.column_stack([
np.ones(N),
np.random.uniform(1, 10, N),
np.random.uniform(0, 5, N),
])
true_beta = np.array([2.0, 1.5, -0.8])
y = X @ true_beta + np.random.randn(N) * 0.5
# OLS = projection: y_hat = X(X^T X)^{-1} X^T y
gram_matrix = X.T @ X
beta_hat = np.linalg.solve(gram_matrix, X.T @ y) # solve normal equations
y_hat = X @ beta_hat # fitted values = pi_U(y)
residuals = y - y_hat
# Verify properties
ortho_check = X.T @ residuals # should be ~0 (normal equations)
ss_res = np.sum(residuals**2)
ss_tot = np.sum((y - y.mean())**2)
r_squared = 1 - ss_res / ss_tot
print("OLS = projection of y onto col(X):")
print(f" beta_hat (estimated): {beta_hat.round(4)}")
print(f" true_beta: {true_beta}")
print(f" R^2: {r_squared:.4f}")
print(f" X^T * residuals (normal equations, should be ~0):")
print(f" {ortho_check.round(8)}")
print(f"\n||y - y_hat||^2 is minimized by OLS (projection theorem).")Source: MML1