A self-contained, scikit-learn-compatible Python library of dataset-splitting strategies for cheminformatics machine learning. chemsplit implements 52 splitting strategies across nine families — baseline, scaffold, similarity, embedding, property, lineage, task, biomolecular, and protocol splitters — behind one coherent, deterministic API, plus a leakage-audit module and a set of reference/synthetic datasets to try them on.
✨ Features
- 🧩 9 families, 52 strategies — from a plain random split to scaffold-tree pruning, Butina/spectral clustering, UMAP-space holdouts, temporal and provenance cuts, protein-family and binding-site holdouts, drug-target cold-start benchmarks, and full CV/nested-CV protocol wrappers.
- 🎯 Deterministic by construction — every splitter accepts a
random_stateand produces bit-identical output regardless of record order orn_jobs, checked continuously by a golden-file regression suite and Hypothesis property tests. - 🛡️ Contract-checked results — every
SplitResultis validated against five structural invariants (index coverage, disjointness, group-label consistency, JSON round-tripping ofparams, id format) before it ever reaches your code. - 🔍 Built-in leakage auditing —
chemsplit.auditreports nearest-neighbour similarity, adversarial-validation AUC, exact/scaffold/ring-system overlap, and property/label shift between train and test. - 🧪 Chemistry-native featurization — ECFP/FCFP/MACCS/Avalon/atom-pair/topological-torsion fingerprints and physicochemical descriptors, behind a pluggable
Featurizerprotocol for your own. - 💻 CLI included — run, audit, and list any registered splitter without writing a line of Python.
- 📚 One example notebook per family — runnable, narrated walkthroughs of every splitter class under
notebooks/.
📦 Installation
pip install chemsplit
Optional extras enable additional splitters and featurizers:
| Extra | Enables |
|---|---|
chemsplit[umap] |
UMAPClusterSplitter (UMAP embedding + clustering) |
chemsplit[hdbscan] |
DensityClusterSplitter (HDBSCAN density clustering) |
chemsplit[ga] |
SIMPDSplitter (genetic-algorithm pseudo-time optimization, via deap) |
chemsplit[bio] |
Protein-sequence splitters with accelerated alignment (biopython, parasail) |
chemsplit[mmpa] |
MatchedMolecularSeriesSplitter matched-series extraction |
chemsplit[all] |
Everything above |
Note: every extra has a dependency-free fallback where one makes sense (e.g. a Hamming-distance fallback for sequence identity without
bio) — an extra buys you a better implementation, not a hard requirement.
🛠️ Requirements
- Python 3.11 – 3.13
- RDKit (installed automatically as a core dependency — no separate conda step needed)
💡 Usage
Quickstart
from chemsplit import datasets, get_splitter
fx = datasets.make_scaffold_families(n_scaffolds=10, per_scaffold=15)
splitter = get_splitter("scaffold_tree", train_size=0.8, test_size=0.2)
result = splitter.split_result(fx.smiles)[0]
train_smiles = [fx.smiles[i] for i in result.train]
test_smiles = [fx.smiles[i] for i in result.test]
print(f"{len(train_smiles)} train / {len(test_smiles)} test records")
Every splitter is resolved the same way, by its splitter_id (see chemsplit.list_splitters() for the full table) or by importing the class directly:
from chemsplit import ButinaSplitter
splitter = ButinaSplitter(cutoff=0.4, train_size=0.7, test_size=0.3, random_state=0)
🔍 Auditing a split for leakage
from chemsplit import audit_split
report = audit_split(result, fx.smiles)
print(report.summary())
chemsplit LeakageReport
------------------------
n_train=120 n_valid=0 n_test=30 n_discard=0
max cross-partition similarity: 0.4375
median NN similarity (test->train): 0.6667
exact duplicates across partitions: 0
shared scaffolds: 0 shared ring systems: 0
adversarial AUC: 1.0000 (95% CI 1.0000-1.0000)
flags: MEDIAN_NN_ABOVE_0.6, HIGH_ADVERSARIAL_AUC, ...
LeakageReport is purely descriptive — it never fails your pipeline, it tells you what to look at.
💻 The CLI
# List every registered splitter, optionally filtered by family
chemsplit list --family scaffold
# Run a splitter over a CSV and write the split to disk
chemsplit split --splitter scaffold_tree --input data.csv --smiles-col smiles \
--train-size 0.8 --test-size 0.2 --seed 0 --out split.json
# Audit that split for leakage
chemsplit audit --split split.json --input data.csv --smiles-col smiles --out report.json
chemsplit --help
🧭 Design principles
- Determinism. Same inputs + same
random_state⇒ byte-identical outputs, on any platform, any CPU count, anyn_jobs. - Explicitness. No silent fallbacks. If a requested configuration is infeasible, raise, never approximate.
- Honesty. Every splitter's docstring discloses its pitfalls with the same prominence as its advantages.
- Composability. Every group-forming splitter exposes its group labels, so any grouping can be fed to any protocol wrapper.
- scikit-learn compatibility.
.split()is drop-in usable incross_val_score,GridSearchCV(cv=...), andcross_validate.
📚 Learn more
One narrated, runnable notebook per family, under notebooks/:
baseline.ipynb— uninformed and gold-standard controlsscaffold.ipynb— chemotype-aware generalization testssimilarity.ipynb— fingerprint-clustering holdoutsembedding.ipynb— latent-space holdoutsproperty.ipynb— label-shift and distributional stress testslineage.ipynb— date and provenance-aware holdoutsbiomolecular.ipynb— protein-axis holdoutstask.ipynb— drug-target interaction benchmarksprotocol.ipynb— cross-validation and evaluation harnesses
📄 License
This project is licensed under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chemsplit-0.1.0.tar.gz.
File metadata
- Download URL: chemsplit-0.1.0.tar.gz
- Upload date:
- Size: 223.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
359f9a12523d69ad548640aba582660ea39033355670ccfae2372b9eece2fed9
|
|
| MD5 |
7b24411d6059b474309d26b77197cb6d
|
|
| BLAKE2b-256 |
513302705d50edcafbd4c653bfcfe15b6d18546915c088d67609cbe6a750cc23
|
File details
Details for the file chemsplit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: chemsplit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 196.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f078de71d50770c1001c756edaee2092651243de679deed34e1f2b6ffaef53a
|
|
| MD5 |
04e26e8d67c92bebef4dab30787eae6f
|
|
| BLAKE2b-256 |
724a65ce929aed9fb4399a0723199db1f43c268e21bcd192382ad8ee508edfea
|