betula-cluster 0.1.1 — first public release
Fast, memory-bounded, numerically stable BETULA CF-tree clustering with a from-scratch Rust core and a scikit-learn API. No LAPACK, no SciPy at runtime.
Install: pip install betula-cluster
Highlights
- ⚡ 15–40× faster than scikit-learn at N = 1,000,000 — k-means labels 1M points in 0.20 s (vs KMeans 3.3 s, Birch 8.0 s, GaussianMixture 5.5 s).
- 🪶 Bounded memory — streaming 10M points peaks at ~57 MB, flat in N (clusters data larger than RAM); an in-core KMeans needs ~5 GB.
- 🎯 Quality at parity — k-means / GMM / Ward within ≈0.01 ARI of scikit-learn; full-covariance GMM recovers anisotropic clusters; HDBSCAN-on-CF nails non-convex shapes (ARI 1.00).
- 🔢 High-dimensional
normalize=True— MNIST-784 ARI 0.04 → 0.44, beating scikit-learn (0.32). - 🧱 Numerically stable —
(n, μ, S)Welford/Chan updates, PSD by construction; no catastrophic cancellation far from the origin.
What's inside
- Heads: weighted k-means (Hamerly), GMM (diagonal & full), exact Ward-HAC, HDBSCAN-on-CF, Mapper topology; automatic
k(BIC / dendrogram cut). - Streaming:
partial_fitat bounded memory,DenStream/DbStream, mergeable KLL / DDSketch quantiles. - Data: dense f32/f64,
scipy.sparse(O(nnz)), mixed numeric+categorical (k-prototypes). - Beyond labels:
predict_proba, coresets, outliers, near-duplicate pairs, representatives, drift snapshots, COP-KMeans constraints, robust (Huber) insertion. - Engineering: scikit-learn API (Pipeline / clone / GridSearchCV), typed abi3 wheel, save/load + pickle, dependency-free CLI, reusable Rust crate.
Quality bar
153-case Python suite at 100% wrapper coverage + 129 Rust tests; clippy -D warnings + fmt clean across all feature sets; Python 3.11–3.14 (single abi3 wheel).
Wheels
abi3 (CPython 3.11+): manylinux x86_64 + aarch64, macOS x86_64 + arm64, Windows x64, + sdist.
📊 Benchmarks · 📖 Docs · 📓 Examples · 📝 Changelog