Skip to main content

CHB — Clustering Hardness Benchmark

ICML 2026 Open in Colab License: MIT

Official implementation of the ICML 2026 paper "CHB: A Diagnostic Toolkit for Hardness-Aware Clustering Evaluation" (Walid Durani, Philipp Jahn, Collin Leiber, David B. Hoffmann, Thomas Seidl, Claudia Plant, Christian Böhm).

Computes the CHB hardness fingerprint h(D) = (S; C; T) for a labeled dataset, plus the separability gate, the blob-calibrated topology evidence T_evid, and the deterministic regime assignment (A / B / C).

CHB framework overview: hardness fingerprint h(D) = (S; C; T), separability gate, topology evidence T_evid, and deterministic regime assignment (A/B/C), with key empirical findings Q1-Q3

Citation

If you use CHB, please cite:

@inproceedings{durani2026chb,
  title     = {{CHB}: A Diagnostic Toolkit for Hardness-Aware Clustering Evaluation},
  author    = {Durani, Walid and Jahn, Philipp and Leiber, Collin and
               Hoffmann, David B. and Seidl, Thomas and Plant, Claudia and
               B{\"o}hm, Christian},
  booktitle = {Proceedings of the 43rd International Conference on Machine Learning (ICML)},
  series    = {Proceedings of Machine Learning Research},
  volume    = {306},
  publisher = {PMLR},
  year      = {2026}
}

Install

pip install chb-clustering

or from source:

git clone https://github.com/Walid10010/CHB.git && cd CHB
pip install -e .

All dependencies (including ripser, which powers the topology descriptors T2/T3) are installed automatically. The distribution is named chb-clustering, the import name is chb — if you happen to have the unrelated PyPI package chb installed, uninstall it first to avoid a file collision.

Usage

Python API

from chb import compute_fingerprint

fingerprint, regime = compute_fingerprint(X, y)
# fingerprint: {"S1": ..., "S2": ..., "S3": ..., "C1": ..., "C2": ..., "T1": ..., "T2": ..., "T3": ...}
# regime:      "A" (separability collapse) | "B" (topology mismatch) | "C" (scale heterogeneity)

res = compute_fingerprint(X, y)     # rich result object
res.gate, res.t_evid, res.report    # gate details, topology evidence, full combined report

Labels are used for diagnosis only — never to fit clustering.

Command line

# Full CHB run on a single dataset (writes one combined JSON incl. regime)
chb both --input your.csv --label-col target
chb both --input your.npz            # expects arrays X and y/labels

# Batch over kdd_data/ (*.npz) and kdd_data_org/ (data_*/label_* pairs)
# Base dir via env var CLUSTERING_BASE_DIR (default: cwd); output: combined_results/
chb batch

# Add/refresh the CHB block (fingerprint, gate, T_evid, regime) on existing
# combined reports — understands legacy key names from earlier code versions
chb chb --report combined_results/

# Individual blocks
chb cohesion   --input your.csv
chb separation --input your.csv

Also available as python -m chb ...; the old python chb_metrics.py ... entry point keeps working via a deprecation shim.

Every combined report contains a top-level "chb" block:

"chb": {
  "fingerprint": {"S1": ..., "S2": ..., "S3": ..., "C1": ..., "C2": ...,
                   "T1": ..., "T2": ..., "T3": ...},
  "separability_gate": {"SEPF": ..., "gate_fails": ...},
  "topology_evidence": {"T_evid": ..., "tau_top": 15.0},
  "regime": "A" | "B" | "C"
}

Primary (CHB) descriptors

Paper JSON key (dataset_summary) Block Orientation
S1 S1_overlap separation ↑ harder
S2 S2_hubness separation ↑ harder
S3 S3_margin separation ↓ harder
C1 C1_density_complexity density ↑ harder
C2 C2_elongation cohesion ↑ harder
T1 T1_ph0_persistence cohesion ↑ harder
T2 T2_ph1_persistence cohesion ↑ harder
T3 T3_ph2_persistence cohesion ↑ harder

Regime rule: A if the separability gate fails (2-of-3 strict failures, equivalently SEPF = median(S1−0.5, S2−0.33, 1.0−S3) > 0); B if the gate passes and T_evid = Σ log(1+Tᵢ) > 15.0; C otherwise.

Secondary diagnostics

All non-CHB metrics are kept for exploration and are clearly marked with a sec_ prefix (e.g. sec_margin_svm, sec_geodesic_tightness, sec_density_composite_badness) or live in their own blocks (directional A1–A5, baseline meta-features, hyperparameter stability). They are not part of the CHB fingerprint or the regime rule.

Validation

smoke_test.py reproduces the paper's Appendix E.1 synthetic sanity checks (separated blobs → C, overlapping blobs → A, elongated clusters → C with high C2). On MNIST (n=50000, seed 42) the pipeline reproduces the paper's Table 15 fingerprint to table precision and assigns Regime B.

python tests/smoke_test.py            # all cases
python tests/smoke_test.py legacy     # fast case only

Note on legacy reports

Reports produced by earlier code versions use old key names; the chb annotate mode maps them automatically. Their density block (DensityComplexity) is treated as outdated and is recomputed on the next both/batch run.

License

Released under the MIT License.

Metadata

Release files for chb-clustering 1.0.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 chb-clustering 1.0.0
File Size Uploaded
chb_clustering-1.0.0.tar.gz 48.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chb-clustering 1.0.0
File Interpreter ABI Platform
chb_clustering-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 95.6 kB

Release files / chb_clustering-1.0.0.tar.gz

Download URL chb_clustering-1.0.0.tar.gz
Size 48.8 kB
Tags Source
SHA-256 checksum
How to use checksums
07a742b6d7b0a5fa65e00a9519d070958e33bddd9fa9b76f1afe0595e32e64f2
BLAKE2b-256 checksum
How to use checksums
036b1dcd76fb7307036d0cd9e483d27d55e8ab602870a90e02594638e36c01d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.13

Release files / chb_clustering-1.0.0-py3-none-any.whl

Download URL chb_clustering-1.0.0-py3-none-any.whl
Size 46.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a256a3e3eebab5b8776abd4ff625551b0ee15973774617430395b105f1efb3ab
BLAKE2b-256 checksum
How to use checksums
0c5796dd0f6302e12df53aa005f7e70e08d864b9d1ab05cc39915a6fc02854d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.13

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 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