Skip to main content
Docs

Search guides and API endpoints, for example “Idempotency-Key” or “submit job”.

    Tools · Custom Modeling

    QSAR Models

    Train classical QSAR models on your data, compare random forest, LightGBM, Gaussian process and other algorithms by cross-validation, and keep the best.

    Updated October 10, 2026

    On this page

    Prices, workflows, and method papersOpen in the app

    QSAR Models trains a panel of classical models on molecular fingerprints and descriptors, compares them under one split by cross-validation, and saves the best one as a model you can predict with. You get the winner and an honest comparison: how every algorithm did in cross-validation and on a held-out test set. At the dataset sizes most projects have (tens to a few thousand compounds), these models are often as accurate as graph neural networks and train in seconds.

    The panel

    AlgorithmWhat it is
    Ridge / logistic regressionA linear model on standardized features
    Random forestAn ensemble of decision trees
    LightGBMGradient-boosted trees
    SVMA support vector machine with an RBF kernel
    kNN (Tanimoto)A similarity-weighted average of the nearest training molecules
    Gaussian process (Tanimoto)A probabilistic model with calibrated uncertainty (regression, up to 5,000 molecules)

    Untick any you do not need. Each algorithm tries a small fixed set of settings, so run time stays predictable.

    How the best model is chosen

    1. A test set is held out first (random, scaffold or cluster split, or your own train / val / test labels). Scaffold and cluster splits keep related molecules together, so the test set measures prediction on new chemotypes.
    2. Each algorithm is scored by k-fold cross-validation on the rest (5 folds by default; scaffold and cluster groups stay within one fold).
    3. The algorithm with the best cross-validated metric (RMSE by default for regression, ROC AUC for classification) is refitted on all non-test molecules and saved.
    4. Every algorithm is also refitted once and scored on the test set, alongside mean and nearest-neighbour baselines, so the comparison shows whether the winner really learned something.

    Features

    Morgan count fingerprints (radius and size are configurable), RDKit 2D descriptors, MACCS keys and PaDEL descriptors, alone or combined. The kNN and Gaussian process models always use Tanimoto similarity on Morgan counts.

    Predictions

    Each prediction comes with:

    • a 90% prediction interval (regression; split-conformal, from cross-validation errors), and a standard deviation from the Gaussian process, random forest or kNN models;
    • the similarity of the molecule to its nearest training molecule, so you can tell when a prediction is outside the model's experience;
    • signed atom attributions for linear, random forest and LightGBM models on Morgan features: atoms that raise the prediction and atoms that lower it, from SHAP values.

    Binary models predict the probability of the positive class. Train a binary model from 0 / 1 labels, or from values with a threshold (for example p_activity ≥ 6).

    Inputs

    SMILES with one value each, or a table such as a Bioactivity Dataset Curator curated table, including its split column. Up to 10,000 molecules.

    Outputs

    FileContents
    comparison.csvEvery algorithm's metric on every fold and on the test set
    test_predictions.csvObserved values and each algorithm's test-set predictions (for parity and ROC plots)
    feature_importance.csvThe saved model's most influential features
    model/The saved model, with its model card (no pickled code)

    The saved model appears in My Models and can score whole libraries in a workflow with Saved Model Scoring.

    Curate the data first with Bioactivity Dataset Curator, or train a message-passing network on the same data with MPNN Models.

    Run it from the API

    Submit with Submit a job and the job_type below. Price it first with Estimate job reservation cost: submitting reserves that amount from your wallet, and the charge settles at the actual runtime.

    QSAR Model Training train-qsar

    Job type
    train-qsar
    Hardware
    cpu (default)
    Typical runtime
    15 min on CPU

    Payload

    Payload fields
    FieldTypeDescription
    model_namerequiredstring

    Limits: min length 1

    input_data[]string[]

    Limits: min items 1, max items 10000

    input_formatstring

    Default: "smiles"One of: "smiles"

    targets[]number[]

    Limits: min items 1, max items 10000

    splits[]string[]

    One of: "train", "training", "val", "valid", "validation", "test"Limits: min items 1

    activity_tablestring | object[] | artifactRef
    smiles_columnstring

    Default: "smiles"Limits: min length 1

    target_columnstring

    Default: "p_activity"Limits: min length 1

    split_columnstring

    Limits: min length 1

    endpointstring

    Limits: min length 1

    include_censoredboolean

    Default: false

    training_data_sources[]object[]

    Limits: max items 1

    training_data_sources.sourcerequired"chembl"
    training_data_sources.releasestring | null
    taskstring

    Default: "regression"One of: "regression", "binary"

    binary_thresholdnumber
    features[]string[]

    Default: ["morgan_counts"]One of: "morgan_counts", "rdkit2d", "maccs", "padel"Limits: min items 1

    morgan_radiusinteger

    Default: 2One of: 1, 2, 3, 4

    morgan_bitsinteger

    Default: 2048One of: 512, 1024, 2048, 4096

    algorithms[]string[]

    One of: "linear", "random_forest", "lightgbm", "svm", "knn", "gp"Limits: min items 1

    selection_metricstring

    One of: "rmse", "mae", "r2", "roc_auc", "pr_auc", "balanced_accuracy", "mcc"

    cv_foldsinteger

    Default: 5Limits: ≥ 3, ≤ 10

    split_methodstring

    One of: "random", "scaffold", "cluster", "provided"

    test_sizenumber

    Default: 0.1Limits: ≥ 0, ≤ 0.5

    random_seedinteger

    Limits: ≥ 0

    unitstring
    model_descriptionstring
    tags[]string[]

    Example

    from cognichem_client import CogniChem
    
    client = CogniChem.from_env()  # reads COGNICHEM_API_KEY
    payload = {
        "model_name": "mr38-qsar-tiny",
        "input_data": ["CCO", "CCCO", "CCCCO", "CCCCCO", "CC(C)O", "… 35 more"],
        "input_format": "smiles",
        "targets": [-0.001, 0.389, 0.779, 1.169, 0.387, "… 35 more"],
        "unit": "log units",
        "task": "regression",
        "features": ["morgan_counts", "maccs"],
        "morgan_bits": 512,
        "cv_folds": 3,
        "test_size": 0.2,
        "random_seed": 7,
        "split_method": "random",
    }
    
    estimate = client.jobs.estimate(job_type="train-qsar", payload=payload, resource="cpu")
    print(f"Reserves ${estimate.cost:.2f}")
    
    job = client.jobs.submit(
        job_name="my-train-qsar-run",
        job_type="train-qsar",
        payload=payload,
        resource="cpu",
    )
    status = client.jobs.wait(job.process_id)
    if status.status == "completed":
        client.jobs.result(job.process_id, save_path=".")

    Sample data from the job catalog; long values are shortened here. Each job_name must be unique among your jobs.

    Workflow inputs

    • Table (list) · optionalCSV, TSV, JSON
    • Molecules (list) · optionalSMILES

    Workflow outputs

    • ArchiveZIP
    • TableCSV
    • Trained modelOPAQUE