netcl.cluster: Clustering & Graph Algorithms
netcl.cluster: Clustering & Graph Algorithms
The netcl.cluster module provides hardware-accelerated clustering and graph partitioning algorithms on OpenCL devices.
GPU kernels evaluate distance metrics and argmin reductions in a single pass. Large intermediate distance matrices are never allocated in VRAM, preserving memory for high-dimensional representations.
[!TIP] Theory & Curriculum Link: For the first-principles mathematical derivation of Voronoi partitions, fused distance-argmin execution, and Graph Laplacians, see Curriculum: Clustering & Geometry and Curriculum: Spectral Graph Theory.
1. Quick Example: KMeans and Spectral Clustering
import numpy as np
from netcl import cluster
from netcl.core.device import manager
from netcl.core.tensor import Tensor
q = manager.default("auto").queue
X = Tensor.from_host(q, np.random.randn(1000, 64).astype(np.float32))
# 1. GPU-accelerated KMeans
km = cluster.KMeans(n_clusters=8, seed=0).fit(X)
labels = km.labels_
# 2. Graph-based Spectral Clustering with k-NN affinity graph
sc = cluster.SpectralClustering(n_clusters=4, n_neighbors=10, affinity="knn").fit(X)
2. Algorithm Overview
| Class | Distance Metric / Mechanism | Target Application |
|---|---|---|
KMeans |
Euclidean (L2) | Standard clustering of spherical point clouds |
MiniBatchKMeans |
Euclidean (Streaming batches) | Datasets that exceed available GPU VRAM |
SphericalKMeans |
Cosine Distance (L2-normalized) | Embeddings from language models or SSL vision |
BalancedKMeans |
Sinkhorn Equipartition | Pseudo-labels for deep learning preventing cluster collapse |
GaussianMixture |
Diagonal Covariance (Log-space) | Soft probabilistic cluster memberships |
DBSCAN |
Density-based ($O(N)$ VRAM) | Unknown cluster count, noise/outlier filtering (-1) |
SpectralClustering |
k-NN Graph + LOBPCG | Non-convex geometries, concentric rings, manifolds |
3. SpectralClustering (Graph-Based Clustering)
Constructs a $k$-Nearest Neighbors ($k$-NN) graph and computes spectral graph decomposition to separate non-linear cluster manifolds.
from netcl.cluster import SpectralClustering
sc = SpectralClustering(
n_clusters=4, # Number of target clusters
n_neighbors=10, # Number of neighbors per node in k-NN graph
affinity="knn", # "knn" with local density scaling or "rbf"
n_power_iter=200, # Maximum iterations for LOBPCG eigensolver
seed=0,
)
sc.fit(X)
labels = sc.labels_ # NumPy int32 array of shape (N,)
coords = sc.embedding_ # Spectral coordinates of shape (N, n_clusters)
Graph Execution Pipeline
- k-NN Graph with Local Density Scaling: Rather than using a rigid global Gaussian bandwidth, netcl scales edge weights by local density:
$$W_{ij} = \exp\left(-\frac{\text{dist}(x_i, x_j)^2}{\sigma_i \cdot \sigma_j}\right)$$
Where $\sigma_i$ is the Euclidean distance from sample $i$ to its $k$-th nearest neighbor. The matrix is symmetrized via $W = \max(W, W^T)$.
- Normalized Graph Laplacian: Using degree vector $d = W\mathbf{1}$, the normalized affinity operator is formed:
$$A = D^{-1/2} W D^{-1/2}$$
- GPU-Accelerated LOBPCG Eigensolver: Finds the leading eigenvectors of $A$. All compute-heavy sparse matrix-vector multiplications execute on the GPU, while the small $(3K \times 3K)$ Rayleigh-Ritz subproblem is solved on the host CPU. Embeddings are normalized onto the unit hypersphere and clustered via KMeans.
4. KMeans
Classical Lloyd algorithm featuring k-means++ seeding and empty-cluster reseeding.
from netcl.cluster import KMeans
km = KMeans(
n_clusters=8,
init="k-means++",
n_init=1,
max_iter=100,
tol=1e-4,
seed=0,
)
km.fit(X)
# Fitted attributes
labels = km.labels_ # int32 cluster assignments
centers = km.cluster_centers_ # Centroid tensor of shape (n_clusters, D)
inertia = km.inertia_ # Sum of squared distances to closest centroid
# Assign new samples
new_labels = km.predict(new_X)
5. SphericalKMeans & BalancedKMeans
SphericalKMeans (Cosine Similarity)
Projects all vectors onto the unit sphere and optimizes cosine similarity. Ideal for normalized embeddings where angular direction represents semantic content:
from netcl.cluster import SphericalKMeans
skm = SphericalKMeans(n_clusters=16, seed=0).fit(embeddings)
labels = skm.labels_
BalancedKMeans (Equipartition Constraints)
Prevents cluster collapse by enforcing that every cluster contains approximately $\frac{N}{K}$ samples using the Sinkhorn-Knopp optimal transport algorithm:
from netcl.cluster import BalancedKMeans
bkm = BalancedKMeans(n_clusters=10, max_iter=50, eps=0.05, seed=0).fit(X)
pseudo_labels = bkm.labels_
6. GaussianMixture
Expectation-Maximization (EM) algorithm for Gaussian Mixture Models with diagonal covariance in log-space:
from netcl.cluster import GaussianMixture
gmm = GaussianMixture(
n_components=5,
max_iter=100,
tol=1e-4,
init="kmeans",
seed=0,
).fit(X)
hard_labels = gmm.predict(X) # Discrete cluster assignment
probs = gmm.predict_proba(X) # Soft posterior probabilities (N, K)
bic = gmm.bic(X) # Bayesian Information Criterion for model selection
7. DBSCAN
Density-based clustering with automated cluster discovery and outlier detection:
from netcl.cluster import DBSCAN
db = DBSCAN(eps=0.5, min_samples=5, metric="euclidean").fit(X)
labels = db.labels_ # -1 designates noise / outlier points
n_clusters = db.n_clusters_
core_points = db.core_sample_indices_
8. Evaluation Metrics (netcl.cluster.metrics)
from netcl.cluster import (
silhouette_score,
davies_bouldin_score,
cluster_report,
)
# Unsupervised metrics (without ground-truth labels)
sil = silhouette_score(X, km.labels_)
db = davies_bouldin_score(X, km.labels_)
# Supervised evaluation (against validation ground truth y_true)
print(cluster_report(y_true, km.labels_, X))
Related Documentation
- Concepts: Clustering: Details on GPU memory efficiency and fused kernels.
- Curriculum: Clustering & Geometry: Theoretical foundations of Voronoi partitions.
- Curriculum: Spectral Graph Theory: Mathematical derivation of graph Laplacians.