UMAP (umap-learn): non-linear dimension reduction that drops into an sklearn pipeline
Uniform Manifold Approximation and Projection
At a glance
- What is it?
- UMAP is a Python dimension reduction library built on a fuzzy topological model of a Riemannian manifold. It is an easy swap for t-SNE in an sklearn-style workflow, but the default parameters and the numba dependency shape where it fits.
- Who is it for?
- Adopt umap-learn if you already have scikit-learn and numba in your environment and you want a non-linear embedding that behaves like an sklearn transformer, including the densMAP variant for density-aware plots. Do not adopt it if you need a linear projection you can interpret coefficient by coefficient, or if you cannot pin numba, since every install path routes through it.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What UMAP is solving, and for whom
High-dimensional data is hard to look at. UMAP takes a data matrix and returns a low-dimensional embedding, typically two dimensions for plotting, that preserves neighbourhood structure better than a linear projection would. The README frames the two use cases directly: visualisation, in the same slot as t-SNE, and general non-linear dimension reduction. The second is the more interesting one for engineers, because it means the output can be fed into a downstream classifier or clusterer rather than only drawn.
The intended audience is anyone already working in the Python scientific stack. The package inherits from sklearn classes, so umap.UMAP() is called the same way as any other sklearn transformer. That is the whole pitch: fit_transform, no new mental model for the API. If your team writes scikit-learn pipelines, this slots in without a rewrite.
The fuzzy topological model underneath
UMAP's mechanism is stated in the README as three assumptions: the data is uniformly distributed on a Riemannian manifold, the Riemannian metric is locally constant or can be approximated as such, and the manifold is locally connected. From those, the manifold is modelled with a fuzzy topological structure, and the embedding is found by searching for a low-dimensional projection whose fuzzy topological structure is as close as possible to the original.
The practical consequence is that UMAP is not optimising pairwise distances the way t-SNE does. It is optimising a graph-like structure. The README points to the 2018 ArXiv paper (1802.03426) for the mathematics and to a 2024 Nature Reviews Methods Primers article for a broader introduction aimed at scientists. The README's own summary of the mathematics is one sentence: you do not need to worry about it. That is a fair summary of the user experience, but it also means the behaviour of the embedding is not something you can reason about from first principles at the call site. You tune parameters and look at the result.
The nearest-neighbour search is delegated to pynndescent, a separate package by the same author, which is listed as a hard requirement. That is a real architectural dependency, not a detail: approximate nearest neighbours are what make the graph construction tractable, and the quality of that approximation feeds directly into the embedding.
Installing UMAP and the numba requirement
The README gives two primary install paths. Via conda-forge, which the project describes as covering Linux, OS X and Windows 64 bit:
conda install -c conda-forge umap-learn
Or via PyPI, presuming numba, sklearn, numpy and scipy are already present:
pip install umap-learn
There are extras. pip install umap-learn[plot] pulls the plotting dependencies (matplotlib, datashader, holoviews). pip install umap-learn[parametric_umap] installs a CPU-only TensorFlow for Parametric UMAP; the README recommends installing TensorFlow from its own instructions instead. On x86, pip install umap-learn[tbb] adds tbb for extra CPU optimisation.
The dependency list is the part worth reading twice. UMAP requires scikit-learn, numpy, scipy, numba, tqdm and pynndescent. The README explains why numba is there: the original version used Cython, and the project moved to Numba for code clarity and performance. That is a deliberate trade. It means installation is not a pure pip-and-go affair on platforms where numba lags, and the README anticipates this by offering a manual fallback: install numpy, scipy, scikit-learn and numba through conda first, then pip install umap-learn on top. For a fully manual install, the README shows downloading the master zip, then python -m pip install -e . after optionally installing scikit-learn and numba through conda.
n_neighbors and min_dist are the two knobs that matter
The README calls out the major parameters explicitly. n_neighbors controls how many neighbouring points are used in the local approximations of manifold structure. Larger values preserve more global structure at the cost of detailed local structure. The README says the parameter should often sit in the range 5 to 50, with 10 to 15 a sensible default.
min_dist controls how tightly the embedding is allowed to compress points together. Larger values spread embedded points more evenly; smaller values let the algorithm optimise the local structure more accurately, at the cost of a clumpier picture. The README text on min_dist is cut off in the supplied material, so the exact recommended range is not something I can quote.
This is the honest shape of tuning UMAP: two parameters, one governing the scale of structure you care about and one governing how the result is laid out. The README's framing makes the trade-off explicit rather than hiding it. If you change n_neighbors and the cluster structure you were about to present changes, that is the algorithm telling you the structure was not stable at that scale. That is a property of the method, not a bug in the library, and it is the reason an embedding should not be treated as a fixed result.
For the densMAP variant, the README states that it augments UMAP to preserve local density information in addition to topological structure, citing the Nature Biotechnology 2021 paper by Narayan, Berger and Cho. densMAP is provided by this same package, so it is a parameter choice rather than a separate install.
Where UMAP is the wrong tool
UMAP is a non-linear method. If you need a projection whose axes you can interpret, or whose components you can regress against, this is not it. PCA gives you that; UMAP does not, and no amount of parameter tuning changes the fact that the output dimensions are not individually meaningful.
The second limitation is environmental. Every install path goes through numba. If your deployment target is a platform where numba is unavailable or pinned to an incompatible version, UMAP is not a lightweight addition to your stack. The README's fallback advice (install the dependencies through conda, then pip install umap-learn) is a workaround for pip resolution problems, not a way around numba itself.
The third is the one the README states plainly and users routinely ignore: the embedding is a projection of a fuzzy topological structure, and the structure it recovers depends on n_neighbors. Small values show fine local detail; large values show global arrangement. Neither is the true picture. A UMAP plot is an argument about structure at a chosen scale, and presenting it without stating that scale is presenting half the result.
t-SNE and PCA as the alternatives
The README positions UMAP as a drop-in replacement for scikit-learn's t-SNE, and that is the most direct comparison. The API difference is the practical one: sklearn.manifold.TSNE is a transformer you can call the same way, so the swap is trivial in code. The algorithmic difference is that t-SNE optimises pairwise similarities between points, while UMAP optimises a fuzzy topological representation built from approximate nearest neighbours via pynndescent. UMAP's README also claims the method works for general non-linear dimension reduction, not only visualisation, which is the capability t-SNE is not typically used for.
PCA is the other alternative and the opposite choice. It is linear, it is fast, it has no numba dependency, and its components have a defined interpretation as directions of maximum variance. If your goal is a plot of cluster structure, PCA will often look worse and UMAP will often look better. If your goal is a feature representation you can reason about, PCA is the one that will not surprise you.
There is also Parametric UMAP, which the README lists as requiring TensorFlow greater than 2.0.0. That variant learns a parametric mapping rather than an embedding for a fixed dataset, which is what you would need to embed new points without refitting. The README does not go into detail on it beyond the install extra, so treat that as a separate evaluation rather than something you get for free.
Maintenance, releases and the licence
The repository is active. Releases in the supplied material run from release-0.5.10.post2 in December 2025 through release-0.5.11 in January 2026 to release-0.5.12 in April 2026, with the last push to master dated September 2026. The versioning pattern (including a .post2 release) suggests point fixes ship between minor versions, which is normal for a library with a wide dependency surface.
Upgrade cost is dominated by the dependencies rather than UMAP's own code. numba, scikit-learn and pynndescent all move, and a UMAP upgrade that pulls a new numba can break an environment that was otherwise stable. Pinning is the usual answer, and the conda-forge path is the one the README presents as the most reliable.
The licence is BSD-3-Clause, per the repository metadata and the LICENSE.txt badge link. That is a permissive licence. It permits use and redistribution with the conditions the licence text sets out, which typically include retaining the copyright notice and disclaimer. I am not a lawyer and this is not legal advice; read LICENSE.txt before shipping it in a product.
The README cites two papers, the 2018 ArXiv preprint and the 2024 Nature Reviews Methods Primers article, and the JOSS paper badge links to DOI 10.21105/joss.00861. If you need to justify the method in a written report, those are the citations the project itself points at.
Editorial conclusion
Adopt umap-learn if you already have scikit-learn and numba in your environment and you want a non-linear embedding that behaves like an sklearn transformer, including the densMAP variant for density-aware plots. Do not adopt it if you need a linear projection you can interpret coefficient by coefficient, or if you cannot pin numba, since every install path routes through it. Before committing, run your own data through two or three values of n_neighbors and check whether the cluster structure you see survives the change; the README is explicit that larger values trade local detail for global structure, and that trade-off is the parameter you will actually be tuning.
Community notes