Skip to main content

A library to quickly build QSAR models

Project description

Ersilia's LazyQSAR

A Python library for building supervised QSAR models quickly, with minimal configuration. LazyQSAR automates chemical descriptor computation, and model selection to produce robust models for property and activity prediction.

Two entry points:

  • LazyClassifierQSAR: pass SMILES strings directly; built-in descriptors are computed automatically
  • LazyClassifier: bring your own pre-computed descriptor arrays

Table of Contents

Installation

We recommend installation from source:

git clone https://github.com/ersilia-os/lazy-qsar.git
cd lazy-qsar
pip install -e .

The base install includes only lightweight runtime dependencies (numpy, onnxruntime, etc.), sufficient for loading and running pre-trained ONNX models without any ML and chemistry-related packages (RDKit). Therefore, the base install assumes descriptors are provided by the user.

You can install optional extras depending on your use case:

Extra Command Adds
fit pip install -e .[fit] Required to train models (scikit-learn, XGBoost, scipy, skl2onnx)
descriptors pip install -e .[descriptors] Required for built-in molecular descriptors (e.g. RDKit, FPSim2)
all pip install -e .[all] Everything above

The first time you use deep-learning descriptors (Chemeleon, CLAMP, CDDD), their checkpoints are downloaded automatically. To do this in advance:

lazyqsar setup --descriptors

Python API

LazyClassifierQSAR (SMILES)

Pass SMILES strings directly. Choose a descriptor mode:

Mode Descriptors Notes
fast Morgan fingerprints No deep-learning models, fastest
slow Chemeleon, CLAMP, Morgan, RDKit (physchem), CDDD Most thorough
from lazyqsar.qsar import LazyClassifierQSAR

model = LazyClassifierQSAR(mode="slow") # default is "slow"
model.fit(smiles_list=smiles_train, y=y_train)

Available prediction methods:

Method Returns Description
predict(smiles_list) (N,) Binary labels at an optimized threshold
predict_proba(smiles_list) (N, 2) Calibrated class probabilities
predict_logit(smiles_list) (N, 2) Log-odds scores
predict_rank(smiles_list) (N, 2) Rank quantiles (0–1)
predict_score(smiles_list) (N, 2) Raw model scores
predict_lift(smiles_list) (N, 2) Probability / population prior

LazyClassifier (custom descriptors)

Pass your own descriptor arrays or HDF5 files. We recommend the Ersilia Model Hub for descriptor computation — its .h5 output format is supported natively.

from lazyqsar.agnostic import LazyClassifier

# From a NumPy array
model = LazyClassifier()
model.fit(X=X_train, y=y_train)
y_hat = model.predict_proba(X=X_test)[:, 1]

# From an Ersilia .h5 file
model.fit(h5_file="descriptors.h5", y=y_train)
y_hat = model.predict_proba(h5_file="descriptors.h5")[:, 1]

The same prediction methods listed above are available, using X= instead of smiles_list=.

Saving and loading

Models are saved as ONNX files, so inference only requires numpy and onnxruntime, i.e. no scikit-learn or XGBoost at prediction time. Metadata is stored in JSON format.

To save models:

model.save(model_dir)          # directory
model.save("my_model.zip")     # or zip archive

And to load them:

model = LazyClassifierQSAR.load(model_dir)
y_hat = model.predict_proba(smiles_list=smiles_test)[:, 1]

model = LazyClassifier.load(model_dir)
y_hat = model.predict_proba(X=X_test)[:, 1]

CLI

All commands are available through the lazyqsar entry point.

Fit:

The --input directory must contain one CSV per task, with SMILES in the first column and binary labels (0/1) in the second column, with a header row.

lazyqsar fit --task classification --input $DATA_DIR --output $MODEL_DIR --mode slow

Pass --models_txt to train a subset of tasks (one CSV stem per line); without it, all CSVs in the directory are used.

Predict:

lazyqsar predict --input $INPUT_CSV --model $MODEL_DIR --output $OUTPUT_CSV

The output CSV contains one predicted probability column per task, ordered alphabetically by task name, or according to the order provided by --models_txt at fit time.

How it works

LazyQSAR builds an ensemble for each descriptor set through four steps:

  1. Portfolio selection: the dataset is profiled (sample count, dimensionality, sparsity, class imbalance) and a rule-based selector decides which heads to train. The default portfolio is XGBoost + Random Forest; Linear Models and Support Vector Machines are added automatically for small, high-dimensional, or low-prevalence datasets.

  2. Preprocessing: a scaler (StandardScaler, RobustScaler, MaxAbsScaler, or PowerTransformer) and an optional correlation-based feature reducer are selected automatically from dataset statistics.

  3. Heads: each selected head is fitted on preprocessed features. For severely imbalanced datasets, balanced sub-batches are used and the batch predictions are averaged.

  4. Pooling: head predictions are combined via a learned gating network (InnerClassifierPooler When using LazyClassifierQSAR, a separate ensemble is trained per descriptor type and their predictions are combined via an AUC-weighted ensemble that accounts for per-sample prediction confidence.

  5. Export: the full pipeline is exported to ONNX for dependency-free inference.

Base Models

The components under lazyqsar/base/ can be used independently of the full pipeline:

Module Description
lazyqsar.base.preprocessing Automatic scaler and feature reducer selection
lazyqsar.base.xgboost Automatic XGBoost hyperparameter selection with portfolio comparison
lazyqsar.base.linear Automatic linear model selection (logistic/ridge/SGD)
lazyqsar.base.randomforest Random Forest classifier with zero-shot hyperparameter selection

Ersilia Model Hub integration

LazyQSAR models can be used inside an Ersilia Model Hub template. See eos1lb5 for an example.

Basically, lazyqsar fit can be used to produce a checkpoints folder with one sub-directory per task and per descriptor type:

checkpoints/
└── task1/
    ├── cddd/
    │   ├── featurizer.json
    │   ├── metadata.json
    │   └── batch_0/
    │       ├── preprocessor.onnx
    │       ├── xgboost.onnx
    │       └── pooler.json
    ├── chemeleon/   (same structure)
    ├── clamp/       (same structure)
    ├── morgan/      (same structure)
    └── rdkit/       (same structure)

The, the code/main.py inference script:

import os, sys
from lazyqsar.api.classifier_predict import predict

root = os.path.dirname(os.path.abspath(__file__))
checkpoints_dir = os.path.abspath(os.path.join(root, "..", "checkpoints"))
predict(model_dir=checkpoints_dir, input_csv=sys.argv[1], output_csv=sys.argv[2])

Roadmap

We are currently working on regression models, mirroring what has been done for classification.

Disclaimer

This library is intended for quick QSAR modeling. For a more complete automated QSAR pipeline, refer to ZairaChem.

ZairaChem's version, with an earlier version of LazyQSAR, was presented in this article:

@article{Turon2023,
  author = {Turon, G. and Hlozek, J. and Woodland, J.G. and et al.},
  title = {First fully-automated AI/ML virtual screening cascade implemented at a drug discovery centre in Africa},
  journal = {Nat Commun},
  volume = {14},
  pages = {5736},
  year = {2023},
  doi = {10.1038/s41467-023-41512-2},
  url = {https://doi.org/10.1038/s41467-023-41512-2}
}

About the Ersilia Open Source Initiative

The Ersilia Open Source Initiative is a tech non-profit organization with the mission to equip laboratories, universities, and clinics in the Global South with AI/ML tools for infectious disease research. We work on the principles of open science, decolonized research, and egalitarian access to knowledge and research outputs. You can support Ersilia by clicking here.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lazyqsar-3.0.1.tar.gz (144.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lazyqsar-3.0.1-py3-none-any.whl (174.5 kB view details)

Uploaded Python 3

File details

Details for the file lazyqsar-3.0.1.tar.gz.

File metadata

  • Download URL: lazyqsar-3.0.1.tar.gz
  • Upload date:
  • Size: 144.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.4 CPython/3.12.3 Linux/6.17.0-1011-azure

File hashes

Hashes for lazyqsar-3.0.1.tar.gz
Algorithm Hash digest
SHA256 a50d98174e4f6de5add10b2247d43c2566c712c3f37b5ad0f402ee157c4de840
MD5 5abf9d12df8be79c5bd14230402b9232
BLAKE2b-256 3373ce1a38520cf281927530882a2297c764ae2b5bb95e524953c7d865b2f97e

See more details on using hashes here.

File details

Details for the file lazyqsar-3.0.1-py3-none-any.whl.

File metadata

  • Download URL: lazyqsar-3.0.1-py3-none-any.whl
  • Upload date:
  • Size: 174.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.4 CPython/3.12.3 Linux/6.17.0-1011-azure

File hashes

Hashes for lazyqsar-3.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 39ca430f98c0008856c6adf22fd6f00e3c77f142d0bc631d7d5cd3f4361d28b3
MD5 ea1b03b23b2f278824f6a0266b39ec02
BLAKE2b-256 85443e36ed51f6dd169653557ae4bd97ae740348845e8389e942c8e065838c5e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page