Contents
Deep Breakdown
What it tells me (Situation Awareness): An affine subspace is a linear subspace shifted by a point — it does not necessarily pass through the origin. The distance from a point to is computed by: (1) translating the problem to the origin (subtract from ), (2) projecting the translated point onto , and (3) measuring the residual. The formula reduces the affine problem to the linear projection problem. In DA/DS: distance from a data point to a hyperplane (a 2D affine subspace in , or D in ) is used in SVM, linear regression diagnostics, and decision boundary analysis.
Flowchart
Real-world use
Where it is used
Distance from a point to a hyperplane (SVM margin), computing the residual of a data point from a fitted regression line/plane (OLS residual in geometric terms), finding the nearest point on a fitted linear manifold to a query point, and clustering (distance from a centroid-defined affine cluster to a new data point).
Problem it solves
Linear subspaces pass through the origin. Real data is rarely centered at the origin. An affine subspace (like a fitted regression plane or an SVM hyperplane) is a linear subspace translated by a specific offset . Computing the distance requires removing this offset first before applying the standard linear projection formula.
How it solves the problem
The key idea: translate by to get . Now is measured relative to the origin of , and IS a linear subspace containing . The distance from to is the standard subspace distance: . Since translation preserves distances: .
Example in a business
In SVM: the decision hyperplane is , which is an affine subspace. The geometric margin (distance from a support vector to the hyperplane) is . This is the distance formula for an affine subspace (the hyperplane). SVM maximizes this margin, i.e., pushes support vectors as far from the decision boundary as possible.
The formula, piece by piece
- : the affine subspace; is any anchor point on ; is the associated linear subspace (direction space)
- : the point whose distance to we want
- : translate to be relative to the anchor point ; this converts an affine problem to a linear one
- : project the translated vector onto the linear subspace
- : the residual; the component of not captured by
- : the distance; always , equals 0 iff
The formula in words
"Shift the origin to a point on the affine subspace . Now looks like a linear subspace passing through the origin. Compute the standard linear projection distance. Shift back." Tiny example: = the line through in the direction (horizontal line at height 1). , . Query: . . (project onto x-axis). Residual: . . (Distance from to the horizontal line is .)
Critical Concepts
- SVM hyperplane distance: for hyperplane : . This is the affine subspace distance formula applied to a codimension-1 subspace.
- OLS residuals: the residual is the distance from observation to the fitted hyperplane measured in the response direction.
- Affine vs. linear: a linear subspace contains ; an affine subspace does not (unless ). The formulas differ by a translation.
- Closest point on L: is the closest point on to (covered in its own file).
- Invariance: for any shift .
Distance is translation-invariant.
Step-by-step calculation (tiny example)
Step 1: Define the affine subspace Line through in direction (the x-axis shifted to height 2 in y, z=0). Query: .
Step 2: Translate and project . . . Residual: .
Step 3: Compute distance . Interpretation: the point is units from the line.
Code examples
Beginner example (Python)
import numpy as np
# -- Distance from a point to an affine subspace ---
# L = x0 + span(b): a line through x0 in direction b
x0 = np.array([1.0, 2.0, 0.0]) # anchor point on L
b = np.array([1.0, 0.0, 0.0]) # direction of the line (unit vector)
x = np.array([5.0, 4.0, 3.0]) # query point
# Step 1: translate
v = x - x0
# Step 2: project onto U = span(b)
proj_v = np.dot(b, v) * b # pi_U(v)
# Step 3: residual and distance
residual = v - proj_v
dist = np.linalg.norm(residual)
print(f"v = x - x0 = {v}")
print(f"pi_U(v) = {proj_v}")
print(f"Residual = {residual}")
print(f"d(x, L) = {dist:.4f}")
# Closest point on L
closest_on_L = x0 + proj_v
print(f"\nClosest point on L: {closest_on_L}")
print(f"Distance verification: {np.linalg.norm(x - closest_on_L):.4f}")Beginner example (R)
# -- Distance from point to affine subspace ---
x0 <- c(1, 2, 0)
b <- c(1, 0, 0)
x <- c(5, 4, 3)
v <- x - x0
proj_v <- sum(b * v) * b
resid <- v - proj_v
dist <- sqrt(sum(resid^2))
cat(sprintf("d(x, L) = %.4f\n", dist))
closest <- x0 + proj_v
cat(sprintf("Closest point on L: (%g, %g, %g)\n", closest[1], closest[2], closest[3]))Professional example (Python)
import numpy as np
import pandas as pd
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
np.random.seed(42)
# -- Business scenario: SVM margin = distance to hyperplane (affine subspace) ---
# The SVM hyperplane w^T x + b = 0 is an affine subspace.
# Margin = distance from support vectors to this affine subspace.
# Generate two-class customer data (2 features for visualization clarity)
N = 200
X_class0 = np.random.randn(N // 2, 2) - 1.5
X_class1 = np.random.randn(N // 2, 2) + 1.5
X = np.vstack([X_class0, X_class1])
y = np.array([0] * (N // 2) + [1] * (N // 2))
scaler = StandardScaler()
X_s = scaler.fit_transform(X)
svm = SVC(kernel='linear', C=1.0)
svm.fit(X_s, y)
w = svm.coef_[0]
b_val = svm.intercept_[0]
# Distance from each training point to the hyperplane
# Affine subspace formula: d = |w^T x + b| / ||w||
distances = np.abs(X_s @ w + b_val) / np.linalg.norm(w)
margin = 2 / np.linalg.norm(w) # total margin width
results = pd.DataFrame({
"obs": range(N),
"class": y,
"distance": distances.round(4),
})
print(f"SVM hyperplane: w = {w.round(4)}, b = {b_val:.4f}")
print(f"||w|| = {np.linalg.norm(w):.4f}")
print(f"\nMargin width = 2/||w|| = {margin:.4f}")
print(f"\nSupport vectors (distance to hyperplane <= 1/||w|| + tolerance):")
sv_mask = distances < (1.0 / np.linalg.norm(w) + 0.05)
print(results[sv_mask].head(10).to_string(index=False))Source: MML1