Lesson 51 of 180, in Analytic Geometry
Projection Matrices Transform Whole Datasets
A projection can explain one observation with a single direction. The more useful question for an AI pipeline is what happens when the observation is a dataset: can one small linear rule transform every row consistently?
Yes. A projection matrix applies the same nearest-point operation to every sample. It preserves the component along a chosen direction and removes the orthogonal component, so a point cloud becomes a one-direction representation while every output still has the original number of coordinates.
By the end of this lesson, you will be able to construct a line-projection matrix, apply it to a row-stored dataset, and check the two identities that make it a projection: symmetry and idempotence.
Learning outcome: Construct and check a simple projection matrix.
This lesson builds on Lesson 035: Matrices Represent Linear Mappings, where matrices became reusable rules, and Lesson 050: Projection Finds the Nearest Point, where one vector was projected onto a line. Section 3.8 of the official Mathematics for Machine Learning book develops the projection-matrix construction. The dataset, calculations, visual, NumPy implementation, and assessments here are original.
Turn one line projection into a matrix
Let be a nonzero direction vector, and let be the line through the origin that it defines. For one column-vector observation , the previous lesson gave
The scalar is a dot product. Rewrite the right side so that appears as the final factor:
That rearrangement exposes a reusable linear rule.
The matrix has two immediate geometric consequences. First,
so is symmetric. Second, once a vector has reached the line, projecting it again does nothing:
This is called idempotence. To see why it holds, let . Then
Symmetry describes the right-angle geometry; idempotence describes the fact that the output is already settled on the target line. Neither property says that is invertible. A one-direction projection usually discards the other directions.
Apply the same rule to a row-stored dataset
AI data is often stored with one sample per row. Let
where is the number of samples and is the number of features. Because is symmetric, multiplying on the right applies the column-vector projection to each row’s transpose:
Each row of is still length , but every row lies on the one-dimensional line . The data has not been reduced to one coordinate yet. The coefficient matrix
stores the one coordinate per sample, and the reconstruction is . Keeping is convenient when the downstream code expects the original feature width; keeping is convenient when the goal is a compact one-number representation.
A four-sample point cloud, transformed two ways
Use the direction
The outer product and projection matrix are
Take four two-feature observations as rows:
Geometry: each row moves to U
- Original observation
- Projected observation
- Target line U
Matrix: one rule for all rows
With samples stored as rows, multiply X on the right by P.
Y = X @ P
| Sample | Original xᵢ | Coefficient zᵢ | Projected yᵢ | Residual xᵢ − yᵢ |
|---|---|---|---|---|
| x₁ | (3, 1) | 1.4 | (2.8, 1.4) | (0.2, −0.4) |
| x₂ | (1, 3) | 1 | (2, 1) | (−1, 2) |
| x₃ | (−2, −1) | −1 | (−2, −1) | (0, 0) |
| x₄ | (0, 4) | 0.8 | (1.6, 0.8) | (−1.6, 3.2) |
The point plot shows the geometry; the table preserves the values without relying on color, scale, or an interactive view.
The visual exposes a useful distinction. The matrix is a rule for every input, not a lookup table for these four points. Any new row in the same feature space can be multiplied by the same , and points already on remain unchanged.
Check the matrix with NumPy
NumPy’s outer
computes the outer product of two vectors, which constructs the numerator
. Its matmul
function performs matrix products; the @ operator is its array shorthand. We
can therefore write the row-stored transformation as X @ P and use
linalg.norm
with axis=1 to measure each row’s residual length.
allclose
checks numerical equality within chosen tolerances. The checks below do not
replace the algebra: they catch an implementation mistake while acknowledging
that floating-point arithmetic may leave a tiny remainder instead of literal
zero.
import numpy as np
b = np.array([2.0, 1.0])
X = np.array(
[
[3.0, 1.0],
[1.0, 3.0],
[-2.0, -1.0],
[0.0, 4.0],
]
)
P = np.outer(b, b) / np.dot(b, b)
Y = X @ P
residuals = X - Y
residual_lengths = np.linalg.norm(residuals, axis=1)
tolerance = 1e-12
symmetric = np.allclose(P.T, P, rtol=0.0, atol=tolerance)
idempotent = np.allclose(P @ P, P, rtol=0.0, atol=tolerance)
already_projected = np.allclose(Y @ P, Y, rtol=0.0, atol=tolerance)
print(P)
print(Y)
print(residual_lengths)
print(symmetric, idempotent, already_projected)
Verified output:
[[0.8 0.4]
[0.4 0.2]]
[[ 2.8 1.4]
[ 2. 1. ]
[-2. -1. ]
[ 1.6 0.8]]
[0.4472136 2.23606798 0. 3.57770876]
True True True
The three Boolean results answer different questions. symmetric checks the
matrix’s transpose identity, idempotent checks , and
already_projected checks that the entire transformed dataset stays fixed on a
second pass. The residual lengths show that a point can lie on the target line
with zero error, while another point can retain a substantial orthogonal
component.
What the matrix keeps—and what it cannot keep
For any vector , the output lies on . The coefficient is the part of that the chosen line can explain, while is perpendicular to . The projection is therefore a one-dimensional model of a -dimensional observation.
This is the basic shape of dimensionality reduction: choose a lower-dimensional feature space, preserve the nearest point in that space, and measure the reconstruction error that remains. In an embedding or feature pipeline, a direction could represent a learned pattern and could be retained as its strength. The projection matrix can apply that same representation rule to a batch, but the choice of direction still determines what information is preserved. A small residual means “close under this Euclidean line,” not “the sample’s meaning has been completely captured.”
Boundary cases and layout traps
A zero direction is not a line. If , then and the
formula divides by zero. A production function should reject that input rather
than produce nan values or silently call the zero vector a direction.
An offset line needs centering. The matrix above projects onto a line through the origin. For an affine line , first project and then add :
Applying directly to would use the wrong line. For a whole dataset, subtract from each row before the matrix multiplication and add it back afterward.
Do not let storage orientation choose the mathematics for you. For a row matrix use ; for a column matrix use . A transposed dataset can make a wrong multiplication look plausible while swapping “number of samples” and “number of features.” Check the shapes before interpreting the output.
The single-vector projection from Lesson 050 becomes a batch operation without changing its geometry. Lesson 052 will use the same nearest-point idea for a subspace generated by several columns, where the projection matrix can retain more than one learned direction.
Check your understanding
Question 1
For b = (1, 2), construct the projection matrix P = bbᵀ/(bᵀb) and state its shape.
Show the step-by-step solution
First compute the denominator:
Then form the outer product, placing in the left factor and in the top factor:
Therefore
Because has two coordinates, is a matrix.
Question 2
Using b = (2, 1) and x = (1, 3), calculate the projection coefficient and projected point.
Show the step-by-step solution
Compute the dot product and squared length:
The coefficient is . Multiply it by the direction:
The result lies on because it is a scalar multiple of .
Question 3
A dataset X has four rows and two feature columns. Should its row-wise projection onto P be X @ P or P @ X? Explain the dimensions.
Show the step-by-step solution
The shape of is , and a projection matrix for two-dimensional features has shape . The product
is defined and keeps one output row for each sample. Thus the row-wise
operation is X @ P. The product would try to multiply a
matrix by a matrix; the inner dimensions and do not match.
If samples were stored as columns in a matrix, then would act
on the left instead.
Question 4
Verify idempotence for P = [[0.8, 0.4], [0.4, 0.2]] by computing P². What does the result mean for a projected dataset?
Show the step-by-step solution
Multiply the matrix by itself:
Therefore . A second pass leaves every projected row unchanged; it does not continue shrinking the dataset.
Question 5
Why is the line-projection matrix symmetric, and how does that relate to the residual?
Show the step-by-step solution
The matrix is
The denominator is a scalar, and transposing the numerator reverses the factors:
So . Geometrically, the projection uses the usual Euclidean inner product, so the difference has zero dot product with . The symmetry is an algebraic signature of that orthogonal, right-angle projection; it does not by itself imply that every vector is preserved.
Question 6
An engineer says, "Because P has two rows and two columns, it keeps two independent directions." Correct the claim for a nonzero two-dimensional direction b.
Show the step-by-step solution
The shape of a matrix is not its number of independent directions. Both columns of are scalar multiples of , so its columns span only the one-dimensional line . Any component perpendicular to is removed. Thus a projection matrix can have rank one: it keeps one direction while using two coordinates to store each output point.
Question 7
What should a NumPy implementation do when b = [0.0, 0.0], and why is adding a tiny denominator not a faithful fix?
Show the step-by-step solution
The zero vector does not define a line, and its denominator is . The implementation should reject it explicitly, for example with a check that the squared norm is greater than zero, and explain the invalid input. Adding an arbitrary tiny number to the denominator would manufacture a very large or unstable matrix for an undefined geometric task. A numerical regularizer may be appropriate for a different, explicitly defined problem, but it does not turn the zero vector into a direction.
Question 8
For an affine line c + tb, why can’t the origin-line matrix P be applied directly to x? Give the corrected row-wise dataset operation.
Show the step-by-step solution
The matrix maps to a line through the origin. An affine line has offset , so the relevant vector is , not . For each row of a dataset, center first, project, then restore the offset:
where is an -entry column of ones. The subtraction and addition are row-wise. Applying without centering would project onto the parallel line through zero and answer a different question.