import type { BaseClustering, DataMatrix, HDBSCANParams } from './types'; import type { ClusterRepresentations } from './representations'; /** * HDBSCAN — hierarchical density-based clustering. * * Discovers clusters of varying density without a preset cluster count and * flags samples in sparse regions as noise (`-1`). The estimator builds the * mutual-reachability graph from per-point core distances, takes its minimum * spanning tree, condenses the resulting single-linkage hierarchy, and selects * stable clusters by Excess of Mass. It is fit-only — like * AgglomerativeClustering there is no principled `predict` for unseen points. * * The front-half (distance matrix, core distances, mutual reachability) runs * on the TensorFlow.js backend in a single fused `tf.tidy` inside `fit`. Core * distances use a `tf.topk` order-statistic; mutual reachability is a broadcast * `tf.maximum`. The two halves meet at a single `.data()` readback: the * mutual-reachability tensor is flushed once to a flat `Float32Array`, which * `graph/minimum_spanning_tree` consumes directly. Everything downstream of * that readback (MST, condensed tree, EoM) is plain JS. * * Parity: labels and probabilities match scikit-learn closely but not * bit-for-bit. Mutual-reachability weight ties are ordered differently across * implementations (numpy's unstable `argsort` over the MST edges), which shifts * a few boundary points. The condensed-tree + Excess-of-Mass core is itself * exact — it reproduces scikit-learn's labels and probabilities verbatim when * fed scikit-learn's own single-linkage hierarchy (see * `condensation_tree.test.ts`). */ export declare class HDBSCAN implements BaseClustering, ClusterRepresentations { readonly params: HDBSCANParams; /** Cluster labels: integers >= 0, `-1` for noise. Null until `fit`. */ labels_: number[] | null; /** Per-sample membership strength in `[0, 1]`. Null until `fit`. */ probabilities_: number[] | null; /** * Most-persistent exemplar sample index per 0-based cluster label. * * Library-defined: scikit-learn's HDBSCAN has no equivalent attribute. The * exemplar of a cluster is the point that persists to the highest λ in the * condensed tree; ties resolve towards the lowest sample index. Populated * only when `store_exemplars` is set; null otherwise. */ exemplar_indices_: Map | null; private static readonly DEFAULT_MIN_CLUSTER_SIZE; constructor(params?: Partial); private static validate_params; /** Resets fitted state. HDBSCAN keeps no tensors as instance state. */ dispose(): void; /** * The returned tensor is always freshly owned: `fit` disposes it without * touching a caller-supplied tensor (the precomputed-tensor case is cloned). */ private distance_matrix; /** * The core distance of point i is the distance to its * (min_samples − 1)-th nearest neighbour, counting self as neighbour 0. * * Negation trick: `tf.topk` returns the largest values first, so negating * `D_tensor` makes the min_samples smallest distances rank first. Column * (min_samples − 1) of the negated result is the negated k-th order * statistic; negating again recovers the core distance. The diagonal (self, * distance 0) is always the least-negative value and occupies index 0. * * The returned tensor is owned by the caller and must be disposed after use. */ private core_distances; fit(X: DataMatrix): Promise; fit_predict(X: DataMatrix): Promise; }