PCA and SVD: what a projection keeps
You have 50-dimensional user embeddings and want to plot them, compress them, or denoise them. If you may keep only a few numbers per user, which numbers keep the most?
Start in two dimensions, where you can see everything, and keep just one number per point.
Keeping one number per point
Center the data (subtract the mean). Choose a unit direction \(u\). Each point \(x\) keeps one number, its coordinate along \(u\): \(z = x \cdot u\). Its reconstruction is \(z\,u\), and what's lost is the residual \(x - z\,u\), which is perpendicular to \(u\).
The residual is perpendicular to \(u\), so each point splits by Pythagoras:
The left side doesn't depend on \(u\). Every bit of variance you keep is a bit of error you don't make, so maximizing one minimizes the other, for any data.
Find the axis
Drag anywhere on the plot to rotate the line. Blue dots are the kept coordinates; dashed red segments are what's lost. Keep as much variance as possible: within 0.5% of the best.
The best axis is an eigenvector
With centered data \(X\) (one row per point), the variance along a unit direction \(u\) is
Maximizing \(u^\top\Sigma u\) over unit vectors (a Rayleigh quotient) gives the top eigenvector of the covariance \(\Sigma\), and the variance it keeps is the top eigenvalue \(\lambda_1\). The next best direction, perpendicular to the first, is the second eigenvector, and so on. Those directions are the principal components.
Total variance is the trace, \(\lambda_1 + \lambda_2 = 5\). PC1 keeps \(\lambda_1/(\lambda_1+\lambda_2) = 80\%\), and the residual error is exactly the discarded eigenvalue, 1. In \(d\) dimensions, keeping \(k\) components keeps \(\sum_{i\le k}\lambda_i / \sum_i \lambda_i\).
The same thing, computed directly from the data
Any matrix factors as \(X = U S V^\top\): orthonormal columns in \(U\) and \(V\), and non-negative singular values on the diagonal of \(S\). Substitute it into the covariance:
The columns of \(V\) are the principal directions, the eigenvalues are \(s_i^2/n\), and \(US\) holds each point's coordinates. In practice PCA is computed with the SVD of \(X\) rather than an eigendecomposition of \(X^\top X\). Forming \(X^\top X\) squares the condition number and throws away precision.
Keeping only the top \(k\) singular values gives the best rank-\(k\) approximation of \(X\) in squared error (Eckart–Young), and the error is exactly what you dropped:
\(2 \times 4096 \times 16 = 131{,}072\) against \(4096^2 = 16{,}777{,}216\): 0.78%. LoRA bets that the change a fine-tune needs has low rank. Matrix factorization for recommendations makes the same bet about the user–item matrix: a few latent factors explain most preferences. Low rank is a recurring structural prior.
Signal, then noise
Here are 20-dimensional data generated from 3 hidden factors plus noise in every dimension. The eigenvalues of its covariance, largest first:
Computed in your browser: 500 samples, sample covariance, Jacobi eigendecomposition.
Three eigenvalues stand out, then a flat floor of noise. Turn the noise up and the floor rises until the third factor sinks into it. Rules like "keep 95% of the variance" are heuristics. The better question is what the components are for: plotting (2–3), compression (bytes vs error), or denoising (stop where the signal meets the noise floor).
Apply it somewhere else
PCA maximizes variance, and variance depends on units: revenue's variance is millions of times larger. Standardize (PCA on the correlation matrix) unless the units are genuinely comparable. It's the same issue as k-means in lesson 6.
Unsupervised fitting still leaks the test distribution (its mean, its directions) into training. It's usually small, but it's real and can be large with few samples. Fit every preprocessing step on training data only, inside the cross-validation loop. Lesson 11 is about exactly this kind of mistake.
Most zeros mean "never shown", not "not wanted" (lesson 9). Use weighted matrix factorization (low confidence on unobserved entries, as in implicit-feedback ALS), or fit only the observed entries with regularization. Evaluate by ranking held-out interactions, not by reconstruction error.
PCA from the SVD
numpy's np.linalg.svd is allowed; sklearn isn't. ⌘/Ctrl+Enter runs.
Exercise 1: PCA
Exercise 2: best rank-k approximation
Answer out loud, then check
- It keeps the directions of largest variance, which gives the best linear reconstruction in squared error, and the Euclidean geometry within that subspace.
- It discards everything in the low-variance directions, even if that's where the label signal lives (unsupervised). It can't capture nonlinear structure.
- It's sensitive to scale and outliers. Variance isn't importance.
- PCA: linear, fast, deterministic, invertible, and reusable on new data. A good first baseline for compression and denoising.
- A linear autoencoder with squared loss learns the same subspace as PCA. Nonlinear autoencoders can capture curved structure but need training and tuning.
- t-SNE/UMAP: for 2-D visualization of local neighborhoods. Distances between far clusters and cluster sizes aren't meaningful, so don't use them as features without care.
- Forming \(X^\top X\) squares the condition number, so small singular values lose precision. SVD works on \(X\) directly.
- At scale: randomized SVD (random projections, then a small exact SVD), incremental or streaming PCA, or distributed Gram matrices when \(d\) is small.
- For only the top few components, power or Lanczos iterations cost roughly one matrix-vector product per iteration.
- The empirical finding: fine-tuning updates have low intrinsic rank. \(\Delta W = BA\) with small \(r\) trains about \(r(d+k)\) parameters instead of \(dk\), and can be merged into \(W\) for inference at no extra cost.
- Rank is task-dependent. Small ranks (4–16) often suffice for style or format adaptation; knowledge-heavy or very different domains may need more, or full fine-tuning.
- Pick it by sweeping rank against held-out quality and memory. Also decide which matrices to adapt: attention only, or the MLP too.
Sources: Eckart & Young, The approximation of one matrix by another of lower rank (1936); Halko, Martinsson & Tropp, Finding structure with randomness (2009); Hu et al., LoRA (2021); Hu, Koren & Volinsky, Collaborative Filtering for Implicit Feedback Datasets (ICDM 2008).