Skip to main content

Python bindings for BETULA — Fast, streamable data clustering in Rust

Project description

BETULA

Fast, streamable data clustering in Rust — an improved implementation of the BIRCH algorithm with better cluster features.

What is BETULA?

BETULA introduces improved Clustering Feature (CF) trees that avoid the catastrophic cancellation present in the original BIRCH algorithm. The key contribution is a replacement cluster feature that:

  • Is numerically stable (no catastrophic cancellation)
  • Is not much more expensive to maintain
  • Makes many computations simpler and more efficient
  • Can be used in other BIRCH-derived algorithms (streaming, k-means, GMM, hierarchical clustering)

This crate is a Rust implementation based on ELKI's BETULA for the Java reference.

Reference: Lang & Schubert, "BETULA: Fast clustering of large data with improved BIRCH CF-Trees", Information Systems 108 (2022), DOI: 10.1016/J.IS.2021.101918

Installation

Add to your Cargo.toml:

[dependencies]
betula = "0.1"

Quick Start

use betula::cf_tree::CFTree;
use betula::cluster_feature::VII;
use betula::distance::CentroidEuclideanDistance;

// Create a CF-Tree with Euclidean distance
let mut tree = CFTree::new(
    CentroidEuclideanDistance::new(),  // distance function
    CentroidEuclideanDistance::new(),  // absorption function
    32,       // node capacity
    2,        // dimensionality
    1000,     // max leaf entries
    0.0,      // threshold (auto-estimated)
);

// Insert points
for point in &[
    vec![1.0, 2.0],
    vec![1.1, 2.1],
    vec![10.0, 20.0],
    vec![10.1, 20.1],
] {
    tree.insert(point);
}

// Access cluster statistics
for (id, cf) in tree.leaf_entries().iter().enumerate() {
    println!(
        "Cluster {}: {} points, centroid={:?}, variance={:.4}",
        id,
        cf.size(),
        cf.centroid(),
        cf.ssd() / cf.size() as f64,
    );
}

CF-Tree

The core data structure is a CFTree<F, CF, D, A> parameterized by:

Parameter Description
F Float type (e.g. f64)
CF Cluster feature type — VII, VVI, or VVV
D Distance function for tree routing
A Absorption function for leaf assignment

Cluster Features

Feature Stores Use case
VII Scalar SSD + centroid Simple clustering, most common
VVI Per-dimension SSD + centroid When per-dimension variance matters
VVV Full cross-product matrix + centroid When covariance is needed

Parameters

  • capacity: Node capacity — controls tree depth. Lower values give deeper trees; higher values give shallower trees. Recommended: 32–64.
  • maxleaves: Maximum leaf entries — triggers tree rebuilds when exceeded.
  • threshold: Leaf entry size limit — automatically estimated on rebuild. A good threshold avoids rebuilds; starting with 0 is fine.

Note: The Python bindings (betulars) provide default values for these parameters (capacity=32, maxleaves=1000, threshold=0.0). The Rust API requires all parameters explicitly.

Insertion API

  • insert(x) — validated insertion (checks dimensionality)
  • insert_unchecked(x) — unsafe fast path (caller guarantees x.len() >= dim)

Distance Measures

Six distance functions are available, all implementing the CFDistance trait:

Distance Description
CentroidEuclideanDistance Squared Euclidean distance between centroids
CentroidManhattanDistance Manhattan distance between centroids
AverageInterclusterDistance Average squared distance to cluster points (Zhang "D2")
AverageIntraclusterDistance Average pairwise distance within clusters (Lang & Schubert "D3")
VarianceIncreaseDistance SSD increase from adding/merging (Zhang "D4")
RadiusDistance Average radius of the resulting cluster

CLI Benchmark Tool

A benchmark binary is included for performance testing and comparison:

cargo build --release

./target/release/betula \
  --input data.npy \
  --output results.json \
  --capacity 32 \
  --maxleaves 1000 \
  --distance euclidean

Output: JSON with metadata, timing, per-cluster statistics (centroid, size, variance).

Python Bindings

BETULA can be used from Python via the betulars package, built with pyo3 and maturin.

Installation

From source:

pip install maturin
maturin develop --features python

Or build a wheel:

maturin build --features python
pip install target/wheels/betulars-*.whl

Quick Start

import numpy as np
import betulars

# High-level: build a model from data
data = np.array([[1.0, 2.0], [1.1, 2.1], [10.0, 20.0], [10.1, 20.1]])
model = betulars.Betula(
    data=data,
    capacity=32,
    maxleaves=1000,
    threshold=0.0,
    distance="euclidean",
    absorption="euclidean",
    feature="vii",  # or "vvi" or "vvv"
)

print(f"Clusters: {model.num_clusters}")
print(f"Variance: {model.overall_variance:.4f}")

for cf in model.leaf_clusters:
    print(f"  Cluster: {cf.size} points, centroid={cf.centroid}, variance={cf.variance:.4f}")

Incremental Insertion

import numpy as np
import betulars

# Lower-level: insert points one at a time
tree = betulars.CFTree(dim=2, capacity=32, maxleaves=1000, threshold=0.0, feature="vii")

for point in np.array([[1.0, 2.0], [1.1, 2.1], [10.0, 20.0]]):
    tree.insert(point)

print(f"Clusters: {tree.num_clusters}")
for cf in tree.leaf_clusters:
    print(f"  {cf.size} points, centroid={cf.centroid}")

Supported Distance Measures

Name Description
euclidean Squared Euclidean distance between centroids
manhattan Manhattan distance between centroids
avgintercluster Average squared distance to cluster points
avgintracluster Average pairwise distance within clusters
varianceincrease SSD increase from adding/merging
radius Average radius of the resulting cluster

Cluster Feature Types

Feature Stores Use case
vii Scalar SSD + centroid Simple clustering, most common
vvi Per-dimension SSD + centroid When per-dimension variance matters
vvv Full cross-product matrix + centroid When covariance is needed

API Reference

Betula

High-level wrapper. Builds a CF-Tree from data in one call.

  • Betula(data, capacity=32, maxleaves=1000, threshold=0.0, distance="euclidean", absorption="euclidean", feature="vii")
    • data — 2D numpy array, shape (n_points, n_dims), dtype float64
  • .leaf_clusters — list of ClusterFeature objects
  • .num_clusters — number of leaf clusters
  • .rebuild_count — number of tree rebuilds
  • .overall_variance — total SSD / total points

CFTree

Incremental CF-Tree. Insert points one at a time.

  • CFTree(dim, capacity=32, maxleaves=1000, threshold=0.0, feature="vii")
  • .insert(point) — insert a data point (1D numpy array or sequence)
  • .leaf_clusters — list of ClusterFeature objects
  • .num_clusters — number of leaf clusters
  • .rebuild_count — number of tree rebuilds
  • .dim — dimensionality

ClusterFeature

Read-only cluster statistics.

  • .size — number of points
  • .centroid — numpy 1D array
  • .ssd — sum of squared deviations
  • .ssd_per_dim — numpy 1D array of per-dimension SSDs
  • .covariance — numpy 2D array (or None for vii/vvi)
  • .variance — ssd / size

Python Version Support

Python 3.8 and later (via abi3 compatibility).

Roadmap

The following features are planned for future releases:

  • K-means clustering — Refine CF-Tree leaf clusters with k-means for a fast k-means approximation.
  • Gaussian Mixture Modelling — Fit GMMs to leaf clusters using the full covariance information from VVV cluster features.
  • Parallel tree building — Multi-threaded tree construction for improved performance on large datasets.
  • Hierarchical agglomerative clustering — Bottom-up merging of leaf clusters to produce a full hierarchy / dendrogram.

License

Dual licensed under MIT or Apache-2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

betulars-0.1.0.tar.gz (62.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

betulars-0.1.0-cp314-cp314t-win_amd64.whl (2.5 MB view details)

Uploaded CPython 3.14tWindows x86-64

betulars-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ x86-64

betulars-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl (1.6 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

betulars-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl (784.4 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

betulars-0.1.0-cp39-abi3-win_amd64.whl (2.5 MB view details)

Uploaded CPython 3.9+Windows x86-64

betulars-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ x86-64

betulars-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl (1.6 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ ARM64

betulars-0.1.0-cp39-abi3-macosx_11_0_arm64.whl (790.4 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file betulars-0.1.0.tar.gz.

File metadata

  • Download URL: betulars-0.1.0.tar.gz
  • Upload date:
  • Size: 62.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for betulars-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e770e377479f4c6d5aafffffc7c6d60d6a58db7fbdb40883af92bb31d6abd64c
MD5 4a7cfa79aa320041c3bf9cf45757f411
BLAKE2b-256 1f0f2428577431ab1226ec86fa352ae2c7b55a3f4a443d4075f511ded9078f60

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0.tar.gz:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp314-cp314t-win_amd64.whl.

File metadata

  • Download URL: betulars-0.1.0-cp314-cp314t-win_amd64.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: CPython 3.14t, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for betulars-0.1.0-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 1870396614f1ad044fb87d1fe1d69c90a92a959bbd08686b3fddb904f115cabe
MD5 5b803d5ccfca0027d4d77c2ed70d31ec
BLAKE2b-256 bdb48b88102888f9ec4876b46816a7dee62e5dfc1bbd8ea63cb563d464e5ebe3

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp314-cp314t-win_amd64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for betulars-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 468b9573f76821ada9dfe0a57c869ceb82c196b4fd3e44b41ca439610b3507d8
MD5 99bb12afbe25aabbac4b1603f1a5c466
BLAKE2b-256 f6f0fb669c049411e1ce6248dcf8c45662ae80a8ffa94f1b18c0875552a8f43e

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for betulars-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 99bd1711a54a3d241cc7fa91035499af0fb68c8fadf7162e0d430835877b2d3e
MD5 7823e8d730547755db28dd9419617bf9
BLAKE2b-256 b7db29b8da0dfb8ec6c89752951aaa501d9b4caa8b884893818d880248da0359

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for betulars-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0313d105ac8eb900770444a0ea61a3f7edeb74efb192f9c03ddc4a710d10345e
MD5 50b7af8636ac22631d9b3c18d93ad413
BLAKE2b-256 9b18d637b61acb20231e29b58cdc68dee76703b4548912c02ced8bb3772eeeef

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: betulars-0.1.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for betulars-0.1.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 63ddda2c9273b95b5bc95f4f8d1aaad0f1aa0b8b6abf4c7e9ba61ff9dcb4cd91
MD5 35f5fd08c6470c811b1fe6962005d4f3
BLAKE2b-256 d7d72563ea8559e12e498218ddec6cb4ef6de6756cc00986ea70714b052ecce7

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp39-abi3-win_amd64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for betulars-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 08dc609fcdb1ecccefe80c373d082baf7500de08782f76f9e5440b12a94b34cd
MD5 f79471af59775e772ad5d5a3a0044ee1
BLAKE2b-256 f756105eb3cd2070fa8929df6976657efd6f63281d1080e59d681d5e877e0555

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for betulars-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 89d147bacc78f2671a99478bb7dd94b0e93146953426f31fef55c9e7e541fa2e
MD5 c3531c7438819528bd9575d3993b15bd
BLAKE2b-256 f912361af6b405ff0ae935b31eb372528af01683b7399e6ddbb589d49d7bd67d

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file betulars-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for betulars-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 56f0bab00b9d3c21e226b63692c7ea76de4114e12b00b76bba0ed9485990b92d
MD5 af2eb1c2709505c41f34bbb9133ae0a3
BLAKE2b-256 891669809f6b6347767dc79e0c14df43d279746b0de47bba78ddf3922f6ab362

See more details on using hashes here.

Provenance

The following attestation bundles were made for betulars-0.1.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: build.yml on andiwg/betula

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page