Skip to main content

HeteroSplit

Leakage-safe entity-disjoint splits and audits for heterogeneous link-prediction datasets.

CI coverage python license: MIT

HeteroSplit constructs, validates, and reports cold-start / inductive splits for heterogeneous link-prediction tasks (drug–drug–cell-line synergy, drug–target interaction, recommendation, knowledge graphs). It is designed to complement PyTorch Geometric — it focuses narrowly on split semantics and leakage auditing, and does not replace PyG's loaders, samplers, or training stack.

Status: early release (0.1.x). APIs may change. This is positioned as a reusable implementation of entity-disjoint split policies and leakage audits for PyG HeteroData link-prediction tasks — not (yet) a research novelty claim.

Why

Graph libraries make random node/edge splitting easy, but cold-start experiments often rely on one-off scripts with ambiguous semantics. A nominally "cold" test set can still leak information through:

  • the same entity appearing in training under another edge or relation;
  • reverse edges left in the message-passing graph;
  • an unordered pair reversed across splits;
  • context entities (e.g. cell lines) crossing a supposedly disjoint boundary;
  • features / precomputed embeddings fit using held-out entities;
  • negative sampling that pulls entities or pairs from the wrong regime.

HeteroSplit makes the split contract explicit, enforces it, and produces evidence (a serializable manifest + audit report) that the contract holds.

Why it matters (real DrugComb): a small GraphSAGE link predictor scores AUC 0.84 under a random split but 0.27 on genuinely unseen drugs (either-cold-start) — random splitting massively overestimates cold-start performance. See benchmarks.

Install

The correctness core is pure Python + NumPy:

pip install heterosplit

PyTorch Geometric integration is an optional extra:

pip install "heterosplit[pyg]"

From source (development)

This project uses uv:

git clone https://github.com/ZubairQazi/heterosplit
cd heterosplit
uv sync                 # creates .venv and installs the dev toolchain
uv run pytest           # run the test suite
uv run --extra pyg pytest   # include the PyG adapter tests

Quickstart

from heterosplit import make_synthetic_dataset, split_records

# A DrugComb-shaped dataset: (drug, drug, cell-line) synergy observations.
# Swap in your own PredictionRecords / HeteroData for real data.
data = make_synthetic_dataset(
    n_records=5000,
    n_source_entities=120,
    n_context_entities=30,
    n_labels=2,
    source_type="drug",
    context_type="cell_line",
    relation="synergy",
    seed=42,
)

# Joint cold-start: a test triple must involve an unseen drug AND an unseen cell line.
spec = data.spec(
    "joint_cold_start",
    holdout={"drug": "either", "cell_line": "all"},
    ratios=(0.8, 0.1, 0.1),
    stratify_by="label",
    seed=42,
)

result = split_records(data.records, spec)
result.audit.raise_for_leakage()  # fails loudly on any leakage
result.manifest.save("split-manifest.json")  # deterministic, reloadable

train_edges = result.message_passing_edge_index()  # leakage-safe training graph

Runnable versions live in examples/ (quickstart.py, recommendation.py, drugcomb.py, corrupted_leakage.py), or try the CLI:

uv run heterosplit demo --regime joint_cold_start
uv run heterosplit split --input data.csv --spec spec.json --out-dir out/

Real data: DrugComb

The DrugComb drug–drug–cell-line synergy corpus is wired up directly (CC-BY-4.0):

from heterosplit.datasets.drugcomb import download_drugcomb_summary, load_drugcomb_csv

download_drugcomb_summary("drugcomb.csv")  # ~1.4 GB, once
records = load_drugcomb_csv("drugcomb.csv", max_rows=200_000)  # streams; filters mono-therapy rows

records_from_drugcomb(frame, ...) maps an in-memory DrugComb frame (dict or DataFrame) if you already have one.

Documentation

Split taxonomy (v1 target)

Regime Test-set contract
Random / transductive Test edges are unseen; entities may have appeared in training.
Pair cold-start The (s, d) pair is unseen, but each entity may appear separately.
Source cold-start Test source entities never appear as training sources.
Destination cold-start Test destination entities never appear as training destinations.
Either-entity cold-start At least one endpoint of each test edge is unseen.
Both-entity cold-start Both endpoints of every test edge are unseen.
Context cold-start Test context entities never occur in training.
Joint cold-start A configured combination of endpoint and context disjointness.

Leakage audit & manifests

Every split ships with an audit and a reproducible manifest:

  • result.audit turns the regime's contract into machine-checkable findings — entity / pair / context overlap (across all splits, including val-vs-test), reversed unordered pairs, message-passing leakage, duplicate observations, and optional negative-sample / feature-provenance checks. Each finding has a count, severity, and concrete offending ids; raise_for_leakage() fails on any violation.
  • result.manifest records library/schema versions, a collision-resistant input fingerprint, the normalized spec, per-split counts, and hashes of the split indices. manifest.digest() is a stable reproducibility key; runtime/memory measurements are kept separate so a fixed input + spec + seed always produce the same digest.

License

MIT

Metadata

Release files for heterosplit 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 heterosplit 0.1.0
File Size Uploaded
heterosplit-0.1.0.tar.gz 268.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for heterosplit 0.1.0
File Interpreter ABI Platform
heterosplit-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 331.8 kB

Release files / heterosplit-0.1.0.tar.gz

Download URL heterosplit-0.1.0.tar.gz
Size 268.3 kB
Tags Source
SHA-256 checksum
How to use checksums
bb8f39c951bf07322b496974fb010a7dc7f9bb64164251536f3d34d6e6d53655
BLAKE2b-256 checksum
How to use checksums
7f822003e055e8752da21e2f86993bec5ac7c96d5087d516a6db618ccb1bfda5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 13, 2026.

Transparency log

Release files / heterosplit-0.1.0-py3-none-any.whl

Download URL heterosplit-0.1.0-py3-none-any.whl
Size 63.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fbc41db611331229c044a02bb0b7dbaf58f7fa7c216bcd386ce80c9122af8b80
BLAKE2b-256 checksum
How to use checksums
e7ec0cd12a698afc0b119c9bcde6873719cdfc7210d378d95559a4e096c7deba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.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