Skip to main content

Molecular Applicability Domain — check whether predictions are trustworthy using SHAP-based fingerprint similarity

Project description

moldom — Molecular Applicability Domain

PyPI version Python 3.8+ License: MIT

Check whether molecular predictions are trustworthy using SHAP-based fingerprint similarity.

When a QSAR/ML model makes a prediction on a new molecule, moldom answers:

"Is this molecule similar enough to the training set for the prediction to be reliable?"

It uses two complementary fingerprint similarity metrics derived from SHAP feature importance:

Metric Reference fingerprint Meaning
Dice bits with non-zero SHAP Structural coverage
Tanimoto bits selected by shap_direction Target-relevant feature match

Installation

pip install moldom

Requires RDKit. If you don't have it:

conda install -c conda-forge rdkit
# or
pip install rdkit

Quick Start

from moldom import check_ad

result = check_ad(
    query_smiles=["CCO", "c1ccccc1", "CC(=O)Oc1ccccc1C(=O)O"],
    shap="shap_features.csv",       # CSV with SHAP values, one per fingerprint bit
    train_smiles="train.csv",        # training set CSV (must have a 'SMILES' column)
)

print(result)
#                                SMILES      Dice  Tanimoto  in_AD  valid
# 0                                 CCO  0.412     0.318    True   True
# 1                           c1ccccc1  0.287     0.201   False   True
# 2  CC(=O)Oc1ccccc1C(=O)O             0.531     0.445    True   True

# Filter to in-domain molecules only
reliable = result[result.in_AD]

API Reference

check_ad()

from moldom import check_ad

result = check_ad(
    query_smiles,           # str or list of SMILES to evaluate
    shap,                   # SHAP values: CSV path, array, DataFrame, or Series
    train_smiles,           # training SMILES: list or CSV path
    train_target=None,      # training target values (optional, for tanimoto filtering)

    # ── fingerprint ──────────────────────────────────────────────────────────
    radius=2,               # Morgan fingerprint radius

    # ── SHAP direction ───────────────────────────────────────────────────────
    shap_direction="positive",  # see below

    # ── threshold method ─────────────────────────────────────────────────────
    # Choose 'percentile', 'mean_std', or 'fixed' for each metric
    dice_method="percentile",
    tanimoto_method="mean_std",

    # percentile settings (used when method='percentile')
    dice_percentile=15.0,
    tanimoto_percentile=15.0,

    # mean-std settings (used when method='mean_std')
    dice_n_std=1.0,
    tanimoto_n_std=1.0,

    # fixed settings (used when method='fixed')
    dice_fixed=None,
    tanimoto_fixed=None,

    # ── target filtering for tanimoto baseline ───────────────────────────────
    target_col=None,             # column name if train_smiles is a CSV
    target_threshold=None,       # e.g. 0.2 — exclude low-activity molecules
    target_exclude_below=True,   # True = exclude molecules below threshold

    # ── output ───────────────────────────────────────────────────────────────
    return_scores=True,     # include Dice and Tanimoto columns in output
    n_jobs=1,               # parallel workers (>1 uses multiprocessing)
)

Returns: pd.DataFrame with columns SMILES, Dice, Tanimoto, in_AD, valid

The DataFrame also carries .attrs["dice_threshold"] and .attrs["tanimoto_threshold"] so you can inspect the calibrated cutoffs.


SHAP Direction

shap_direction controls which bits are used to build the Tanimoto reference fingerprint. Choose based on what "good" means for your prediction target:

Value Bits used When to use
"positive" (default) SHAP > 0 Target should be high (e.g. solubility, activity)
"negative" SHAP < 0 Target should be low (e.g. toxicity, side effects)
"both" SHAP ≠ 0 Direction doesn't matter / pure structural AD
# Predicting CO₂ solubility — higher is better
check_ad(..., shap_direction="positive")

# Predicting toxicity — lower is better
check_ad(..., shap_direction="negative")

# Just structural coverage, ignore direction
check_ad(..., shap_direction="both")

get_thresholds()

Calibrate and inspect thresholds without screening any molecules:

from moldom import get_thresholds

thresholds = get_thresholds(
    shap="shap_features.csv",
    train_smiles="train.csv",
    shap_direction="positive",
    dice_method="percentile",
    tanimoto_method="mean_std",
)
# {'dice_threshold': 0.341, 'tanimoto_threshold': 0.178}

SHAP Input Formats

check_ad is flexible about how you provide SHAP values:

# CSV file (column named 'Mean_SHAP_Value', 'shap', 'value', or last column)
check_ad(..., shap="shap_features.csv")

# numpy array
check_ad(..., shap=np.array([0.01, 0.0, -0.03, ...]))

# pandas Series
check_ad(..., shap=shap_series)

# single-column DataFrame
check_ad(..., shap=shap_df)

Threshold Methods

Method Description Key parameter
"percentile" Lower percentile of training similarities dice_percentile / tanimoto_percentile
"mean_std" mean - n * std of training similarities dice_n_std / tanimoto_n_std
"fixed" User-specified constant dice_fixed / tanimoto_fixed

You can mix methods: e.g., dice_method="percentile" and tanimoto_method="fixed".


Replicating the Original CO₂ Script

from moldom import check_ad

result = check_ad(
    query_smiles=il_df["IL_smile"].tolist(),
    shap="shap_feature_co2.csv",
    train_smiles="co2_train_clean.csv",
    train_target=train_df["co2"].tolist(),
    shap_direction="positive",       # high CO₂ solubility is desirable
    target_threshold=0.2,
    target_exclude_below=True,
    dice_method="percentile",
    dice_percentile=15.0,
    tanimoto_method="percentile",
    tanimoto_percentile=15.0,
    n_jobs=24,
)

License

MIT

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

moldom-0.1.1.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

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

moldom-0.1.1-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file moldom-0.1.1.tar.gz.

File metadata

  • Download URL: moldom-0.1.1.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.12

File hashes

Hashes for moldom-0.1.1.tar.gz
Algorithm Hash digest
SHA256 54561425a9711018c50045e4e13f0a96b8b9bfc90c89b8679ef14dbcd2b58c4e
MD5 33d929605dbb610f45b1d23d06a21387
BLAKE2b-256 b618f963086024f5d1bd4c0ede3e2c880f5baae57a4d31c4d33ba3bb557afb7e

See more details on using hashes here.

File details

Details for the file moldom-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: moldom-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.12

File hashes

Hashes for moldom-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 656d0a96310c26b4df3180aa1e57f87ee8ba056c4f6a68641d693aed39fc9d96
MD5 e159f57c3155341521e947c329b04c47
BLAKE2b-256 f04b5ca50e70332141eafd8ac7e33d894630eadbcb139cc0619906312a1d194f

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