Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

26 Commits

Folders and files

Repository files navigation

drug-repurposing-pipeline

CI

A small, tested pipeline that surfaces drug-repurposing hypotheses for a disease by reasoning over the Open Targets knowledge graph: it finds the biological targets associated with a disease, collects existing drugs that act on those targets, removes drugs already used for the disease, groups what remains by mechanism of action, and evaluates the whole pipeline against known drugs.

The emphasis of this project is reliable, evaluated engineering, not modelling novelty. The candidate-generation logic is deterministic and fully tested; the interesting work is in the honest evaluation of what such a pipeline can and cannot tell you.

What it does

Given a disease (e.g. pemphigus), the pipeline:

  1. Finds associated targets — queries Open Targets for the disease's associated targets, ranked by association score.
  2. Collects candidate drugs — for each top target, fetches drugs known to act on it.
  3. Removes already-indicated drugs — excludes, by ChEMBL id, drugs already recorded as used for the disease. This subtraction is what makes the output repurposing candidates rather than a list of the disease's existing treatments.
  4. Groups by mechanism — collapses near-duplicate drugs and groups candidates by target, labelling each group "not yet used in" or "established" based on whether the disease's existing drugs already act on that mechanism.
  5. Evaluates — holds out a fraction of the disease's known drugs and measures how many the pipeline recovers (recall@k), plus precision@k and mean reciprocal rank.

How it works

disease ──▶ associated targets (ranked by score)
                     │
                     ▼
        drugs acting on each top target        already-indicated drugs
                     │                          (disease's own known drugs)
                     └──────────── subtract by ChEMBL id ──────────┘
                                   │
                                   ▼
                    group by mechanism, collapse duplicates,
                    label "not yet used" vs "established"
                                   │
                                   ▼
                        ranked repurposing candidates

Data source: Open Targets GraphQL API. Scoring is deterministic — no LLM is used, so results are reproducible and tests run offline with no API key.

Install

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,examples]"

Run

# Generate repurposing candidates for pemphigus and ALS (grouped by mechanism)
python examples/run_disease.py MONDO_0006594
python examples/run_disease.py MONDO_0004976 

# Evaluation metrics (recall@k, precision@k, MRR) across k, for pemphigus and ALS
python examples/run_metrics.py

# Recall-vs-k sensitivity analysis with figure
python examples/run_sensitivity.py

# Any of the above accepts a disease id; with none, the metric scripts run the
# pemphigus + ALS comparison by default.

Example output (pemphigus, grouped by mechanism)

[not yet used] PPAT
  AZATHIOPRINE (APPROVAL) | Amidophosphoribosyltransferase inhibitor
  MERCAPTOPURINE (APPROVAL) | Amidophosphoribosyltransferase inhibitor

[established] NR3C1
  ALCLOMETASONE DIPROPIONATE (APPROVAL, x53) | Glucocorticoid receptor agonist
  RELACORILANT (PHASE_3) | Glucocorticoid receptor antagonist
  ...

[established] BTK
  ACALABRUTINIB (APPROVAL, x18) | Tyrosine-protein kinase BTK inhibitor
  RILZABRUTINIB (…) | Tyrosine-protein kinase BTK inhibitor
  ...

19 already-indicated drugs excluded

Mechanisms already used to treat pemphigus (glucocorticoids on NR3C1, CD20 agents on MS4A1, IMPDH inhibitors, FcRn antagonists, BTK inhibitors) are labelled "established"; mechanisms the disease's existing drugs don't act on are labelled "not yet used".

Example output — contrast: ALS

The same pipeline on ALS (MONDO_0004976) illustrates the limitations described below. Its highest-scoring associated target is tubulin (TUBA4A), which pulls in dozens of oncology antibody–drug conjugates — pharmacologically irrelevant as ALS treatments, but linked to ALS via that target:

[established] TUBA4A
  CABAZITAXEL (APPROVAL, x23) | Tubulin inhibitor
  PACLITAXEL POLIGLUMEX (APPROVAL, x9) | Tubulin stabiliser
  TRASTUZUMAB EMTANSINE (APPROVAL, x2) | erbB-2 binding agent; Tubulin inhibitor
  ENFORTUMAB VEDOTIN (APPROVAL) | Nectin-4 binding agent; Tubulin inhibitor
  BRENTUXIMAB VEDOTIN (APPROVAL) | Tubulin inhibitor; TNFRSF8 binding agent
  ... (dozens more -vedotin / -mertansine / -ravtansine conjugates on the same target)

190 already-indicated drugs excluded

Two things this reveals. First, the candidate pool is dominated by drugs hitting an ALS-associated target for reasons unrelated to treating ALS — which is why recall and precision collapse on ALS. Second, TUBA4A is labelled [established] only because one of ALS's 190 already-indicated drugs happens to hit it; "established" means a known drug touches this target, not this is a genuine therapeutic mechanism. Both are properties of the data (weak, heterogeneous target associations), not of the pipeline — and both are the failure modes the evaluation section quantifies.

Evaluation

The pipeline is validated by holding out ~30% of a disease's known drugs and measuring how many are recovered through the target path, across 10 random seeds and a range of top_k values.

Disease (known drugs) recall@k (plateau) precision@k notes
Pemphigus (19) ~0.72 (range 0.33–0.83 across seeds) ~0.02 high recall, low precision
ALS (190) ~0.25 (range 0.04–0.32 across seeds) ~0.02 recall collapses on a large, noisy drug set

Two findings drive the interpretation:

  • Recall plateaus, it does not climb. For pemphigus, recall reaches ~0.72 by k≈10 and stays there to k=200; for ALS it reaches ~0.25 by k≈100. Beyond a small k, recall is bounded not by search depth but by how completely each disease's known drugs map onto its top associated targets. See docs/recall_vs_k.png.
recall_vs_k
  • Precision is low throughout (~0.02). The pipeline recovers known biology but surfaces it amid many near-duplicate candidates (e.g. dozens of glucocorticoid variants on NR3C1). This is precisely why the output is grouped and collapsed by mechanism rather than returned as a flat list. See docs/precision_recall_vs_k.png.
precision_recall_vs_k

Limitations

This is a v0.1 validated on one disease; its boundaries are stated plainly because they are the point.

  • Documented links only. The pipeline surfaces drugs already recorded in Open Targets as acting on a disease-associated target. It does not discover novel drug–target relationships or propose molecules without existing database evidence.
  • "Not yet used" means "not recorded in this dataset for this disease", not "never tried". For example, azathioprine surfaces as "not yet used" for pemphigus because Open Targets does not record it against pemphigus via that target — though it is used clinically. Labels reflect the data, not ground clinical truth.
  • Recall@k is an optimistic upper bound. A held-out known drug is "recovered" only if its target ranks highly — but Open Targets' association score is computed partly from known-drug (ChEMBL) evidence, which already encodes that the drug is used for the disease. So the score partly leaks the answer being held out.
  • The metric is small-sample and disease-dependent. Pemphigus's 19-drug benchmark gives a high but noisy estimate (recall swings 0.17 per drug across seeds); ALS's 190-drug set gives a low but stable one, because most ALS entries derive from weak genetic associations (its top target, tubulin/TUBA4A, pulls in oncology antibody-drug conjugates irrelevant to ALS). Recall@k is a valid sanity check only on diseases with small, clinically coherent drug sets — it is neither precise nor high in general.
  • Mechanism ≠ opportunity. A target being untouched by a disease's current drugs does not make a drug on it clinically viable; these are hypotheses for a human to triage, not recommendations.

These are properties of the benchmark and the data source, not of the candidate-generation code, which behaves identically for any disease.

Roadmap (not built)

  • Literature-support signal (e.g. Europe PMC drug–disease co-occurrence) to add confidence to each hypothesis.
  • Leakage-controlled evaluation that excludes the known-drug (ChEMBL) datasource from association scoring.
  • Generalised, drug-set-size-aware evaluation across disease types.

Tech notes

  • Python ≥3.10, httpx + pydantic; deterministic scoring, no LLM.
  • Live runs (the examples/ scripts) query the public Open Targets GraphQL API over the network — no API key required, but internet access is needed.
  • Tests use respx to mock the API, so the full suite runs offline with no network or API key; CI runs entirely without external calls.
  • Linting with ruff, CI via GitHub Actions (ruff check + pytest).
  • Configuration (API endpoint, default top_k, holdout fraction) centralised in src/repurpose/config.py.

Licence

MIT.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages