Skip to content

deepbox/ml

Manifold & Projection

Manifold learning (TSNE, Isomap, MDS, SpectralEmbedding) and Gaussian random projection.

  • Embedding

Overview

  • fitTransform(X) returns the embedding of the fitted rows. nComponents defaults to 2.
  • TSNE runs the exact O(n^2) algorithm by default and refuses more than maxExactSamples (2000) rows. Set method: "approximate" for larger inputs. perplexity defaults to 30 and must be below the number of samples. Pass randomState for a repeatable embedding.
  • Isomap builds its neighbor graph from nNeighbors: 5 by default.
  • GaussianRandomProjection reduces dimensions with a random matrix. johnsonLindenstraussMinDim(nSamples, eps) gives the number of components that keeps pairwise distances within eps.

Types

1

TSNEOptions

type

Constructor options of TSNE.

  • readonly nComponents?: number
  • readonly perplexity?: number
  • readonly learningRate?: number | "auto"
  • readonly nIter?: number
  • readonly earlyExaggeration?: number
  • readonly earlyExaggerationIter?: number
  • readonly randomState?: number
  • readonly minGradNorm?: number
  • readonly method?: "exact" | "approximate"

    "exact" uses full pairwise interactions; "approximate" uses sampling for large datasets.

  • readonly maxExactSamples?: number

    Maximum samples allowed in exact mode before requiring approximate.

  • readonly approximateNeighbors?: number

    Number of nearest neighbors per point in approximate mode.

  • readonly negativeSamples?: number

    Number of negative samples per point in approximate mode.

Classes

5

Isomap

Isomap: nonlinear dimensionality reduction through geodesic distances.

1. Connects every sample to its nNeighbors nearest neighbors (the graph is made symmetric; separate components are joined through their closest points and a warning is issued). 2. Computes all-pairs shortest-path distances on that graph (Dijkstra). 3. Embeds the geodesic distances with classical MDS.

Unlike t-SNE, Isomap can project new samples with transform.

Example
import { Isomap } from 'deepbox/ml';import { tensor } from 'deepbox/ndarray'; const X = tensor([[0, 0], [1, 0.1], [2, 0.3], [3, 0.2], [4, 0.1], [5, 0]]);const iso = new Isomap({ nComponents: 1, nNeighbors: 2 });const embedding = iso.fitTransform(X); // shape [6, 1]const projected = iso.transform(tensor([[2.5, 0.25]]));
Members (9)
  • constructor(options?: { readonly nComponents?: number; readonly nNeighbors?: number; })
  • embedding: Tensor

    Embedding of the training data, shape (n_samples, nComponents).

  • distMatrix: Tensor

    Geodesic (shortest-path) distances between the training samples, shape (n_samples, n_samples).

  • nFeaturesIn: number

    Number of features seen during fit.

  • fit(X: Tensor): this

    Learn the embedding of the training data.

  • fitTransform(X: Tensor): Tensor

    Fit the model and return the embedding of the training data.

  • transform(X: Tensor): Tensor

    Project new samples into the learned embedding.

  • getParams(): Record<string, unknown>
  • setParams(params: Record<string, unknown>): this

    Update hyperparameters.

MDS

Classical (Torgerson) multidimensional scaling.

Computes the pairwise Euclidean distances (or takes a precomputed distance matrix), double-centres the squared distances and embeds the points with the leading eigenvectors. This is a closed-form, deterministic solution and not the iterative SMACOF stress minimisation that scikit-learn's MDS runs; for Euclidean input it equals PCA of the data.

Example
import { MDS } from 'deepbox/ml';import { tensor } from 'deepbox/ndarray'; const X = tensor([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 1]]);const embedding = new MDS({ nComponents: 2 }).fitTransform(X); // From a precomputed distance matrixconst D = tensor([[0, 3, 4], [3, 0, 5], [4, 5, 0]]);const layout = new MDS({ nComponents: 2, dissimilarity: 'precomputed' }).fitTransform(D);
Members (7)
  • constructor(options?: { readonly nComponents?: number; readonly dissimilarity?: "euclidean" | "precomputed"; })
  • embedding: Tensor

    Embedding of the fitted data, shape (n_samples, nComponents).

  • nFeaturesIn: number

    Number of columns of the matrix passed to fit.

  • fit(X: Tensor): this

    Compute the embedding.

  • fitTransform(X: Tensor): Tensor

    Fit the model and return the embedding.

  • getParams(): Record<string, unknown>
  • setParams(params: Record<string, unknown>): this

    Update hyperparameters.

SpectralEmbedding

Laplacian eigenmaps with a fully connected RBF affinity graph.

The affinity is W_ij = exp(-gamma * ||x_i - x_j||^2) with a zero diagonal. With the degree matrix D, the embedding consists of the eigenvectors of the symmetric normalized affinity D^-1/2 W D^-1/2 that belong to its largest eigenvalues (the smallest eigenvalues of the normalized Laplacian), without the trivial first one, mapped back with D^-1/2. This is the construction of scikit-learn's SpectralEmbedding(affinity="rbf").

Example
import { SpectralEmbedding } from 'deepbox/ml';import { tensor } from 'deepbox/ndarray'; const X = tensor([[0, 0], [0, 1], [1, 0], [5, 5], [5, 6], [6, 5]]);const se = new SpectralEmbedding({ nComponents: 2, gamma: 0.5 });const embedding = se.fitTransform(X);
Members (7)
  • constructor(options?: { readonly nComponents?: number; readonly gamma?: number; })
  • embedding: Tensor

    Embedding of the fitted data, shape (n_samples, nComponents).

  • nFeaturesIn: number

    Number of features seen during fit.

  • fit(X: Tensor): this

    Compute the embedding.

  • fitTransform(X: Tensor): Tensor

    Fit the model and return the embedding.

  • getParams(): Record<string, unknown>
  • setParams(params: Record<string, unknown>): this

    Update hyperparameters.

TSNE

t-Distributed Stochastic Neighbor Embedding (t-SNE).

A nonlinear dimensionality reduction technique for embedding high-dimensional data into a low-dimensional space (typically 2D or 3D) for visualization.

Algorithm: Exact t-SNE with an optional sparse approximation - Computes pairwise affinities in high-dimensional space using a Gaussian kernel whose bandwidth is calibrated per point to the requested perplexity - Computes pairwise affinities in low-dimensional space using a Student-t distribution - Minimizes the KL divergence between the two distributions by gradient descent with momentum and adaptive per-coordinate gains

Scalability Note: Exact t-SNE is O(n^2) in time and memory. With method: "approximate" the input affinities are restricted to the approximateNeighbors true nearest neighbors of every point and the repulsive forces are estimated from negativeSamples random points per sample and iteration, so every iteration costs O(n * (neighbors + negatives)). Finding the neighbors is still an O(n^2 d) brute-force pass.

t-SNE is non-parametric: it embeds exactly the samples it was fitted on and cannot project new data.

Example
import { TSNE } from 'deepbox/ml';import { tensor } from 'deepbox/ndarray'; const X = tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [2, 1, 0]]); const tsne = new TSNE({ nComponents: 2, perplexity: 2, randomState: 0 });const embedding = tsne.fitTransform(X);
Members (9)
  • constructor(options?: TSNEOptions)
  • embedding: Tensor

    Embedding of the fitted data, shape (n_samples, n_components).

  • embeddingResult: Tensordeprecated

    Get the embedding.

  • klDivergence: number | undefined

    KL divergence between the input and embedding affinities after the last fit.

  • fitTransform(X: Tensor): Tensor

    Fit the t-SNE model and return the embedding.

  • fit(X: Tensor): this

    Fit the model (same as fitTransform for t-SNE).

  • transform(X?: Tensor): Tensor

    Return the fitted embedding.

  • getParams(): Record<string, unknown>

    Get hyperparameters for this estimator.

  • setParams(params: Record<string, unknown>): this

    Update hyperparameters.

GaussianRandomProjection

Gaussian Random Projection.

Reduces dimensionality by projecting data onto a random Gaussian matrix. Each component of the projection matrix is drawn from N(0, 1/n_components).

Based on the Johnson-Lindenstrauss lemma: random projections approximately preserve pairwise distances. With nComponents: "auto" the target dimension is the Johnson-Lindenstrauss bound for the number of training samples and eps.

Without randomState the matrix is drawn from the global generator, so setSeed() makes it reproducible; with randomState it comes from a private stream.

Example
import { GaussianRandomProjection } from 'deepbox/ml'; const proj = new GaussianRandomProjection({ nComponents: 50, randomState: 0 });proj.fit(X_train);const X_reduced = proj.transform(X_test);
Members (8)
  • constructor(options?: { readonly nComponents?: number | "auto"; readonly eps?: number; readonly randomState?: number | null; readonly seed?: number | null; })
  • components: Tensor

    Projection matrix of shape (n_components, n_features).

  • fit(X: Tensor, _y?: Tensor): GaussianRandomProjection

    Draw the random projection matrix.

  • transform(X: Tensor): Tensor

    Project X onto the random components.

  • fitTransform(X: Tensor, y?: Tensor): Tensor

    Fit and project in one call.

  • getParams(): Record<string, unknown>
  • setParams(params: Record<string, unknown>): GaussianRandomProjection

    Set hyperparameters.

  • clone(): GaussianRandomProjection

    Create an unfitted copy with the same hyperparameters.

Functions

1

johnsonLindenstraussMinDim

function johnsonLindenstraussMinDim(nSamples: number, eps?: number): number;

Smallest number of random-projection components that keeps pairwise distances of nSamples points within a factor 1 +/- eps, according to the Johnson-Lindenstrauss lemma (the bound used by scikit-learn's johnson_lindenstrauss_min_dim).

Parameters

nSamples
number
Number of points (>= 1)
epsoptional
number
Allowed distortion, in the open interval (0, 1)

Returns

numberMinimum safe number of components

Throws

  • InvalidParameterErrorIf nSamples is not a positive integer or eps is outside (0, 1)
Example
johnsonLindenstraussMinDim(1e6, 0.5); // 663
ml-manifold.ts
import {  GaussianRandomProjection,  Isomap,  MDS,  TSNE,  johnsonLindenstraussMinDim,} from "deepbox/ml";import { tensor } from "deepbox/ndarray"; const X = tensor([  [1, 0, 0],  [0.9, 0.1, 0],  [0, 1, 0],  [0, 0.9, 0.1],  [0, 0, 1],  [0.1, 0, 0.9],]); console.log(johnsonLindenstraussMinDim(1000, 0.2));console.log(new GaussianRandomProjection({ nComponents: 2, randomState: 0 }).fitTransform(X).shape);console.log(new Isomap({ nComponents: 2, nNeighbors: 3 }).fitTransform(X).shape);console.log(new MDS({ nComponents: 2 }).fitTransform(X).shape);console.log(new TSNE({ nComponents: 2, perplexity: 2, randomState: 0 }).fitTransform(X).shape);