UMAP-JS Dimension Reduction
UMAP-JS is a JavaScript implementation of the Uniform Manifold Approximation and Projection (UMAP) algorithm, a popular dimension reduction technique for both visualization and general non-linear dimension reduction. Currently stable at version 1.4.0, the library offers synchronous, asynchronous, and step-by-step fitting methods, allowing for flexible integration into various application contexts. Key differentiators from the original Python implementation include the use of a random embedding to seed the optimization step, rather than a spectral embedding, which yields comparable results for smaller datasets but avoids complex eigenvalue/eigenvector computations in JavaScript. The library also lacks specialized functionality for angular distances or sparse data representations. Releases appear to follow an irregular schedule, with the last publish about two years ago, but the project is maintained by PAIR-code, indicating ongoing support.
Common errors
-
TypeError: UMAP is not a constructor
cause Attempting to use `require('umap-js')` without destructuring for named exports, or using a default import syntax for a named export.fixEnsure you are using named imports with ESM: `import { UMAP } from 'umap-js';` or proper destructuring for CJS: `const { UMAP } = require('umap-js');`. -
Module not found: Can't resolve 'umap-js'
cause The `umap-js` package has not been installed or is not correctly listed in `package.json`.fixInstall the package using your package manager: `npm install umap-js` or `yarn add umap-js`.
Warnings
- gotcha UMAP-JS differs from the Python UMAP implementation in key ways. It uses a random embedding to seed the optimization step, rather than a spectral embedding, due to the complexity of efficient eigenvalue/eigenvector computations in JavaScript. This can lead to comparable results for smaller datasets but may behave differently or have performance implications for very large or complex datasets where spectral initialization is advantageous.
- gotcha The JavaScript port currently lacks specialized functionality for angular distances or sparse data representations, which are available in the Python UMAP library. Users requiring these features will need to implement them separately or preprocess their data accordingly.
- gotcha While the 1.2.2 release fixed issues with the default import of `LM` (likely an internal component), reliance on undocumented or internal exports in older versions could have led to module resolution or runtime errors. It's best to stick to documented public APIs like `UMAP`.
Install
-
npm install umap-js -
yarn add umap-js -
pnpm add umap-js
Imports
- UMAP
const UMAP = require('umap-js');import { UMAP } from 'umap-js'; - UMAPParameters
import { UMAP, UMAPParameters } from 'umap-js'; - * as umapjs
const umapjs = require('umap-js');import * as umapjs from 'umap-js';
Quickstart
import { UMAP } from 'umap-js';
// Generate some sample high-dimensional data
const numSamples = 1000;
const numDimensions = 10;
const data: number[][] = [];
for (let i = 0; i < numSamples; i++) {
const sample: number[] = [];
for (let j = 0; j < numDimensions; j++) {
sample.push(Math.random() * 100);
}
data.push(sample);
}
// Initialize UMAP with custom parameters
const umap = new UMAP({
nComponents: 2, // Reduce to 2 dimensions for visualization
nNeighbors: 10, // Number of neighbors to consider
minDist: 0.05, // Controls how tightly points are clustered together
spread: 1.0 // Controls the overall scale of the embedding
});
console.log('Starting UMAP fitting...');
// Perform synchronous fitting
const embedding = umap.fit(data);
console.log('UMAP fitting complete. First 5 embedded points:');
console.log(embedding.slice(0, 5));
// Example of transforming new data after fitting
const additionalData = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]];
const transformedPoints = umap.transform(additionalData);
console.log('Transformed additional points:');
console.log(transformedPoints);