mojolearn.SpectralClustering#

class mojolearn.SpectralClustering(n_clusters=8, *, n_components=None, random_state=None, n_neighbors=10, n_init=10, eigen_tol=1e-05, affinity='nearest_neighbors', assign_labels='kmeans', eigen_solver=None, gamma=None, degree=None, coef0=None, kernel_params=None, n_jobs=None, verbose=False, prediction_data=False)[source]#

Bases: object

Spectral clustering on a nearest-neighbor or precomputed affinity graph.

Builds an affinity graph, forms the normalized graph Laplacian, takes its n_components smallest eigenvectors with a thick-restart Lanczos solver and clusters the resulting embedding. Defaults follow cuML’s SpectralClustering, which differ from scikit-learn’s: the default affinity is "nearest_neighbors" with n_neighbors=10, and n_components defaults to n_clusters. The Laplacian is always normalized and the first (nearly constant) eigenvector is kept, so the clustering runs on all n_components columns; embedding_ is therefore not what SpectralEmbedding returns.

Eigenvectors are only defined up to sign, and a basis inside a repeated eigenvalue is arbitrary. Results are reproducible for the same input and seed, but a graph with c connected components has eigenvalue 0 with multiplicity c, and an embedding with n_components <= c can change a lot under tiny input changes.

Parameters:
  • n_clusters (int, default 8) – Number of clusters, in [1, n_samples].

  • n_components (int or None, default None) – Number of eigenvectors; None uses n_clusters. Must satisfy 1 <= n_components < n_samples.

  • random_state (int or None, default None) – Seed in [0, 2**32). None means seed 0, so results are deterministic (unlike scikit-learn and cuML, where None draws a fresh seed).

  • n_neighbors (int, default 10) – Neighbors per row in the nearest-neighbor graph; ignored with affinity="precomputed".

  • n_init (int, default 10) – Number of k-means restarts on the embedding (cuVS’s spectral default; KMeans itself defaults to 1).

  • eigen_tol (float, default 1e-5) – Convergence tolerance of the eigensolver; must be a positive float. The string "auto" raises NotImplementedError: cuML maps it to 0.0, which disables the convergence test.

  • affinity (str, default “nearest_neighbors”) – "nearest_neighbors" (symmetrized k-NN connectivity of X), "precomputed" (X is a square affinity matrix, dense or sparse), "rbf" (exp(-gamma * ||x_i - x_j||**2), scikit-learn’s kernel) or "precomputed_nearest_neighbors" (k-NN connectivity of a precomputed distance matrix, symmetrized as 0.5 * (C + C.T)). A callable or any other name raises ValueError.

  • assign_labels ({“kmeans”, “discretize”, “cluster_qr”}, default “kmeans”) – How labels are assigned from the embedding: k-means, or scikit-learn’s "discretize" and "cluster_qr".

  • eigen_solver (None) – Only None is accepted; any other value raises NotImplementedError.

  • gamma (float or None, default None) – RBF kernel coefficient, used only with affinity="rbf"; None means 1.0 (scikit-learn’s default). Setting it with another affinity raises NotImplementedError.

  • degree, coef0, kernel_params (None) – Not supported; any value raises NotImplementedError.

  • n_jobs (None) – Not supported; any value raises NotImplementedError.

  • verbose (bool, default False) – Not supported; True raises NotImplementedError.

  • prediction_data (bool, default False) – Keep the eigenpairs, degree scaling and k-means centroids (and, for "nearest_neighbors", the training rows) so that predict and save work. It does not change the fitted labels or embedding. Supported with assign_labels="kmeans" and the "nearest_neighbors" or "precomputed" affinities only; otherwise NotImplementedError.

Variables:
  • labels_ (Array of shape (n_samples,), int32) – Cluster label of each training row, in [0, n_clusters).

  • embedding_ (Array of shape (n_samples, n_components), float32) – The spectral embedding that was clustered.

  • n_components_ (int) – Number of eigenvectors used.

  • affinity_matrix_ (array) – The affinity matrix used by the fit: X itself for "precomputed", the dense matrix for "rbf" and "precomputed_nearest_neighbors". Not set for "nearest_neighbors".

  • n_features_in_ (int) – Number of features of X; set for "nearest_neighbors" and "rbf".

  • n_iter_assign_ (int) – Iterations of the "discretize" label assignment; set only for it.

Examples

>>> import numpy as np, mojolearn
>>> X = np.random.default_rng(0).random((1000, 8), dtype=np.float32)
>>> model = mojolearn.SpectralClustering(n_clusters=4, random_state=0).fit(X)
>>> labels = model.labels_
__init__(n_clusters=8, *, n_components=None, random_state=None, n_neighbors=10, n_init=10, eigen_tol=1e-05, affinity='nearest_neighbors', assign_labels='kmeans', eigen_solver=None, gamma=None, degree=None, coef0=None, kernel_params=None, n_jobs=None, verbose=False, prediction_data=False)[source]#

Methods

fit(X[, y])

Cluster X.

fit_predict(X[, y])

Fit to X and return the training labels.

load(path)

Load a model written by save.

predict(X)

Assign new rows to the fitted clusters.

save(path)

Save a model fitted with prediction_data=True to path (npz).

Attributes

gamma

scikit-learn's SpectralClustering default gamma is 1.0 (its SpectralEmbedding's is 1 / n_features).

gamma#

scikit-learn’s SpectralClustering default gamma is 1.0 (its SpectralEmbedding’s is 1 / n_features).

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

Cluster X.

Parameters:
  • X (array-like of shape (n_samples, n_features) or (n_samples, n_samples)) – Training data, or with affinity="precomputed" a square nonnegative affinity matrix (dense or sparse); with "precomputed_nearest_neighbors" a square distance matrix. Values must be finite.

  • y (ignored)

Returns:

self (SpectralClustering) – The fitted estimator.

Raises:
  • ValueError – If X holds NaN or infinity, a precomputed affinity has no nonzero entries, n_clusters exceeds n_samples or n_components is not below n_samples.

  • TypeError – If prediction_data is not a bool.

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

Fit to X and return the training labels.

Parameters:
  • X (array-like) – As in fit.

  • y (ignored)

Returns:

labels (Array of shape (n_samples,), int32) – Same as labels_.

predict(X)[source]#

Assign new rows to the fitted clusters.

Neither scikit-learn nor cuML provides predict for spectral clustering. This one uses the Nystrom out-of-sample extension (Bengio et al., NIPS 2003): each new row is projected onto the fitted eigenvectors through its affinity to the training rows, then assigned to the nearest fitted k-means centroid (ties go to the lowest centroid index). A row’s label does not depend on the other rows in the call.

Requires a fit with prediction_data=True.

The affinity of a new row:

  • "nearest_neighbors": its n_neighbors nearest training rows (Euclidean), each with weight 0.5. Training degrees are unchanged.

  • "precomputed": X is the affinity between the new rows and the training rows, shape (n_new, n_train), finite and nonnegative. A sparse matrix is densified.

Training rows passed to predict are not guaranteed to get their labels_: as a query, a row sees itself with weight 0.5 rather than 1.0 and has no reverse edges.

Parameters:

X (array-like of shape (n_new, n_features) or (n_new, n_train)) – New rows, or their affinity to the training rows.

Returns:

labels (Array of shape (n_new,), int32) – Cluster labels, numbered as in labels_.

Raises:

ValueError – If the model is not fitted, was fitted without prediction_data=True, X has the wrong shape or no rows, or a precomputed affinity is non-finite or negative.

Notes

Every embedding column is kept. If an eigenvalue of the normalized affinity has magnitude below 1e-3 (the projection would amplify that column more than 1000x), the prediction is refused with an error naming the column.

save(path)[source]#

Save a model fitted with prediction_data=True to path (npz).

A model restored with SpectralClustering.load can predict new rows, including on a CPU-only install, but cannot refit.

Parameters:

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

Raises:
classmethod load(path)[source]#

Load a model written by save.

The loaded model can predict; it does not refit. Arrays are read at their saved dtype and never cast.

Parameters:

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

Returns:

model (SpectralClustering) – The restored model, with labels_ and n_components_ set.

Raises:

ValueError – If the file is not a SpectralClustering model or its arrays have inconsistent shapes.