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] Training dependencies (scikit-learn, XGBoost, scipy, ONNX conversion tools)
descriptors pip install -e .[descriptors] Built-in molecular descriptors (RDKit, FPSim2, deep-learning models)
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 CDDD, Chemeleon, CLAMP, Morgan, RDKit Most thorough
from lazyqsar.qsar import LazyClassifierQSAR

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

ranks = model.predict_rank(smiles_list=smiles_test)[:, 1]  # percentile rank vs training set

Other prediction methods include predict_proba, predict, predict_lift, and more — see docs/internals.md for the full list.

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]

For multi-endpoint prediction across multiple model directories, see Ersilia Model Hub integration.

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 [--models_txt FILE] [--predict_type TYPE]

The output CSV contains one column per task, ordered alphabetically by task name, or filtered and ordered by --models_txt at predict time. --predict_type controls the output format: proba (default), rank, logit, lift, score, or binary.

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.

The full pipeline is exported to ONNX, so inference requires only numpy and onnxruntime.

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
lazyqsar.base.svc Support Vector Classifier with automatic kernel and C 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 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], predict_type="rank")

This function computes descriptors once per descriptor type and reuses them across all tasks, making it suitable for scoring large compound libraries. predict_type controls the output format and is available in both the Python API and the CLI (--predict_type).

model_dir also accepts a dict[str, str] mapping column names to model directories, for scoring multiple targets stored under separate paths — see docs/internals.md for details.

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.2.1.tar.gz (145.7 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.2.1-py3-none-any.whl (176.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: lazyqsar-3.2.1.tar.gz
  • Upload date:
  • Size: 145.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.12.3 Linux/6.17.0-1010-azure

File hashes

Hashes for lazyqsar-3.2.1.tar.gz
Algorithm Hash digest
SHA256 f803d114f464ff30f98a2edde6205be140d52773daf68a6ad17e46870f8056eb
MD5 501568711560b4e591732f5e0919eac4
BLAKE2b-256 69a933244099c75391b1b17c8e2ef51e238024952142e94d2480936568c97f63

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for lazyqsar-3.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 83f466f9a9588cac33ade8206fbd4c508a28c57ab56c328edf547c9871788ce4
MD5 d55232ac93ef1c78d4d3adc1b89c22c9
BLAKE2b-256 e5ef480cbc87acc928926cd4591950f49eee0e197ee3594c8919a734adb8f5a4

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