mojolearn.hdbscan#

HDBSCAN density-based clustering.

HDBSCAN clusters the training data. When it is fitted with prediction_data=True, three functions in this module work on new or training points under the fitted clustering, following cuML’s cuml.cluster.hdbscan functions of the same names:

  • approximate_predict gives the cluster label and probability of new points;

  • membership_vector gives the soft cluster membership of new points;

  • all_points_membership_vectors gives the soft cluster membership of every training point.

Each raises ValueError for a clusterer fitted without prediction_data=True, as cuML does. Soft membership is computed in float32 throughout, where cuML uses float64 in some steps.

Functions

approximate_predict(clusterer, points_to_predict)

Predict the cluster of new points under a fitted clustering.

membership_vector(clusterer, points_to_predict)

Soft cluster membership of new points.

all_points_membership_vectors(clusterer[, ...])

Soft cluster membership of every training point.

Classes

HDBSCAN([min_cluster_size, min_samples, ...])

Hierarchical density-based clustering (HDBSCAN).

class mojolearn.hdbscan.HDBSCAN(min_cluster_size=5, min_samples=None, cluster_selection_epsilon=0.0, max_cluster_size=0, metric='euclidean', alpha=1.0, cluster_selection_method='eom', allow_single_cluster=False, prediction_data=False)[source]#

Bases: NumericModeMixin

Hierarchical density-based clustering (HDBSCAN).

Follows cuML’s cuml.cluster.HDBSCAN: builds the mutual reachability graph from exact nearest neighbors, its minimum spanning tree and the condensed cluster tree, then selects clusters by excess of mass or by leaf. Points in no cluster are labeled -1 (noise). X is read as float32; only the Euclidean metric is supported. A NaN or infinity in X, or fewer than 2 rows, raises an error.

Parameters:
  • min_cluster_size (int, default 5) – Smallest group of points that counts as a cluster. Must be between 2 and the number of rows.

  • min_samples (int or None, default None) – Number of neighbors used for the core distance. None means min_cluster_size, as in cuML and scikit-learn. Must be between 1 and the number of rows.

  • cluster_selection_epsilon (float, default 0.0) – A selected cluster born below this distance is merged into its first ancestor born above it. 0.0 disables merging. Must be finite and non-negative.

  • max_cluster_size (int, default 0) – Largest cluster the excess-of-mass selection may return. 0 means no limit.

  • metric ({‘euclidean’}, default ‘euclidean’) – Distance metric. Any other value raises ValueError.

  • alpha (float, default 1.0) – Distance scaling in the robust single linkage. Must be positive and finite.

  • cluster_selection_method ({‘eom’, ‘leaf’}, default ‘eom’) – ‘eom’ selects by excess of mass; ‘leaf’ selects the leaves of the condensed tree.

  • allow_single_cluster (bool, default False) – Allow the result to be a single cluster.

  • prediction_data (bool, default False) – Keep the condensed tree and build prediction data during fit, so approximate_predict, membership_vector, all_points_membership_vectors and save can be used. The clustering itself is the same either way.

Variables:
  • labels_ (Array of shape (n_samples,), int32) – Cluster of each training point, 0 .. n_clusters_ - 1, or -1 for noise. Numbered as cuML numbers them.

  • probabilities_ (Array of shape (n_samples,), float32) – Strength of each point’s membership in its cluster, 0 for noise.

  • core_distances_ (Array of shape (n_samples,), float32) – Distance from each point to its min_samples-th nearest neighbor, not counting the point itself.

  • n_clusters_ (int) – Number of clusters found.

  • n_outliers_ (int) – Number of noise points.

  • n_boruvka_rounds_ (int) – Number of Boruvka rounds the minimum spanning tree took.

  • n_condensed_clusters_ (int) – Number of clusters in the condensed tree.

  • n_features_in_ (int) – Number of features seen during fit.

Examples

>>> import numpy as np, mojolearn
>>> X = np.random.default_rng(0).random((1000, 8), dtype=np.float32)
>>> model = mojolearn.HDBSCAN(min_cluster_size=10, prediction_data=True).fit(X)
>>> labels = model.labels_
>>> new_labels, strengths = mojolearn.hdbscan.approximate_predict(model, X[:10])
fit(X, y=None)[source]#

Cluster X.

Parameters:
  • X (array-like of shape (n_samples, n_features)) – Training data, read as float32.

  • y (ignored) – Present for scikit-learn API compatibility.

Returns:

self (HDBSCAN) – The fitted estimator.

Raises:
  • TypeError – If an integer parameter is not an int, alpha or cluster_selection_epsilon is not a number, or prediction_data is not a bool.

  • ValueError – For an unknown metric or cluster_selection_method, or a negative or non-finite cluster_selection_epsilon.

fit_predict(X, y=None)[source]#

Cluster X and return labels_.

Returns:

labels (Array of shape (n_samples,), int32)

save(path)[source]#

Save the fitted model to path as an .npz file.

The file holds what approximate_predict, membership_vector and all_points_membership_vectors read, including the training data. Load it with load, or with mojolearn.host_model(path) to predict new points on a machine with no GPU.

Parameters:

path (str or path-like) – Destination file.

Raises:

ValueError – If the model is not fitted, was fitted without prediction_data=True, or metric or cluster_selection_method is not given by name.

classmethod load(path)[source]#

Load a model written by save.

Arrays keep their saved dtypes. The result works with approximate_predict, membership_vector and all_points_membership_vectors.

Parameters:

path (str or path-like) – File written by HDBSCAN.save.

Returns:

model (HDBSCAN)

Raises:

ValueError – If the file is of another format or estimator, or is truncated or inconsistent.

mojolearn.hdbscan.approximate_predict(clusterer, points_to_predict)[source]#

Predict the cluster of new points under a fitted clustering.

Follows cuML’s approximate_predict. The labels are those of the original clustering, not the labels a re-clustering with the new points would find (hence “approximate”). If the clusterer found no clusters, a warning is issued and every point is labeled noise.

Parameters:
  • clusterer (HDBSCAN) – A model fitted with prediction_data=True.

  • points_to_predict (array-like of shape (n_samples, n_features)) – New points, read as float32, with the fitted number of features.

Returns:

  • labels (Array (n_samples,) int32) – -1 where the nearest mutual reachability neighbor is noise or the point falls outside its cluster’s lambda range.

  • probabilities (Array (n_samples,) float32) – Strength of each point’s membership in its predicted cluster.

Raises:
  • TypeError – If clusterer is not a mojolearn HDBSCAN.

  • ValueError – If the clusterer is not fitted, was fitted without prediction_data=True, or the feature count differs from the fit’s.

Examples

>>> import numpy as np, mojolearn
>>> X = np.random.default_rng(0).random((1000, 8), dtype=np.float32)
>>> model = mojolearn.HDBSCAN(prediction_data=True).fit(X)
>>> labels, strengths = mojolearn.hdbscan.approximate_predict(model, X[:10])
mojolearn.hdbscan.membership_vector(clusterer, points_to_predict, batch_size=4096)[source]#

Soft cluster membership of new points.

Follows cuML’s membership_vector. Row i gives, for each selected cluster j, the probability that point i is a member of cluster j: the distance to the cluster’s exemplars and the merge height in the condensed tree, combined, normalized, and scaled by the probability that the point is in some cluster, so a row sums to at most 1 and a point far from every cluster has a row near 0.

Computed in float32 throughout, where cuML uses float64 in some steps. Where cuML’s row overflows to NaN (duplicated points), this row is finite.

Parameters:
  • clusterer (HDBSCAN) – A model fitted with prediction_data=True.

  • points_to_predict (array-like of shape (n_samples, n_features)) – New points, read as float32, with the fitted number of features.

  • batch_size (int, default 4096) – Maximum number of points computed per call. Rows are independent, so it does not change the result. Must be positive.

Returns:

membership_vectors (Array (n_samples, n_clusters_) float32)

Raises:
  • TypeError – If clusterer is not a mojolearn HDBSCAN or batch_size is not an int.

  • ValueError – If the clusterer is not fitted, was fitted without prediction_data=True, batch_size is not positive, or the feature count differs from the fit’s.

Examples

>>> import numpy as np, mojolearn
>>> X = np.random.default_rng(0).random((1000, 8), dtype=np.float32)
>>> model = mojolearn.HDBSCAN(prediction_data=True).fit(X)
>>> soft = mojolearn.hdbscan.membership_vector(model, X[:10])
mojolearn.hdbscan.all_points_membership_vectors(clusterer, batch_size=4096)[source]#

Soft cluster membership of every training point.

Follows cuML’s all_points_membership_vectors, using the fact that the training points are already in the condensed tree. Each row has the same meaning as a row of membership_vector. Computed in float32 throughout.

Parameters:
  • clusterer (HDBSCAN) – A model fitted with prediction_data=True.

  • batch_size (int, default 4096) – Maximum number of training rows computed per call. Rows are independent, so it does not change the result. Must be positive.

Returns:

membership_vectors (Array (n_samples, n_clusters_) float32) – With no cluster the shape is (n_samples, 0). cuML returns a 1-D zero vector of length n_samples there instead.

Raises:
  • TypeError – If clusterer is not a mojolearn HDBSCAN or batch_size is not an int.

  • ValueError – If the clusterer is not fitted, was fitted without prediction_data=True, or batch_size is not positive.

Examples

>>> import numpy as np, mojolearn
>>> X = np.random.default_rng(0).random((1000, 8), dtype=np.float32)
>>> model = mojolearn.HDBSCAN(prediction_data=True).fit(X)
>>> soft = mojolearn.hdbscan.all_points_membership_vectors(model)