UMAP (Uniform Manifold Approximation and Projection) is a newer non-linear dimensionality reduction technique that largely replaced t-SNE for many practical uses — significantly faster, and better at preserving some global structure alongside local neighborhoods.
UMAP vs t-SNE — The Practical Comparison
| t-SNE | UMAP | |
|---|---|---|
| Speed | Slow, especially on large datasets | Significantly faster |
| Preserves global structure? | Poorly — focuses almost entirely on local neighborhoods | Better — retains more meaningful large-scale relationships |
| Supports transforming new points? | No — must be rerun on the full dataset | Yes — can fit once, then transform new points later |
| Theoretical foundation | Probability distribution matching | Topological/manifold theory |
| Typical use today | Still common, especially in older codebases and papers | Increasingly the default choice for new work |
Python Implementation
import umap
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
data = load_digits()
X, y = data.data, data.target
reducer = umap.UMAP(n_neighbors=15, min_dist=0.1, n_components=2, random_state=42)
X_embedded = reducer.fit_transform(X)
plt.scatter(X_embedded[:,0], X_embedded[:,1], c=y, cmap="tab10", alpha=0.6)
plt.colorbar(label="Digit")
plt.show()
Note: UMAP requires installing the separate umap-learn package (pip install umap-learn) — it isn't part of scikit-learn itself.
The Two Key Hyperparameters
| Hyperparameter | Effect |
|---|---|
n_neighbors | How many neighbors define "local" structure — small values focus on very fine local detail; large values emphasize broader, more global structure |
min_dist | How tightly points are allowed to pack together in the embedding — smaller values produce tighter, more clumped clusters |
Transforming New Data — UMAP's Practical Advantage
# Fit once on training data
reducer = umap.UMAP(random_state=42)
X_train_embedded = reducer.fit_transform(X_train)
# Later, embed NEW points using the same learned mapping -- t-SNE cannot do this
X_new_embedded = reducer.transform(X_new)
This is a genuinely significant practical difference: because UMAP can transform new, previously-unseen points using a learned mapping, it can be used as an actual preprocessing step in a production pipeline — something t-SNE structurally cannot support.
Practical Use Cases
- Visualizing large, high-dimensional datasets (single-cell genomics, embeddings, image features) where t-SNE would be too slow
- As an actual dimensionality reduction preprocessing step before clustering or another downstream model, thanks to its
transform()support
Common Mistakes
- Assuming UMAP embeddings are more quantitatively meaningful than t-SNE's — the same caution about interpreting cluster sizes and inter-cluster distances still applies, just somewhat less severely.
- Not tuning
n_neighbors/min_distat all — like perplexity in t-SNE, these meaningfully shape what the resulting plot looks like.
Interview Relevance
Q: "Why might you choose UMAP over t-SNE for a production data pipeline?" UMAP is significantly faster on large datasets and, critically, supports transforming new unseen points with a previously fitted mapping — t-SNE has no equivalent and must be rerun from scratch on the full combined dataset every time, making it impractical as a reusable production preprocessing step.
Practice Question
Explain, in your own words, why UMAP's ability to call .transform() on new data (unlike t-SNE) matters specifically for a production ML pipeline, not just for one-off visualization.