t-SNE and UMAP

Imagine a dataset of 70,000 handwritten digit images. Each is a point in 784-dimensional pixel space. No human can see 784 dimensions. Yet the digits secretly cluster into ten groups by shape. How do we compress that hidden structure into a scatterplot? It needs to be something a person can actually look at. This is the visualization problem that motivates neighbor-embedding methods. These are a family of techniques that build a low-dimensional map. They work by preserving local neighborhood relationships rather than raw distances or global variance directions. Classical tools like PCA preserve global variance but blur local structure. Distances in high dimensions are notoriously unreliable. Linear projections cannot unfold curved manifolds. t-SNE (t-distributed Stochastic Neighbor Embedding) and UMAP (Uniform Manifold Approximation and Projection) instead model pairwise similarity as a probability distribution over neighbors. They then find a low-dimensional embedding whose induced similarity distribution matches it as closely as possible. The result is the now-ubiquitous "blobs of clusters" plot. It appears in single-cell genomics, NLP embedding inspection, image feature analysis, and anomaly detection dashboards. Both methods build on the manifold hypothesis. High-dimensional data often lies near a lower-dimensional curved surface embedded in the ambient space. Where they differ is the mathematical machinery. t-SNE frames the problem as minimizing Kullback-Leibler divergence between probability distributions. UMAP frames it via algebraic topology and fuzzy simplicial sets. It minimizes a cross-entropy-like objective on graph structures. Despite the different derivations, their practical algorithms end up remarkably similar. Build a weighted neighbor graph in high dimensions. Build an analogous graph in low dimensions. Then push the low-dimensional points until the two graphs agree. This article gives a rigorous walkthrough of both algorithms. It covers how the similarity graphs are constructed. It explains how the optimization actually runs, with gradient derivations. It shows why the "crowding problem" forces the choice of heavy-tailed kernels. It also covers the complexity tradeoffs that let UMAP scale to millions of points. t-SNE historically could not scale that way. It closes with common misreadings of these plots. These misreadings are the single biggest source of misinformation in applied machine learning visualization.

Key takeaways
  • t-SNE and UMAP are neighbor-embedding algorithms: they preserve local similarity structure, not global distances, when projecting high-dimensional data to 2D/3D for visualization.
  • t-SNE converts high-dim distances to conditional probabilities (Gaussian kernel), matches them to a Student-t distributed low-dim distribution by minimizing KL divergence via gradient descent.
  • UMAP builds a weighted k-nearest-neighbor graph, interprets it as a fuzzy topological structure, and optimizes a low-dimensional layout via a cross-entropy-like objective with negative sampling.
  • Both fight the crowding problem using heavy-tailed low-dimensional kernels, letting moderately-distant points spread out rather than collapsing.
  • UMAP is asymptotically faster (O(nlog⁡n)O(n\log n) neighbor search + graph optimization) than the classical O(n2)O(n^2) t-SNE, though Barnes-Hut and FFT-accelerated t-SNE close much of the gap.
  • Cluster sizes, inter-cluster distances, and global geometry in these plots are not reliably meaningful — only local neighborhood preservation is guaranteed to be approximately respected.
The core insight

Both algorithms turn "who is near whom" in high dimensions into a probability or graph structure, then move points in low dimensions until the same structure re-emerges — sacrificing global distances to keep local neighborhoods intact.

The idea

A neighbor-embedding method takes points x1,…,xn∈RDx_1, \dots, x_n \in \mathbb{R}^D and produces points y1,…,yn∈Rdy_1, \dots, y_n \in \mathbb{R}^d with d≪Dd \ll D (typically d=2d=2), such that points that are close neighbors in the original space remain close in the embedding, and points that are far apart tend to stay far apart locally. This is fundamentally different from Manifold Learning and Nonlinear Dimensionality Reduction methods like Isomap or classical MDS, which try to preserve exact geodesic or Euclidean distances globally. Neighbor embedding instead preserves a probability distribution over neighbor relationships — a softer, more local, and more robust notion of structure that tolerates the fact that distances in high dimensions are often noisy or meaningless beyond the nearest few neighbors. The key technical device in both methods is a two-stage similarity comparison. First, define a similarity measure pijp_{ij} between every pair of points in the original high-dimensional space, typically derived from a kernel over distances (Gaussian for t-SNE, a smooth approximation to a k-NN graph for UMAP). Second, define an analogous similarity measure qijq_{ij} between the corresponding low-dimensional embedding points yi,yjy_i, y_j, using a different, heavier-tailed kernel. Third, optimize the low-dimensional coordinates yiy_i to make qijq_{ij} match pijp_{ij} as closely as possible, measured by a divergence (KL divergence for t-SNE, fuzzy-set cross-entropy for UMAP). This is an instance of the broader The Unsupervised Learning Problem: there is no label to fit, only internal consistency between two representations of the same data. The reason the low-dimensional kernel must have heavier tails than the high-dimensional one is called the crowding problem. In high dimensions, a point can have many equidistant moderate-distance neighbors (the volume of a shell at radius rr grows like rD−1r^{D-1}), but in 2D there simply is not enough "room" to place all of them at moderate distance while also giving close neighbors very small distances — everything gets squashed toward the center. Using a heavy-tailed distribution (Student-t with one degree of freedom, i.e., a Cauchy distribution, in t-SNE) means that moderate qijq_{ij} values correspond to much larger actual distances than under a Gaussian, giving points room to spread out in the 2D map without distorting the representation of true close neighbors.

How it works

t-SNE: probabilistic similarities and KL minimization

Step 1 — high-dimensional similarities. For each point xix_i, define a conditional probability that xjx_j would be picked as a neighbor of xix_i under a Gaussian centered at xix_i:

pj∣i=exp⁡(−∥xi−xj∥2/2σi2)∑k≠iexp⁡(−∥xi−xk∥2/2σi2),pi∣i=0.p_{j|i} = \frac{\exp(-\|x_i - x_j\|^2 / 2\sigma_i^2)}{\sum_{k \ne i} \exp(-\|x_i - x_k\|^2 / 2\sigma_i^2)}, \qquad p_{i|i}=0.

The bandwidth σi\sigma_i is chosen per point, via binary search, so that the perplexity of the distribution PiP_i equals a user-chosen constant (typically 5–50):

Perp(Pi)=2H(Pi),H(Pi)=−∑jpj∣ilog⁡2pj∣i.\mathrm{Perp}(P_i) = 2^{H(P_i)}, \qquad H(P_i) = -\sum_j p_{j|i}\log_2 p_{j|i}.

Perplexity is interpreted as "the effective number of neighbors" — larger perplexity means a wider Gaussian and more points considered locally similar. Symmetrize to get a joint distribution:

pij=pj∣i+pi∣j2n.p_{ij} = \frac{p_{j|i} + p_{i|j}}{2n}.

Symmetrizing this way (rather than just averaging the two conditionals without dividing by nn) guarantees ∑jpij>(1/2n)\sum_j p_{ij} > (1/2n) for every point, so no point contributes a vanishing gradient, which stabilizes optimization for outliers.

Step 2 — low-dimensional similarities. In the embedding space, define joint probabilities using a Student-t distribution with one degree of freedom (equivalent to a Cauchy distribution), which has much heavier tails than a Gaussian:

qij=(1+∥yi−yj∥2)−1∑k≠l(1+∥yk−yl∥2)−1,qii=0.q_{ij} = \frac{(1+\|y_i-y_j\|^2)^{-1}}{\sum_{k\ne l}(1+\|y_k-y_l\|^2)^{-1}}, \qquad q_{ii}=0.

Step 3 — objective and gradient. Minimize the KL divergence from QQ to PP:

C=KL(P∥Q)=∑i≠jpijlog⁡pijqij.C = \mathrm{KL}(P\|Q) = \sum_{i \ne j} p_{ij}\log\frac{p_{ij}}{q_{ij}}.

This is asymmetric: large pijp_{ij} with small qijq_{ij} is penalized heavily (true neighbors must stay together), while small pijp_{ij} with larger qijq_{ij} is penalized only mildly (non-neighbors can end up at any large distance without much cost). This asymmetry is why t-SNE plots show tight, well-separated clusters — the loss actively prioritizes local fidelity over global fidelity. The gradient with respect to a single embedded point works out to a clean physically-interpretable form (attraction and repulsion between all pairs):

∂C∂yi=4∑j(pij−qij)(yi−yj)(1+∥yi−yj∥2)−1.\frac{\partial C}{\partial y_i} = 4\sum_j (p_{ij}-q_{ij})(y_i-y_j)(1+\|y_i-y_j\|^2)^{-1}.

This is optimized with gradient descent plus momentum, and an "early exaggeration" trick: multiply all pijp_{ij} by a constant (e.g. 4–12) for the first few hundred iterations, which forces natural clusters to form tight, well-separated blobs early, from which the optimization refines fine structure afterward. ``` function T_SNE(X, d, perplexity, T, eta, alpha): n = number of rows in X

# --- Step 1: high-dimensional affinities --- for i in 1..n: sigma_i = binary_search_bandwidth(X, i, perplexity) for j in 1..n: p_cond[i][j] = gaussian_affinity(X[i], X[j], sigma_i) for i,j in 1..n: P[i][j] = (p_cond[i][j] + p_cond[j][i]) / (2*n) P[i][j] = max(P[i][j], 1e-12) # avoid log(0)

# --- Step 2: initialize embedding --- Y = random_normal(n, d, scale=1e-4) velocity = zeros(n, d)

# --- Step 3: gradient descent with early exaggeration --- for t in 1..T: P_used = (t <= 250) ? P 12.0 : P # early exaggeration Q, dist_inv = student_t_affinities(Y) # dist_inv[i][j] = (1+||y_i-y_j||^2)^-1 grad = zeros(n, d) for i in 1..n: for j in 1..n where j != i: coeff = 4 (P_used[i][j] - Q[i][j]) dist_inv[i][j] grad[i] += coeff (Y[i] - Y[j]) momentum = (t < 250) ? 0.5 : 0.8 velocity = momentum velocity - eta grad Y = Y + velocity return Y ```

UMAP: fuzzy simplicial sets and cross-entropy

UMAP replaces the Gaussian-kernel-and-KL-divergence machinery with a construction grounded in algebraic topology, but the resulting computational recipe is structurally parallel.

Step 1 — local fuzzy simplicial sets. For each point xix_i, find its kk nearest neighbors (a hyperparameter analogous to perplexity, called `n_neighbors`). Define, for each neighbor xjx_j of xix_i:

ρi=min⁡jd(xi,xj)(distance to nearest neighbor, >0),\rho_i = \min_{j} d(x_i, x_j) \quad (\text{distance to nearest neighbor, } >0),
wj∣i=exp⁡ ⁣(−max⁡(0,d(xi,xj)−ρi)σi),w_{j|i} = \exp\!\left(-\frac{\max(0, d(x_i,x_j)-\rho_i)}{\sigma_i}\right),

where σi\sigma_i is again calibrated (via binary search) so that ∑jwj∣i=log⁡2(k)\sum_j w_{j|i} = \log_2(k). Subtracting ρi\rho_i ensures every point is connected to its nearest neighbor with weight exactly 1, which is what makes UMAP treat the manifold as locally uniform — a core modeling assumption (data is assumed locally uniformly distributed after adjusting for local density via ρi\rho_i). Symmetrize using the fuzzy set union (probabilistic OR), not a simple average:

wij=wj∣i+wi∣j−wj∣i wi∣j.w_{ij} = w_{j|i} + w_{i|j} - w_{j|i}\, w_{i|j}.

This produces a weighted graph on the data — the fuzzy topological representation of the high-dimensional manifold.

Step 2 — low-dimensional layout. In the embedding, define similarity with a smooth, heavy-tailed curve fit to approximate:

ψ(yi,yj)=(1+a∥yi−yj∥2b)−1,\psi(y_i, y_j) = \left(1 + a\|y_i-y_j\|^{2b}\right)^{-1},

where a,b>0a, b>0 are found by curve-fitting to a reference bump function (defaults chosen so this closely tracks exp⁡(−∥yi−yj∥2)\exp(-\|y_i-y_j\|^2) near the origin, with a heavy tail beyond a target `min_dist`).

Step 3 — objective and optimization. UMAP minimizes a fuzzy-set cross entropy:

C=∑i≠j[wijlog⁡wijψij+(1−wij)log⁡1−wij1−ψij].C = \sum_{i \ne j} \left[ w_{ij}\log\frac{w_{ij}}{\psi_{ij}} + (1-w_{ij})\log\frac{1-w_{ij}}{1-\psi_{ij}} \right].

Unlike t-SNE's normalized joint distribution (which requires an O(n2)O(n^2) normalizing constant recomputed every iteration), each term here depends only on the pair (i,j)(i,j) — no global normalization is needed. This is what allows an efficient stochastic gradient descent with negative sampling: for each edge (i,j)(i,j) in the (sparse) k-NN graph, take an attractive gradient step, and pair it with a small number of repulsive steps against randomly sampled non-neighbors, rather than summing over all n2n^2 pairs every iteration. ``` function UMAP(X, d, n_neighbors, min_dist, T, n_negative): n = number of rows in X

# --- Step 1: fuzzy simplicial set (sparse k-NN graph) --- knn_idx, knn_dist = approximate_k_nearest_neighbors(X, n_neighbors) # e.g. via NN-descent for i in 1..n: rho_i = knn_dist[i][0] sigma_i = binary_search_bandwidth(knn_dist[i], n_neighbors, rho_i) for each (j, dist) in (knn_idx[i], knn_dist[i]): w_cond[i][j] = exp(-max(0, dist - rho_i) / sigma_i) W = sparse_matrix(n, n) for each stored edge (i,j): wij = w_cond[i][j] + w_cond[j][i] - w_cond[i][j] * w_cond[j][i] W[i][j] = W[j][i] = wij # fuzzy union, symmetric sparse graph a, b = fit_ab_curve(min_dist) # curve fit to target low-dim kernel shape

# --- Step 2: initialize embedding (e.g. spectral layout of graph W) --- Y = spectral_layout(W, d)

# --- Step 3: SGD with negative sampling over epochs --- edges = nonzero_entries(W) # list of (i, j, w_ij) for epoch in 1..T: shuffle(edges) for (i, j, w_ij) in edges: if random() > w_ij: continue # sample edges proportional to weight dist2 = squared_distance(Y[i], Y[j]) attract = (-2ab*dist2^(b-1)) / (1 + adist2^b) Y[i] += eta attract (Y[i]-Y[j]) Y[j] -= eta attract (Y[i]-Y[j]) for neg in 1..n_negative: k = random_point_index(n) if k == i: continue dist2_neg = squared_distance(Y[i], Y[k]) repel = 2b / ((0.001 + dist2_neg) (1 + adist2_neg^b)) Y[i] += eta repel (Y[i]-Y[k]) eta = eta * (1 - epoch/T) # linearly decay learning rate return Y ```

Figure
Two-stage pipeline shared by t-SNE and UMAP: high-dim graph → low-dim graph → matched by optimization
Neighbor-Embedding Pipeline High-dim data (R^D) p_ij (Gaussian) / w_ij (fuzzy k-NN) match Embedding (R^d, d=2) q_ij (Student-t) / psi_ij (UMAP curve) Objective KL(P || Q) or fuzzy cross-entropy gradient updates y_i

Complexity & correctness

t-SNE complexity. Computing all pairwise affinities pijp_{ij} and doing the binary search for σi\sigma_i per point costs O(n2D)O(n^2 D) for the naive dense version (distance computations dominate). Each gradient-descent iteration recomputes all qijq_{ij} and the gradient sum, which is O(n2)O(n^2) per iteration, giving O(Tn2)O(Tn^2) total for TT iterations — quadratic in nn, which becomes prohibitive beyond tens of thousands of points. The standard acceleration, Barnes-Hut t-SNE, exploits that only near neighbors need exact pijp_{ij} (others are truncated to zero after building an approximate k-NN via a vantage-point tree, O(nlog⁡n)O(n\log n)), and approximates the repulsive force sum using a quadtree/octree, treating clusters of distant points as a single aggregate — analogous to the Barnes-Hut algorithm for n-body simulation. This reduces the per-iteration cost to O(nlog⁡n)O(n\log n), giving overall O(Tnlog⁡n)O(Tn\log n). FFT-accelerated variants (interpolation-based t-SNE) push this toward near-linear time in practice.

UMAP complexity. Nearest-neighbor search uses approximate methods (NN-descent or randomized projection trees), costing roughly O(n1.14)O(n^{1.14}) to O(nlog⁡n)O(n\log n) empirically depending on implementation and data distribution. The fuzzy-set construction is O(nk)O(nk) for kk = `n_neighbors`. The optimization phase is genuinely sparse: each epoch touches only the O(nk)O(nk) edges in the k-NN graph (plus a constant number of negative samples per edge), giving O(nk)O(nk) per epoch and O(Tnk)O(Tnk) total — no dense n2n^2 term ever appears, because the cross-entropy objective is a sum over actual graph edges plus a sampled estimate of the repulsive term, not an exact normalized joint distribution. This asymptotic advantage — avoiding the global normalizing constant that t-SNE's QQ requires — is the single biggest reason UMAP scales to millions of points where classical t-SNE cannot.

Space complexity. Dense t-SNE needs O(n2)O(n^2) memory for the affinity matrices; Barnes-Hut t-SNE needs only O(n)O(n) for point storage plus O(n)O(n) for the sparse truncated PP matrix and O(n)O(n) for the tree. UMAP needs O(nk)O(nk) for its sparse graph — smaller when k≪nk \ll n, which is the typical regime.

Correctness reasoning. Neither algorithm has a "correctness proof" in the sense of an exact-answer algorithm; both are non-convex optimizations solving a well-posed but heuristic objective. The relevant correctness argument is does the objective actually encode "preserve local neighborhoods", and the derivation above shows it does by construction: pijp_{ij} (or wijw_{ij}) is large exactly when xi,xjx_i, x_j are close in the original space, and the gradient of KL divergence (or cross-entropy) drives qijq_{ij} (or ψij\psi_{ij}) toward matching values, with an asymmetric penalty structure that strongly punishes separating true neighbors while only weakly punishing spurious closeness among non-neighbors being avoided. A useful invariant to note: in t-SNE, ∑ijpij=1\sum_{ij} p_{ij} = 1 is fixed and does not change during optimization — only QQ changes — so the algorithm is literally projecting a fixed target distribution onto the family of distributions reachable by placing nn points in Rd\mathbb{R}^d under the Student-t kernel; convergence (to a local optimum) follows from standard gradient descent guarantees on a smooth, bounded-below objective, though global optimality is not guaranteed and initialization/random seed materially affects the resulting layout.

Tradeoffs to be honest about. Both methods discard global structure by design: inter-cluster distances and relative cluster sizes in the output are not reliable measures of true separation or density, since the objectives never directly penalize getting global geometry wrong — they only penalize local neighborhood mismatch (this is elaborated in the pitfalls section). t-SNE has no natural out-of-sample extension (a new point requires re-running or an approximate insertion heuristic); UMAP's optimization is more directly compatible with a `transform` step for new points because the fuzzy-set/embedding relationship can be reused, though this remains an approximation. UMAP's theoretical grounding in fuzzy simplicial sets provides an elegant motivation but does not, by itself, prove the final layout is a faithful topological invariant of the data — in practice both methods are best understood as sophisticated, well-motivated heuristics validated empirically rather than by hard guarantees.

Worked example

Consider six 3-dimensional points forming two obvious clusters, embedded with noise:

PointCoordinates (x1,x2,x3)(x_1,x_2,x_3)True cluster
A(0.0, 0.0, 0.0)1
B(0.2, 0.1, -0.1)1
C(-0.1, 0.2, 0.0)1
D(5.0, 5.0, 5.0)2
E(5.2, 4.9, 5.1)2
F(4.9, 5.1, 4.8)2

t-SNE trace (conceptual, perplexity ≈ 3). Computing pairwise Euclidean distances shows within-cluster distances ≈0.2\approx 0.2–0.30.3 and between-cluster distances ≈8.6\approx 8.6. Binary search finds a small σi\sigma_i for each point (since neighbors are close and dense), producing conditional distributions concentrated almost entirely on the two same-cluster neighbors, e.g., pB∣A≈0.49, pC∣A≈0.49, pD∣A≈pE∣A≈pF∣A≈0.007p_{B|A} \approx 0.49,\ p_{C|A}\approx 0.49,\ p_{D|A}\approx p_{E|A}\approx p_{F|A}\approx 0.007 each. Symmetrizing gives pAB,pAC≫pAD,pAE,pAFp_{AB}, p_{AC} \gg p_{AD}, p_{AE}, p_{AF}. In the embedding, random initialization places all six points near the origin; early exaggeration (multiplying pijp_{ij} by 12) causes the attractive term between A–B–C to dominate hugely over the tiny cross-cluster pp values, so A, B, C rapidly pull together while D, E, F do the same, and the repulsive Student-t term (which grows relatively larger for spatially close but dissimilar points) pushes the two nascent clusters apart. After exaggeration ends, the layout fine-tunes: within-cluster qijq_{ij} increases (points tighten) while between-cluster qijq_{ij} stays small, producing two visually separated blobs whose relative distance in the final plot is not guaranteed to reflect the true ratio 8.6 / 0.25 — it might show any large separation, since only the ordinal fact "far apart" is preserved, not the magnitude.

UMAP trace (n_neighbors = 2). For point A, nearest neighbors are B and C, at distances ≈0.22,0.22\approx 0.22, 0.22; ρA=0.22\rho_A = 0.22 (distance to nearest neighbor). Binary search sets σA\sigma_A so ∑wj∣A=log⁡2(2)=1\sum w_{j|A} = \log_2(2) = 1; since both neighbors are at distance ≈ρA\approx \rho_A, weights are near 1 and near 0 for others, giving wB∣A≈1,wC∣A≈w_{B|A}\approx 1, w_{C|A}\approx (something smaller depending on exact distances), and negligible weight to D, E, F. The fuzzy union symmetrization yields a sparse graph with strong edges A–B, A–C, B–C and D–E, D–F, E–F, and essentially zero-weight (absent) edges between clusters. During SGD, only these six intra-cluster edges (plus symmetric duplicates) generate attractive forces every epoch; every point also receives a handful of repulsive forces from randomly sampled negative examples, which for a cross-cluster pair like A and D will almost always push them apart (since they are not connected by any positive edge, the objective wants ψAD→0\psi_{AD}\to 0). Because UMAP's k-NN graph here is exactly two disconnected triangles, this small example only weakly illustrates UMAP's genuine advantage — its power emerges at scale, where the sparse graph structure lets optimization skip the vast majority of the (n2)\binom{n}{2} pairs entirely, unlike dense t-SNE.

Contrast. In dense t-SNE, all (62)=15\binom{6}{2}=15 pairs contribute to every gradient computation regardless of relevance; in UMAP, only the handful of true k-NN edges plus a small constant number of negative samples per point contribute per epoch. At n=6n=6 this difference is invisible in wall-clock time, but the pattern (dense O(n2)O(n^2) vs. sparse O(nk)O(nk)) is exactly what makes UMAP practical on datasets with nn in the millions, such as single-cell RNA-seq atlases.

Common pitfalls & traps

PitfallWhy it happensConsequence
Reading cluster distance as similarity strengthNeither objective penalizes global inter-cluster geometry, only local neighbor fidelityTwo clusters drawn far apart may be no more "different" than two drawn closer
Reading cluster size as point-count or densityCrowding-problem correction distorts spatial extent nonlinearlyA small tight true cluster can render as a large blob or vice versa
Using one fixed perplexity/`n_neighbors` for all dataLocal density varies across the dataset; one bandwidth setting under- or over-connects sparse/dense regionsSpurious extra clusters (too low) or merged clusters (too high)
Trusting a single runRandom initialization and stochastic optimization (SGD, negative sampling) yield different layouts each runApparent structure may be an artifact of seed, not signal — always check reproducibility across seeds
Applying either method directly to raw high-dimensional features without preprocessingDistances in very high dimensions can be dominated by noise or scale-mismatched featuresNeighbor graph reflects noise, not true manifold structure — dimensionality reduction (e.g. PCA) as a preprocessing step is often needed
Extrapolating to out-of-sample points naivelyt-SNE has no native transform; UMAP's transform is an approximation reusing fitted structureNew points may be placed in nonsensical locations relative to the fitted map

Pioneers & history

Origins · 1 minGeoffrey E. Hinton and how this was discovered
GE
Geoffrey E. Hinton
1947–present · Cognitive scientist and computer scientist, co-developer of Stochastic Neighbor Embedding and t-SNE, foundational figure in deep learning and backpropagation research

LV
Laurens van der Maaten
1979–present · Machine learning researcher who, with Hinton, introduced t-distributed Stochastic Neighbor Embedding (t-SNE) in 2008, and later co-developed Barnes-Hut t-SNE for scalable visualization

LM
Leland McInnes
active 2010s–present · Mathematician and software researcher, lead author of UMAP (2018), grounding dimensionality reduction in Riemannian geometry and algebraic topology (fuzzy simplicial sets)

History
2002
Hinton and Roweis introduce Stochastic Neighbor Embedding (SNE), the direct predecessor using Gaussian kernels in both spaces.
2008
van der Maaten and Hinton publish t-SNE, replacing the low-dimensional Gaussian with a Student-t kernel to solve the crowding problem.
2014
van der Maaten publishes Barnes-Hut t-SNE, reducing per-iteration cost from O(n2)O(n^2) to O(nlog⁡n)O(n\log n) via spatial trees.
2018
McInnes, Healy, and Melville release UMAP, grounding the method in fuzzy simplicial set theory and enabling sparse, scalable graph-based optimization.
2019
onward: GPU-accelerated implementations (e.g. within RAPIDS cuML) and openTSNE bring both algorithms to million-point datasets in single-cell biology and NLP embedding analysis.

Where this matters

Both algorithms are entrenched in exploratory data analysis across fields. In single-cell genomics, UMAP and t-SNE are the standard way to visualize cell-type clusters from gene-expression data with tens of thousands of genes reduced to a 2D atlas — tools like Scanpy and Seurat build UMAP in by default. In NLP and representation learning, practitioners visualize word or sentence embeddings (e.g., BERT hidden states) to sanity-check whether semantically similar tokens cluster together. In computer vision, feature embeddings from convolutional or transformer backbones are projected to inspect class separability before deciding whether a classifier is likely to succeed. Anomaly detection dashboards use these embeddings to visually flag points that sit apart from all learned clusters. Because both build on the same "neighbor graph + optimization" recipe, they connect naturally to ideas in Manifold Learning and Nonlinear Dimensionality Reduction such as Isomap and Laplacian Eigenmaps, and they remain a canonical unsupervised technique taught alongside clustering and PCA in the broader study of The Unsupervised Learning Problem.

Ask the tutor: How does changing the perplexity or n_neighbors hyperparameter change which "resolution" of manifold structure the embedding reveals?

Should I use t-SNE or UMAP for my dataset?

For most modern use cases, UMAP is preferred when scalability matters — it is asymptotically faster, generally preserves more global structure than raw t-SNE, and supports an approximate transform for new points. t-SNE (especially Barnes-Hut or FFT-accelerated variants) remains excellent for smaller datasets and is still widely used in fields like single-cell biology where it has decades of precedent and well-understood behavior. In practice, many analysts run both and compare, since the "right" choice often depends on downstream goals (pure visualization vs. needing a reusable embedding) rather than a universal ranking.

Why do t-SNE plots sometimes look completely different across multiple runs on the same data?

Both the initialization of yiy_i (commonly small random values) and the stochastic elements of optimization (SGD in UMAP, momentum-based gradient descent in t-SNE) are not deterministic across runs unless a random seed is fixed. Because the objective is non-convex, different initializations can converge to different local optima that preserve local neighborhoods equally well but arrange clusters in different relative positions, rotations, or even mirror images. This is expected and not a bug; the fix is to fix the random seed for reproducibility and to avoid over-interpreting any single layout's global arrangement as definitive.

Can t-SNE or UMAP be used as a preprocessing step before clustering or classification?

It is common but risky. Clustering algorithms like k-means applied directly to a t-SNE or UMAP embedding can produce clusters that look plausible visually but do not correspond to meaningful structure in the original space, because the embedding step has already distorted distances and densities by construction. If clustering is the actual goal, it is generally safer to cluster in the original (or a linearly-reduced, e.g. PCA) space and use the neighbor-embedding plot only to visualize those clusters afterward, rather than to define them.

What is the "crowding problem" precisely, and why does it appear in high-to-low dimensional projection?

In high dimensions, the volume of a thin spherical shell at radius rr scales as rD−1r^{D-1}, so a point typically has many neighbors at moderate distances, not just a few nearby and everything else far. When compressing to two dimensions, there is not enough area to place all of those moderate-distance neighbors at their proportionally correct distances while also keeping true close neighbors very close — geometry runs out of room, and points get crushed toward the center. Using a heavy-tailed kernel in the embedding (t-SNE's Student-t, UMAP's fitted curve) means a given output distance corresponds to a much smaller similarity value than under a Gaussian, giving moderate-distance points effectively more "room" to spread apart without disturbing true near neighbors.

How does UMAP's use of algebraic topology (fuzzy simplicial sets) actually change the computed output compared to t-SNE?

Practically, the biggest concrete differences are: UMAP's per-point bandwidth calibration targets log⁡2(k)\log_2(k) rather than a perplexity-derived entropy, it subtracts the nearest-neighbor distance ρi\rho_i before applying the exponential kernel (assuming local uniformity on the manifold), and it symmetrizes with a fuzzy-set union rather than an averaged conditional probability. These choices, motivated by treating each point's neighborhood as a fuzzy simplicial set that gets glued into a global fuzzy topological representation, tend to preserve more of the manifold's global topology and produce embeddings that are somewhat more stable and better at preserving relative continuity between clusters than vanilla t-SNE, though this is an empirical tendency rather than a formally proven topology-preservation guarantee.

Do these methods work well on non-clustered, continuously varying data (e.g., a single smooth manifold like a Swiss roll)?

Yes, though results can be subtler than the classic tight-cluster pictures. On genuinely continuous manifolds, both methods can preserve local continuity reasonably well (UMAP is generally considered somewhat better at this due to its topological construction and initialization via spectral layout), but they can also introduce artificial gaps or tears, since the optimization is still driven by discrete nearest-neighbor graphs and heavy-tailed low-dimensional kernels that favor separation. It is good practice to test hyperparameters (perplexity, n_neighbors, min_dist) across a range and check whether apparent discontinuities persist, rather than assuming the manifold is truly disconnected.

What role does the initial layout (e.g., PCA or spectral embedding) play before running t-SNE or UMAP?

A good initialization substantially affects both the speed of convergence and the stability/reproducibility of the final layout, since both objectives are non-convex. UMAP by default initializes via a spectral embedding of the fuzzy graph (essentially a Laplacian eigenmap), which already places points in a topologically sensible rough arrangement before fine-tuning. t-SNE traditionally used small random initialization, but PCA-based initialization is now a common and recommended alternative, since it tends to preserve more of the global variance structure and produces more consistent, more globally interpretable layouts across repeated runs.

Before this