Affine Spaces
Almost everything so far insisted on passing through the origin — subspaces must contain . But the real world is full of lines and planes that don’t: a regression line with a nonzero intercept, an SVM decision boundary, a GPS position relative to a landmark. These are affine spaces — a subspace that’s been picked up and shifted. This is the bridge from pure linear algebra to the geometry of actual ML models.
A real-life example: a regression line
Fit a line to house prices: price = 50000 + 300 × areaprice = 50000 + 300 × area. The 300 × area300 × area part is a linear
(through-the-origin) relationship; the + 50000+ 50000 base price shifts the whole line up so it no
longer passes through . That constant offset is the signature of an affine object.
Every model with a bias/intercept term lives in an affine space.
Affine subspaces = support point + direction
Let be a vector space, a fixed point, and a subspace. The set
is an affine subspace (also linear manifold). Here:
- is the support point — where the shifted set is “pinned,”
- is the direction space — the subspace that gives its orientation.
If , then does not contain , so it is not a subspace. That single shift is the whole difference between linear and affine.
Support point plus direction, live
A line is a support point (violet) plus all scalar multiples of a direction vector (amber): . Watch the point slide along the affine line as varies. The grey line through the origin is the underlying direction space ; the solid line is the affine version, parallel to it but lifted off the origin:
The affine line and the direction space are parallel — same orientation, different position. The support point is just one way to pin it; any point on the line works equally well.
Lines, planes, and hyperplanes
The parametric equation of a -dimensional affine subspace uses a basis of its direction space:
- → a line (support point + one direction).
- → a plane (support point + two directions).
- in → a hyperplane — the flat that splits the space into two halves.
flowchart LR O["Subspace
(through origin)"] -->|"shift by x₀"| A["Affine subspace
x₀ + U"] A --> L["k=1: line"] A --> P["k=2: plane"] A --> H["k=n−1: hyperplane"] H -.-> ML["SVM decision boundary"] L -.-> RG["regression line"]
A hyperplane is exactly what a linear classifier draws: separates “class A” from “class B.” The bias is what makes it affine rather than forced through the origin.
The link back to linear systems
This ties a bow on the chapter. The solution set of an inhomogeneous system (with ) is either empty or an affine subspace of dimension :
That’s precisely the “particular solution + null space” decomposition from the solving-systems page — now with a name for its shape. Homogeneous → subspace; inhomogeneous → affine subspace.
Affine mappings
An affine mapping is a linear map followed by a translation:
for a linear map and a translation vector . Affine maps preserve dimension and parallelism but not the origin. That formula should look familiar — it’s a neural-network layer , which is affine, not linear, precisely because of the bias .
NumPy: an affine line and a hyperplane
import numpy as np
# Affine line y = x0 + λ u
x0 = np.array([-1.5, 1.4]) # support point
u = np.array([1.6, 0.7]) # direction
for lam in [-1.0, 0.0, 2.0]:
print(f"λ={lam:+.0f} -> point {np.round(x0 + lam * u, 2)}")
# Does the affine line pass through the origin? (Only if it's really a subspace)
# Solve x0 + λ u = 0 component-wise; consistent only if the λ's agree.
lam_x = -x0[0] / u[0]
lam_y = -x0[1] / u[1]
print("through origin?", np.isclose(lam_x, lam_y))
# A hyperplane in R^3: w·x + b = 0 (an affine set, the SVM boundary shape)
w, b = np.array([2.0, -1.0, 3.0]), -4.0
point = np.array([2.0, 0.0, 0.0])
print("on hyperplane?", np.isclose(w @ point + b, 0.0))import numpy as np
# Affine line y = x0 + λ u
x0 = np.array([-1.5, 1.4]) # support point
u = np.array([1.6, 0.7]) # direction
for lam in [-1.0, 0.0, 2.0]:
print(f"λ={lam:+.0f} -> point {np.round(x0 + lam * u, 2)}")
# Does the affine line pass through the origin? (Only if it's really a subspace)
# Solve x0 + λ u = 0 component-wise; consistent only if the λ's agree.
lam_x = -x0[0] / u[0]
lam_y = -x0[1] / u[1]
print("through origin?", np.isclose(lam_x, lam_y))
# A hyperplane in R^3: w·x + b = 0 (an affine set, the SVM boundary shape)
w, b = np.array([2.0, -1.0, 3.0]), -4.0
point = np.array([2.0, 0.0, 0.0])
print("on hyperplane?", np.isclose(w @ point + b, 0.0))λ=-1 -> point [-3.1 0.7]
λ=+0 -> point [-1.5 1.4]
λ=+2 -> point [1.7 2.8]
through origin? False
on hyperplane? Trueλ=-1 -> point [-3.1 0.7]
λ=+0 -> point [-1.5 1.4]
λ=+2 -> point [1.7 2.8]
through origin? False
on hyperplane? TrueWhy this matters for ML
- Every intercept/bias term () makes a model affine, not linear — regression lines, logit boundaries, neural layers.
- Hyperplanes are decision boundaries: SVMs (Chapter 12) are built entirely on finding a good separating hyperplane .
- The affine map is the literal definition of a dense layer — the reason “affine layer” and “linear layer” are used interchangeably (if loosely) in ML.
🧪 Try It Yourself
Exercise 1 – Points on an affine line
Exercise 2 – Subspace or affine?
Exercise 3 – Which side of the hyperplane?
Recap
- An affine subspace is a subspace shifted by a support point ; it’s a subspace only when it contains .
- Lines, planes, hyperplanes are affine subspaces of dimension , , and .
- Inhomogeneous system solutions are affine: particular solution + null space.
- An affine map is — a linear map plus a shift, exactly a neural-network layer .
🎓 Chapter 2 complete
You now have the full linear-algebra toolkit the rest of Mathematics for Machine Learning builds on: systems → matrices → elimination → vector spaces → independence → basis & rank → linear maps → affine spaces. Every neural layer, regression fit, and PCA projection is now something you can read in terms you understand.
Head back to the Linear Algebra Overview to see the whole map again — or revisit any page to replay its visualization.
If this helped you, consider buying me a coffee ☕
Buy me a coffeeWas this page helpful?
Let us know how we did
