advanced ann-indexing 24 min read

Locality-Sensitive Hashing: Collision Probability and the ρ Exponent

Hash so that near points collide more often than far ones, and the collision probability — not a heuristic — becomes the index: an exact angular law, the AND/OR S-curve that sharpens it, and a sublinear exponent that holds for any data

Overview & motivation

Two ANN families so far have avoided scanning every vector by learning the data. IVF read the cloud’s density with k-means and cut it into Voronoi cells you probe; the navigable-graph topics built a structure from the insertion order and walked it. Both look at the points before they answer. Locality-sensitive hashing is the third family, and it makes the opposite bet: fix the partition before seeing a single vector, using randomness alone, and lean on a theorem to make it work.

The theorem is the whole design. A hash function is locality-sensitive if near points are more likely to land in the same bucket than far ones — collision probability is a decreasing function of distance. If you have such a family, retrieval is almost trivial: hash every database vector into a table, hash the query, and scan only the bucket it lands in. The near neighbors are probably there because near points probably collide. Everything hard is in turning “probably” into a guarantee with a tunable knob, and in paying honestly for the fact that the hash never looked at your data.

xy20/72 normals separate ≈ θ/π = 0.300.00.51.00.00.51.0angle θ / πcollision probability1 − θ/πmeasured
exact collision 1 − θ/π
0.70
angle θ
54°

One bit per random hyperplane. A plane separates x and y exactly when its normal lands in the wedge between them — angular measure θ/π — so the two collide with probability 1 − θ/π. The measured points sit on the line because the law is exact, not fitted.

The first panel is the exact angular law on the unit circle — random-hyperplane normals colored by whether they separate two vectors, with the collision probability falling linearly in the angle. The second is amplification: the S-curve that the AND/OR construction bends into a sharp threshold. The third is the payoff and the price — the sublinear exponent ρ on the left, and a cross-index head-to-head on the right where, told honestly, the data-aware indexes win.

Movement 1 — the family and its collision probability

We need a concrete locality-sensitive family, and the cleanest one is the one already half-built in the prerequisite. Random projection multiplies a vector by a random matrix; SimHash keeps only the sign of each coordinate of that projection. One random Gaussian vector h\mathbf{h} defines one bit, b(x)=1[x,h0]b(\mathbf{x}) = \mathbf{1}[\langle \mathbf{x}, \mathbf{h}\rangle \ge 0] — which side of the hyperplane through the origin with normal h\mathbf{h} the point falls on. A kk-bit signature is kk such bits. Because only the sign matters, the 1/k1/\sqrt{k} scaling that Johnson–Lindenstrauss applies is irrelevant here: the random hyperplanes are the projection rows, reused verbatim.

Definition 1 (A locality-sensitive hash family).

A family H\mathcal{H} of hash functions is (r1,r2,p1,p2)(r_1, r_2, p_1, p_2)-sensitive for a distance dd if, for hh drawn uniformly from H\mathcal{H},

d(x,y)r1    Pr[h(x)=h(y)]p1,d(x,y)r2    Pr[h(x)=h(y)]p2.d(\mathbf{x}, \mathbf{y}) \le r_1 \;\Rightarrow\; \Pr[h(\mathbf{x}) = h(\mathbf{y})] \ge p_1, \qquad d(\mathbf{x}, \mathbf{y}) \ge r_2 \;\Rightarrow\; \Pr[h(\mathbf{x}) = h(\mathbf{y})] \le p_2.

The family is useful when r1<r2r_1 < r_2 and p1>p2p_1 > p_2: near points (within r1r_1) collide at least as often as p1p_1, far points (beyond r2r_2) at most as often as p2p_2, and the gap between p1p_1 and p2p_2 is what amplification will widen into a usable filter.

For SimHash the relevant distance is the angle, and the collision probability is not an inequality to be estimated but an exact closed form.

Theorem 1 (The SimHash collision law).

Let x,y\mathbf{x}, \mathbf{y} have angle θ=(x,y)[0,π]\theta = \angle(\mathbf{x}, \mathbf{y}) \in [0, \pi], and let hh be a single random-hyperplane bit with normal h\mathbf{h} drawn from a spherically symmetric distribution. Then

Pr[h(x)=h(y)]=1θπ.\Pr[h(\mathbf{x}) = h(\mathbf{y})] = 1 - \frac{\theta}{\pi}.

The hyperplane separates x\mathbf{x} and y\mathbf{y} — assigns them opposite bits — exactly when its normal falls in the wedge spanned between them, whose angular measure, relative to the full circle of directions, is θ/π\theta/\pi. So they collide with the complementary probability 1θ/π1 - \theta/\pi. The law is linear in the angle, exact for any dimension, and depends on nothing but θ\theta.

The companion code drives the law directly: it builds pairs of unit vectors at a controlled angle θ=θππ\theta = \tfrac{\theta}{\pi}\cdot\pi and measures the fraction of thousands of random hyperplanes that fail to separate them. At θ/π=(0.1,0.3,0.5,0.7,0.9)\theta/\pi = (0.1,\,0.3,\,0.5,\,0.7,\,0.9) the measured collision rates are (0.9009,0.7025,0.5019,0.3029,0.1066)(0.9009,\,0.7025,\,0.5019,\,0.3029,\,0.1066) against the predicted 1θ/π=(0.9,0.7,0.5,0.3,0.1)1 - \theta/\pi = (0.9,\,0.7,\,0.5,\,0.3,\,0.1). The points land on the line because the law is exact, not fitted — this is the number the whole index is built on.

Movement 2 — amplification: AND/OR and the S-curve

A single bit collides with probability 1θ/π1 - \theta/\pi, which for any interesting angle is far too gradual to separate near from far: at θ=π/4\theta = \pi/4 the collision is 0.750.75, at θ=π/2\theta = \pi/2 still 0.50.5. A useful index needs the collision probability to be near one for true neighbors and near zero for everything else — a step, not a ramp. Amplification builds that step out of the gradual base law with two compositions.

Theorem 2 (The AND/OR S-curve).

Let p=1θ/πp = 1 - \theta/\pi be the base collision probability of a single bit. Concatenate kk independent bits into one table key (an AND: the keys match only if all kk bits agree, probability pkp^k), and maintain LL independent such tables (an OR: two points are candidates if they collide in any table). The probability that x\mathbf{x} and y\mathbf{y} become candidates is

g(p)=1(1pk)L.g(p) = 1 - \left(1 - p^{\,k}\right)^{L}.

As a function of pp this is an S-curve: kk slides the threshold rightward and steepens it (a stricter AND), LL raises the whole curve (a more forgiving OR). At k=L=1k = L = 1 it collapses to the identity g(p)=pg(p) = p — the bare hash, the byte-for-byte anchor the code checks.

The two knobs pull in opposite directions, and reading the verified S-curves shows it. At a base p=0.85p = 0.85 (an angle θ=0.15π\theta = 0.15\pi, the kind of small gap a true neighbor sits at), the (k=16,L=4)(k=16,\,L=4) family collides with probability only 0.26550.2655 — sixteen bits is a demanding AND — while (k=8,L=8)(k=8,\,L=8) collides at 0.92150.9215, because eight tables is a forgiving OR. Tuning (k,L)(k,L) places the steep part of the curve right between the near angle you want to keep and the far angle you want to drop. That is the engineering of an LSH index: choose kk to push the threshold past the far radius, then choose LL to pull the near radius back above it. The price of a larger LL is a larger candidate set — every table contributes its bucket to the union you must then rank exactly.

Movement 3 — the ρ exponent and sublinear query time

Amplification gives recall; the reason to use LSH at all is what it costs. The headline result of Indyk and Motwani is that the AND/OR knobs can be set so the query touches a sublinear number of points, and the exponent that controls it is a clean ratio of the two collision probabilities.

Theorem 3 (The ρ exponent and the query-time bound).

For an (r1,r2,p1,p2)(r_1, r_2, p_1, p_2)-sensitive family, set k=log1/p2nk = \log_{1/p_2} n and L=nρL = n^{\rho} with

ρ=ln(1/p1)ln(1/p2).\rho = \frac{\ln(1/p_1)}{\ln(1/p_2)}.

Then the (c,r)(c, r)-approximate near-neighbor problem (with c=r2/r1c = r_2/r_1) is solved with query time O(nρ)O(n^{\rho}) and space O(n1+ρ)O(n^{1+\rho}), and ρ<1\rho < 1 whenever p1>p2p_1 > p_2. The choice of kk makes a random far point’s expected collisions O(1)O(1) per table; the choice of LL makes a near point collide in some table with constant probability. Query time is sublinear, by a family that never examined the data.

The exponent rewards a wider gap. Fixing the near angle at θ1=0.15π\theta_1 = 0.15\pi (so p1=0.85p_1 = 0.85) and widening the far angle by an approximation factor cc, the verified ρ\rho falls from 0.78270.7827 at c=1.25c = 1.25 to 0.45560.4556 at c=2c = 2 to 0.17740.1774 at c=4c = 4: a search willing to accept a four-times-looser “near” is an easy problem, ρ\rho near a fifth, query time close to n1/5n^{1/5}. An easier approximation is a cheaper search, made quantitative.

What the exponent does not say is that LSH wins in practice, and the honest way to see this is to run it against the indexes that learn the data.

Proposition 1 (The head-to-head, on one normalized cloud).

Build LSH, IVF, flat-NSW, and HNSW on the same cloud and score them against the same ground truth, by distance computations per query. To compare angular SimHash against the Euclidean indexes fairly, L2-normalize the cloud: for unit vectors xy2=22cosθ\lVert \mathbf{x} - \mathbf{y}\rVert^2 = 2 - 2\cos\theta, so the Euclidean top-kk ranking is the angular ranking and the ground truth is shared by construction. Count LSH’s cost honestly — the LkL\cdot k hyperplane projections that hash the query (the analogue of IVF’s coarse centroid comparisons) plus one exact distance per candidate.

On this low-rank cloud the data-aware indexes dominate. To reach recall 0.90.9, HNSW spends 8282 distance computations per query, IVF spends 113113, and LSH spends 486486 — and past a few dozen tables LSH does more work than a brute-force scan of all 500500 vectors. This is a verdict on this cloud, not a universal ranking.

The proposition reads like a defeat for LSH, and on this data it is — but the reason is instructive. LSH’s candidate work is small: at recall 0.940.94 its buckets surface only about 3838 vectors to rank exactly, fewer than HNSW touches. What sinks it is the hashing overhead — to get recall on a tightly clustered, low-dimensional cloud the oblivious hash needs many tables, and LkL\cdot k projections at n=500n = 500 is nearly a full scan on its own. That overhead amortizes only as nn grows, and the dominance of the structure-aware indexes is exactly what you should expect when the data has structure to learn. LSH’s case is the opposite regime: very high dimension where graphs and inverted files degrade, adversarial or shifting data where no learned partition can be trusted, and the distribution-free worst-case guarantee that ρ<1\rho < 1 provides no matter what the data does.

Honest accounting

LSH completes the partition-family side of the ANN story: IVF’s learned Voronoi cells and LSH’s random buckets are the two ways to slice the space without scanning it, one data-dependent and one data-oblivious, and the graph indexes are the third way that abandons a partition for a walk. What remains on the ANN thread is the other axis of richness — when a document is not one vector but many, and a query must be scored against the best match among them, the index must change shape again. Multi-vector and late-interaction indexing, where the pruning of that many-to-many match at scale is its own problem, is where the thread continues.

Connections

  • IVF and LSH are the two partition-family answers to the same question — how to avoid scanning every vector — and they split on whether the partition reads the data. IVF's Voronoi cells are data-DEPENDENT, learned by k-means from the cloud's own density; LSH's buckets are data-INDEPENDENT, fixed by random hyperplanes that never see a point. The head-to-head in this topic runs both on the identical normalized cloud and the identical ground truth, by distance computations per query, and the oblivious hash pays for that obliviousness exactly as the data-dependent quantizer pays nothing for structure it can exploit ivf-voronoi-partitioning
  • HNSW is the graph member of the same head-to-head: on the shared normalized cloud it reaches recall ninety percent at the lowest cost of the three indexes, and LSH the highest. The contrast is the point — the graph and the inverted file both learn the data, the hash does not, so on a low-rank cloud the structure-aware methods win, and LSH's guarantee is the distribution-free worst case the others cannot promise hnsw

References & Further Reading

  • paper Approximate Nearest Neighbors: Towards Removing the Curse of Dimensionality — Indyk & Motwani (1998) The origin of locality-sensitive hashing and the rho exponent: an (r1, r2, p1, p2)-sensitive family gives an approximate-near-neighbor structure with query time n to the rho. The VLDB instantiation a year later (Gionis, Indyk & Motwani 1999) made it practical
  • paper Similarity Estimation Techniques from Rounding Algorithms — Charikar (2002) SimHash: one bit per random hyperplane, with the exact collision law one minus theta over pi for the angle between two vectors — the random-hyperplane family this topic builds on, derived from Goemans-Williamson rounding
  • paper Locality-Sensitive Hashing Scheme Based on p-Stable Distributions — Datar, Immorlica, Indyk & Mirrokni (2004) The Euclidean family (E2LSH): hash by a random projection quantized into width-w buckets, a different collision law for L2 distance — the named sibling this topic flags but does not implement
  • paper Near-Optimal Hashing Algorithms for Approximate Nearest Neighbor in High Dimensions — Andoni & Indyk (2008) The near-optimal exponent rho approaching one over c squared for Euclidean ANN — the result behind the rigorFlag's claim that SimHash's rho is not optimal, and that data-dependent and cross-polytope hashing do better for the same gap
  • documentation Faiss indexes — IndexLSH and binary indexes — Johnson, Douze & Jégou (2024) The production realization: IndexLSH bit-packs SimHash codes and searches by Hamming distance, the concrete form of the k-bit signatures and bucket lookups this topic measures
  • documentation datasketch — MinHash LSH — Zhu (2024) A widely used Python LSH for Jaccard similarity via MinHash, whose banding parameters are exactly the (k, L) AND/OR amplification of Movement 2 under a different base family