Skip to content
NovartisPublic

About

Implementation of caMPO (Correlation-aware Multiparameter Optimization), a method for deriving data-driven non-negative MPO weights from property correlation structure in drug discovery.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

caMPO: Correlation-Aware Multiparameter Optimization

Reference implementation and synthetic-data experiments accompanying the manuscript:

caMPO: Correlation-aware multiparameter optimization for data-driven compound prioritization in drug design
Daniel Garellick, Michele Ghini, Jessica Lanini, Nadine Schneider, Grégori Gerebtzoff, and Raquel Rodríguez-Pérez
Novartis Biomedical Research, Basel, Switzerland

caMPO derives data-driven weights for multiparameter optimization (MPO) scoring.

Classical scalarized MPO combines desirability-transformed properties using equal or manually assigned weights, implicitly treating every property as independent. When properties are correlated, this overweights redundant optimization directions and can create a "false sense of progress." caMPO instead assigns each property an influence proportional to its unique contribution after accounting for the correlation structure of the data: redundant (positively correlated) objectives are down-weighted, while independent and anti-correlated objectives that encode genuine trade-offs are emphasized.

Method

For a set of desirability-transformed properties with correlation matrix R, caMPO finds the weight vector w that minimizes the aggregate correlation subject to the standard MPO constraints:

minimize over w:   w^T (R + eps I) w
subject to:        w_i >= 0,   sum_i w_i = 1

where eps >= 0 is a small ridge term added to the diagonal of the correlation matrix before inversion for numerical stability (default eps=1e-6).

Ignoring the non-negativity constraint, this convex quadratic program admits a closed-form solution via the Karush–Kuhn–Tucker (KKT) conditions, computed in src/campo/core.py as compute_campo_weights(R):

w* = ((R + eps I)^(-1) 1) / (1^T (R + eps I)^(-1) 1)

The formulation is conceptually related to Markowitz portfolio theory, where asset weights are optimized against a covariance structure to achieve diversification.

Note on the non-negativity constraint. The formula above is the exact KKT solution when all entries of (R + eps I)^(-1) 1 are non-negative (i.e., when the non-negativity constraints are not active). When some entries are negative — which can occur under strong correlations — the closed-form normalized weights leave the simplex, and compute_campo_weights falls back to one of two strategies:

  • Quadratic solution (default): the constrained problem is solved numerically as a quadratic program (SLSQP), converging to a global optimum solution.
  • Clipping heuristic (heuristic_clip=True): negative intermediate weights are clipped to zero and the remaining weights are renormalized to sum to 1.

The clipping heuristic is a fast approximation; the quadratic solver returns the exact non-negative optimum.

Scope of this repository

This repository provides the caMPO framework and the synthetic-data experiments used to validate it under controlled correlation structures (Section 3.1 of the manuscript). The synthetic datasets are drawn from multivariate Gaussian distributions with predefined correlation matrices covering independent, positively correlated, anti-correlated, and mixed regimes. The historical Novartis drug-discovery project data analyzed in the manuscript are proprietary and are not included here.

Installation

The environment is managed with conda; the package is installed via pyproject.toml.

conda env create -f environment.yml
conda activate campo
pip install -e ".[dev]"

Reproduce the synthetic experiments

make reproduce

This runs the full pipeline end to end:

  1. Generate synthetic datasets with controlled correlation structure.
  2. Analyze each dataset and render the correlation-matrix / caMPO-weight figures.
  3. Compose the two-panel manuscript figure for the selected experiments.

Datasets are written to data/processed/synthetic/ and figures to figures/synthetic/.

Individual steps

python scripts/generate_synthetic_data.py --seed 42 --n-rows 2000
python scripts/run_analysis.py --corr-colorbar each
python scripts/make_two_panel_figure.py --experiments Exp3_BCD_0.98 Exp11_BC_-0.35

Repository layout

Path Description
src/campo/core.py Closed-form compute_campo_weights implementation.
src/campo/data_generation.py Synthetic dataset specifications, generation, and CSV export.
src/campo/analysis.py Per-experiment analysis and correlation/weight figures.
src/campo/visualization.py Two-panel correlation + weight manuscript figure.
src/campo/plotting.py Shared plotting style and figure-saving helpers.
scripts/ Command-line wrappers for the generation and plotting workflows.
tests/ Unit tests for the core algorithm and visualization behavior.
notebooks/demo.ipynb Minimal walkthrough: generate data, compute weights, plot.
data/processed/synthetic/ Generated synthetic datasets (git-ignored).
figures/synthetic/ Generated figures (git-ignored).

Development

ruff check src tests scripts
pytest -q

For source-layout safety, you can also run tests and scripts with an explicit source path to ensure local imports:

PYTHONPATH=src pytest -q
PYTHONPATH=src python scripts/run_analysis.py --corr-colorbar each

Citation

If you use this code, please cite the manuscript above. A machine-readable citation entry will be added upon publication.

License

Released under the MIT License. See LICENSE.

About

Implementation of caMPO (Correlation-aware Multiparameter Optimization), a method for deriving data-driven non-negative MPO weights from property correlation structure in drug discovery.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages