Skip to main content

wlearn-dimred

Dimensionality reduction for Python: PCA, t-SNE, UMAP and TriMap, running on the standalone C backend by default. Optional CPU/GPU acceleration uses Polygrad. Part of wlearn.

Install

The C backend shares fixed math routines with the JavaScript/Wasm backend for reproducible seeded fits within a package version. Polygrad uses different algorithms/arithmetic and need not produce the same coordinates.

pip install wlearn-dimred
# or, together with wlearn:
pip install 'wlearn[dimred]'

Requires Python 3.10 or newer. The package is distributed as source and compiles a small C extension during installation, so a C compiler is needed. Polygrad is optional: pip install 'wlearn-dimred[polygrad]' enables its backend.

Quick start

import numpy as np
from wlearn_dimred import PCA, UMAP

# Three clusters in 4 dimensions
rng = np.random.default_rng(0)
centers = np.array([[0, 0, 0, 0], [5, 0, 0, 0], [0, 5, 0, 0]], dtype=np.float32)
X = (centers[np.arange(150) % 3] + rng.normal(scale=0.5, size=(150, 4))).astype(np.float32)

pca = PCA(n_components=2)
umap = UMAP(n_neighbors=15)
try:
    scores = pca.fit_transform(X)   # shape (150, 2)
    layout = umap.fit_transform(X)  # shape (150, 2)

    pca.save("pca.wlrn")
    restored = PCA.load("pca.wlrn")
    print(scores.shape, layout.shape, restored.transform(X[:3]).shape)
    restored.dispose()
finally:
    pca.dispose()
    umap.dispose()

With wlearn 0.3.1 or newer, the same classes are also available as from wlearn.dimred import PCA, UMAP.

The C backend does not compile kernels. The optional Polygrad backend compiles on first use and can reuse cached kernels on subsequent fits.

Methods

Class Result Parameters (defaults)
PCA Linear projection; can transform new points n_components (2); Polygrad solver: max_iter (256), tolerance (1e-5)
TSNE 2-D layout perplexity (20), max_iter (500), learning_rate (50), method ('barnes_hut' on C, 'exact' on Polygrad; both also support 'sparse')
UMAP 2-D layout n_neighbors (15, max 64), max_iter (300), learning_rate (1 on C, 0.1 on Polygrad), seed (42)
TriMap 2-D layout n_inliers (12), n_outliers (4), n_random (3), max_iter (400), learning_rate (0.1), seed (42)

Every class accepts backend='c' | 'polygrad' (default 'c') and polygrad. Supplying polygrad selects it unless backend is explicit. C PCA has no 16-component limit; max_iter/tolerance configure only Polygrad PCA. C t-SNE defaults to 'barnes_hut'; Polygrad to 'exact'. C UMAP's default learning rate is 1, versus 0.1 for Polygrad. Unknown parameters raise a ValidationError. PCA accepts up to min(features, samples - 1) components on C and at most 16 on Polygrad. Sparse Polygrad t-SNE accepts block_size (256); Polygrad t-SNE and UMAP accept segment_sum (False). C sparse/Barnes-Hut t-SNE uses at most 64 neighbours and requires perplexity <= min(64, samples - 1).

API

All classes:

  • fit(X, y=None, on_step=None) and fit_transform(X, y=None, on_step=None). X is a 2-D array; y is ignored.
  • embedding_ is the fitted layout; is_fitted reports state.
  • get_params() and set_params(**params) read and change parameters. Changing parameters clears the fitted state.
  • save(path=None) returns the model as bytes and optionally writes them. load(source, polygrad=None) accepts bytes or a path.
  • dispose() releases native resources. Call it when you are done.
  • capabilities describes what the estimator supports.

PCA also has transform(X), components_ (components x features, as in scikit-learn), mean_ and explained_variance_.

For t-SNE, UMAP and TriMap, on_step(iteration, embedding) is called every 10 iterations with the current coordinates. Return False to cancel; the fit then raises InterruptedError on C. On Polygrad, it raises RuntimeError for exact t-SNE and InterruptedError for the other methods. C also reports the final iteration when it is not a multiple of 10.

Choosing a runtime

polygrad is either a dict of polygrad.create() options or an existing runtime:

import numpy as np
import polygrad
from wlearn_dimred import UMAP

# Two groups of points in 3 dimensions
X = np.random.default_rng(1).normal(size=(60, 3)).astype(np.float32)
X[30:] += 4

with polygrad.create(device='CPU') as pg:
    umap = UMAP(polygrad=pg, max_iter=100)
    try:
        print(umap.fit_transform(X).shape)
    finally:
        umap.dispose()
  • Options, for example polygrad={'device': 'CUDA'}, create a runtime for each fit or transform and dispose it afterwards.
  • An existing runtime is borrowed and never disposed by dimred. It keeps compiled kernels between fits. Do not use one runtime from two estimators at the same time.

Faster UMAP and sparse t-SNE

For larger inputs, enable Polygrad's dedicated reduction kernel with both segment_sum=True and polygrad={'kernels': True}:

from wlearn_dimred import UMAP

umap = UMAP(segment_sum=True, polygrad={'kernels': True})
print(umap.get_params()['segment_sum'])
umap.dispose()

segment_sum without kernels gives correct results but is slow. On 10,000 points, this made UMAP optimization 5 to 8 times faster on WebGPU and WebAssembly. Results can differ slightly because the summation order changes.

Precomputed neighbours

wlearn_dimred.graphs.tsne_sparse runs sparse t-SNE on neighbours from your own search, for example an approximate nearest-neighbour index. indices and distances have shape (N, k), exclude each point itself, and hold Euclidean (not squared) distances:

import numpy as np
import polygrad
from wlearn_dimred.graphs import tsne_sparse

X = np.random.default_rng(2).normal(size=(80, 3)).astype(np.float32)
X[40:] += 4
d = np.linalg.norm(X[:, None] - X[None], axis=-1)
np.fill_diagonal(d, np.inf)
indices = np.argsort(d, axis=1)[:, :30].astype(np.int32)
distances = np.take_along_axis(d, indices, axis=1).astype(np.float32)

with polygrad.create(device='CPU', logical='always') as pg:
    Y = tsne_sparse(pg, X, perplexity=10, neighbours=(indices, distances))
print(Y.shape)

Saving and loading

save() writes the wlearn .wlrn format. The npm package @wlearn/dimred reads the same files. Importing wlearn_dimred registers its loaders, so wlearn.load() also works.

t-SNE, UMAP and TriMap save the fitted layout and parameters. They cannot place new points.

Notes and limitations

  • t-SNE, UMAP and TriMap return 2-D layouts and have no transform or predict. They are not used as AutoML candidates. PCA can be a step in a wlearn Pipeline.
  • C PCA uses double-precision centered covariance/Gram and a direct eigensolver. Inputs and portable arrays remain float32; it is not a direct SVD. The following iterative restrictions concern only Polygrad PCA.
  • Polygrad PCA uses float32 covariance/Jacobi or subspace iteration, not an exact SVD. Up to 64 features it uses the full covariance. Larger inputs start with subspace iteration; up to 1,024 features a full solve is available as a fallback within the same max_iter budget. The budget counts subspace steps or full Jacobi sweeps. PCA checks the residual against the original data and raises if the requested tolerance is not reached; very small tolerances may be unattainable in float32. Component signs and repeated-eigenvalue bases are not unique. Nonlinear methods can use an approximate PCA initializer; their max_iter controls layout optimization, not PCA convergence.
  • Exact t-SNE (method='exact') supports 4 to 2,000 points. method='sparse' has no fixed 2,000-point limit, but still compares all pairs, so time grows quadratically and available memory limits the input size.
  • C 'barnes_hut' t-SNE approximates repulsion using a quadtree. 'sparse' retains exact repulsion on both backends. Polygrad has no Barnes-Hut path.
  • C neighbor search is exact for small/low-dimensional inputs; above 2,000 points and 16 features it uses approximate neighbor refinement. Polygrad compares all pairs. n_neighbors is at most 64.
  • C UMAP uses sequential scheduled updates. Polygrad updates all edges at once. TriMap uses the selected backend's neighbour search instead of Annoy. Layouts are reproducible for a fixed seed but differ from umap-learn and trimap. All three nonlinear methods start from PCA coordinates.
  • Tested on Linux. Windows is not supported.
  • The X86 kernel-argument limit affecting wider PCA and TriMap fits is fixed in Polygrad 0.7.1, the minimum supported optional runtime.

Compatibility

Requires wlearn 0.3 or newer. Only the optional accelerated backend requires polygrad >=0.7.1,<0.8.0. The default backend and fitted artifacts do not require it.

License

Apache-2.0. See NOTICE for third-party attributions.

Metadata

Release files for wlearn-dimred 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wlearn-dimred 0.2.0
File Size Uploaded Provenance Actions
wlearn_dimred-0.2.0.tar.gz 173.6 kB Without provenance Details for wlearn_dimred-0.2.0.tar.gz

Release files / wlearn_dimred-0.2.0.tar.gz

Download URL wlearn_dimred-0.2.0.tar.gz
Size 173.6 kB
Tags Source
SHA-256 checksum
How to use checksums
a4c3a4368358972485623935f91e9978481784d61e73a385efba8590e1a1dd9d
BLAKE2b-256 checksum
How to use checksums
fecdc6eb323f36b56fae1ad35bb41eea5d6f39c81f1598179c12a38e5cded43f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.16

Security for wlearn-dimred 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page