Project high-dimensional data down to two or three dimensions while preserving the structure each method is designed to keep. DruidJS gives you 20 dimensionality reduction methods, 7 nearest-neighbor indices and 7 clustering algorithms behind one API, with SIMD-accelerated WebAssembly kernels and a pure-JavaScript fallback everywhere.
If you use npm, install with npm install @saehrimnir/druidjs, and use it with
import * as druid from "@saehrimnir/druidjs";Otherwise download the files here, or use for instance unpkg this way:
<script src="https://unpkg.com/@saehrimnir/druidjs"></script>import * as druid from "@saehrimnir/druidjs";
const X = druid.Matrix.from(data); // n ⨯ d
const Y = new druid.UMAP(X, { d: 2, seed: 1212 }).transform();
Y.to2dArray(); // [[x, y], ...] — ready for d3Every method has the same shape: construct it with the data and a parameters object, then call transform().
For a one-off projection there is a static shorthand:
const Y = druid.PCA.transform(X, { d: 2 });The iterative methods can be stepped instead of run to completion, so you can draw the embedding while it converges:
for (const Y of new druid.TSNE(X, { d: 2, perplexity: 30 }).generator()) {
draw(Y.to2dArray());
}Dimensionality reduction — PCA · LDA · MDS · SMACOF · StressMDS · KKMDS · SQDMDS · t-SNE · UMAP · TriMap · PaCMAP · LocalMAP · Sammon · ISOMAP · LLE · LTSA · LSP · FastMap · TopoMap · MINFOTree
Nearest neighbors — BallTree, KDTree, HNSW, Annoy, LSH, NNDescent, NaiveKNN
const index = new druid.HNSW(points, { seed: 1212 });
index.search(points[0], 10); // the 10 nearest pointsClustering — KMeans, KMedoids, XMeans, OPTICS, CURE, MeanShift, HierarchicalClustering (single, complete, average and Ward linkage)
The hot paths run through WebAssembly kernels once the input is large enough to pay for crossing the boundary, and fall back to JavaScript otherwise — automatically, with no difference in the API. Measured between the published 0.8.0 and 0.9.0 packages: 2.35⨯ on dimensionality reduction, 2.24⨯ on nearest-neighbor search, 2.21⨯ on matrix operations.
The kernels can be turned off, which is the easiest way to compare them against the fallback:
druid.setWasmEnabled(false);
druid.isWasmAvailable();DruidJS uses internally the Matrix class for storing data. You can use it by creating a druid.Matrix object for instance with the function from, in example:
import * as druid from "@saehrimnir/druidjs";
let data = [[...], [...], ...];
let matrix = druid.Matrix.from(data);You can create a druid.Matrix object programmatically by:
let fn = (row, col) => (row == col ? 1 : 0);
let matrix = new druid.Matrix(rows, columns, fn);If rows == columns, then matrix would be a identity matrix.
A shortcut for a identity matrix is:
let matrix = new druid.Matrix(rows, columns, "I");
// or
let matrix = new druid.Matrix(rows, columns, "identity");There are more shortcuts for creating matrices:
let matrix = new druid.Matrix(3, 3, "zeros"); // matrix would be a 3x3 matrix with zeroes
let matrix = new druid.Matrix(3, 3, "center"); // matrix would be a 3x3 center matrix;
let number = 12;
let matrix = new druid.Matrix(3, 3, number); // matrix would be a 3x3 matrix filled with 'number'If you want to use a druid.Matrix object, for instance, with d3, you can use either the to2dArray method, the iterate_rows generator function, or just use the druid.Matrix object as an iterable (works with d3 since version 6).
let data = await d3.csv("data.csv");
let matrix = druid.Matrix.from(data);
d3.selectAll("datapoints").data(matrix.to2dArray()); //...
d3.selectAll("datapoints").data(matrix.iterate_rows()); //...
d3.selectAll("datapoints").data(matrix); //...Live, interactive examples in the documentation:
- Projections — the DR methods side by side on the Iris dataset
- Clustering and Cluster Diagnostics
- k-Nearest Neighbors — the indices compared
- Topology · Dendrograms · Geospatial · Image Search
All showcases → · Every method, one page each →
@inproceedings{cutura2020druid,
title={{DRUIDJS — A JavaScript Library for Dimensionality Reduction}},
author={Cutura, Rene and Kralj, Christoph and Sedlmair, Michael},
booktitle={2020 IEEE Visualization Conference (VIS)},
pages={111--115},
year={2020},
organization={IEEE}
}
- Documentation
- API Reference
- Demo
- Hello DruidJS on Observable
- Conference Talk IEEEVIS2020