Randomized SVD
Find a huge matrix's top directions with randomness: sketch it down to a thin sample, solve the small problem, lift the answer back up.
Why Does This Exist?
Truncated SVD on a million-by-million matrix costs and materialises dense factors that dwarf memory. Yet the goal is only the top directions, and randomness finds them cheaply. Randomized SVD multiplies by a thin random sketch (say ), orthogonalises the sample into , compresses to the small core , and decomposes instead. Cost drops to with structured sketches, and the error sits within a small factor of the optimal rank- error with overwhelming probability.
This powers PCA on data that never fits in RAM, fast LSA on term-document matrices, and near-real-time recommender updates. Exact foundations are in singular value decomposition; the compression payoff in PCA derivation.
The one idea you need first
A random projection preserves geometry: captures the range of 's top directions because random vectors have components along everything, amplified where stretches most. Oversampling (a few extra columns beyond ) plus one or two power iterations ( applied to the sketch) sharpens the capture on flat spectra.
Think of It Like This
Polling instead of a census
A census interviews everyone at enormous cost. A poll interviews a random sample and estimates the totals within a known margin of error. Nobody confuses the poll with the census, but decisions run on polls because the error bars suffice.
Randomized SVD polls a matrix. The sketch is the random sample of directions; the small core is the tabulated poll; the lifted factors are the projected totals. Oversampling is polling extra respondents in volatile districts; power iterations are callback rounds that sharpen fuzzy answers. The Johnson-Lindenstrauss intuition (random projections preserve lengths) is why the pollster's math works.
How It Actually Works
The four stages for target rank with oversampling :
- Sketch: draw Gaussian () and form . Optionally sharpen: with or .
- Orthogonalise: thin QR, . 's columns span the sampled range.
- Compress: , small (). The giant problem now fits in memory.
- Solve small: SVD of , lift . Truncate to .
Error bounds: within of optimal with probability , where oversampling and power iterations trade cost against both. Fixed seeds make it reproducible; without them, two runs return different-but-equally-valid bases.
Worked example
Approximate the rank-one . Its Gram matrix has trace 125 and determinant , so singular values and . Sketch with the deterministic :
One column captures the entire range (the matrix is rank one, so any in-range sketch suffices). Normalise to , compress , and . The sketch route recovers exactly, with zero dense factor ever formed.
Code
The point is the check: confirm the sketched singular value matches the exact one.
import numpy as np
A = np.array([[3.0, 4.0], [6.0, 8.0]])exact = np.linalg.svd(A, compute_uv=False)Y = A @ np.array([[1.0], [0.0]]) # one-column sketchQ, _ = np.linalg.qr(Y)B = Q.T @ Asketched = np.linalg.svd(B, compute_uv=False)print([round(float(v), 4) for v in exact]) # -> [11.1803, 0.0]print(round(float(sketched[0]), 4)) # -> 11.1803Watch Out For
Skimping on oversampling with a flat spectrum
When the top singular values decay slowly, a tight sketch () mixes the -th direction with the tail and the truncation wobbles between runs. Oversample by 5 to 10 and add one power iteration: both are cheap insurance, and the error bounds assume you bought it. Flat spectra are exactly where naive sketches embarrass.
Leaving the sketch unseeded in a pipeline
Unseeded randomness returns a different valid basis every run: components flip, signs change, downstream caches invalidate and tests flake. Seed the generator and log the seed with the artefacts. Randomised does not have to mean irreproducible.
The Quick Version
- Randomized SVD sketches , orthogonalises to , solves small , lifts back.
- The rank-one demo recovers through a single sketch column.
- Cost falls from to sketch-plus-small-solve; error stays near optimal with high probability.
- Oversample 5 to 10 and power-iterate once on flat spectra.
- Seed every sketch: different valid bases per run break caches and tests.