Skip to main content

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.

Metadata

Release files for betulars 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for betulars 0.1.0
File Size Uploaded
betulars-0.1.0.tar.gz 62.5 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for betulars 0.1.0
File
betulars-0.1.0-cp314-cp314t-win_amd64.whl CPython 3.14 CPython 3.14 free-threading Windows x86-64 Details
betulars-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64 Details
betulars-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64 Details
betulars-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64 Details
betulars-0.1.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
betulars-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl CPython 3.9 abi3 Linux glibc 2.28+ x86-64 Details
betulars-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl CPython 3.9 abi3 Linux glibc 2.28+ ARM64 Details
betulars-0.1.0-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details

Total release size: 14.5 MB

Release files / betulars-0.1.0.tar.gz

Download URL betulars-0.1.0.tar.gz
Size 62.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e770e377479f4c6d5aafffffc7c6d60d6a58db7fbdb40883af92bb31d6abd64c
BLAKE2b-256 checksum
How to use checksums
1f0f2428577431ab1226ec86fa352ae2c7b55a3f4a443d4075f511ded9078f60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp314-cp314t-win_amd64.whl

Download URL betulars-0.1.0-cp314-cp314t-win_amd64.whl
Size 2.5 MB
Tags CPython 3.14 CPython 3.14 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
1870396614f1ad044fb87d1fe1d69c90a92a959bbd08686b3fddb904f115cabe
BLAKE2b-256 checksum
How to use checksums
bdb48b88102888f9ec4876b46816a7dee62e5dfc1bbd8ea63cb563d464e5ebe3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl

Download URL betulars-0.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl
Size 2.3 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
468b9573f76821ada9dfe0a57c869ceb82c196b4fd3e44b41ca439610b3507d8
BLAKE2b-256 checksum
How to use checksums
f6f0fb669c049411e1ce6248dcf8c45662ae80a8ffa94f1b18c0875552a8f43e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl

Download URL betulars-0.1.0-cp314-cp314t-manylinux_2_28_aarch64.whl
Size 1.6 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
99bd1711a54a3d241cc7fa91035499af0fb68c8fadf7162e0d430835877b2d3e
BLAKE2b-256 checksum
How to use checksums
b7db29b8da0dfb8ec6c89752951aaa501d9b4caa8b884893818d880248da0359
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl

Download URL betulars-0.1.0-cp314-cp314t-macosx_11_0_arm64.whl
Size 784.4 kB
Tags CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0313d105ac8eb900770444a0ea61a3f7edeb74efb192f9c03ddc4a710d10345e
BLAKE2b-256 checksum
How to use checksums
9b18d637b61acb20231e29b58cdc68dee76703b4548912c02ced8bb3772eeeef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp39-abi3-win_amd64.whl

Download URL betulars-0.1.0-cp39-abi3-win_amd64.whl
Size 2.5 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
63ddda2c9273b95b5bc95f4f8d1aaad0f1aa0b8b6abf4c7e9ba61ff9dcb4cd91
BLAKE2b-256 checksum
How to use checksums
d7d72563ea8559e12e498218ddec6cb4ef6de6756cc00986ea70714b052ecce7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl

Download URL betulars-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl
Size 2.3 MB
Tags CPython 3.9 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
08dc609fcdb1ecccefe80c373d082baf7500de08782f76f9e5440b12a94b34cd
BLAKE2b-256 checksum
How to use checksums
f756105eb3cd2070fa8929df6976657efd6f63281d1080e59d681d5e877e0555
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl

Download URL betulars-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl
Size 1.6 MB
Tags CPython 3.9 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
89d147bacc78f2671a99478bb7dd94b0e93146953426f31fef55c9e7e541fa2e
BLAKE2b-256 checksum
How to use checksums
f912361af6b405ff0ae935b31eb372528af01683b7399e6ddbb589d49d7bd67d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release files / betulars-0.1.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL betulars-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
Size 790.4 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
56f0bab00b9d3c21e226b63692c7ea76de4114e12b00b76bba0ed9485990b92d
BLAKE2b-256 checksum
How to use checksums
891669809f6b6347767dc79e0c14df43d279746b0de47bba78ddf3922f6ab362
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

9 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page