agentsclimarketplace

Deepchem

Skill jaechang-hits/SciAgent-Skills/skills/structural-biology-drug-discovery/deepchem

Deep learning for drug discovery. 60+ models (GCN, GAT, AttentiveFP, MPNN, ChemBERTa, GROVER), 50+ featurizers, MoleculeNet benchmarks, HPO, transfer learning. Unified load-featurize-split-train-evaluate API. For fingerprints use rdkit-cheminformatics; for featurization-only use molfeat.From its SKILL.md

Install
npx -y skills add jaechang-hits/SciAgent-Skills --skill deepchem

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

22.9 KB, ~6.0k tokens by cl100k_base, as published. Nobody here has run it

DeepChem — Deep Learning for Drug Discovery

Overview

DeepChem is an open-source Python framework providing a unified API for molecular machine learning across drug discovery, materials science, and quantum chemistry. It wraps 60+ model architectures (graph neural networks, transformers, classical ML) with 50+ molecular featurizers and standardized datasets (MoleculeNet), enabling end-to-end workflows from SMILES strings to trained predictive models.

When to Use

  • Predicting molecular properties (solubility, toxicity, binding affinity) from SMILES
  • Benchmarking models on MoleculeNet standardized datasets (BBBP, Tox21, ESOL, FreeSolv, etc.)
  • Training graph neural networks on molecular graphs (GCN, GAT, AttentiveFP, MPNN, DMPNN)
  • Fine-tuning pretrained chemical language models (ChemBERTa, GROVER, MolFormer)
  • Running hyperparameter optimization for molecular ML models
  • Virtual screening and hit prioritization with trained models
  • Materials property prediction from crystal structures (CGCNN, MEGNet)
  • Protein-ligand interaction modeling and binding affinity prediction
  • For fingerprint-based cheminformatics without deep learning, use rdkit-cheminformatics instead
  • For featurization only (no model training), use molfeat-molecular-featurization instead

Prerequisites

  • Python packages: deepchem (core), torch or tensorflow (backend-dependent models)
  • GPU: Recommended for graph neural networks and transformer models; CPU sufficient for classical ML and fingerprint models
  • Data: SMILES strings with property labels (CSV), or MoleculeNet datasets (auto-downloaded)
# Core installation (includes RDKit, scikit-learn, XGBoost)
pip install deepchem

# With PyTorch backend (GNN models)
pip install deepchem[torch]

# With TensorFlow backend (legacy models)
pip install deepchem[tensorflow]

# Full installation (all backends + extras)
pip install deepchem[all]

Quick Start

import deepchem as dc

# Load MoleculeNet dataset with featurization + scaffold split
tasks, datasets, transformers = dc.molnet.load_delaney(featurizer="ECFP")
train, valid, test = datasets

# Train and evaluate a multitask regressor
model = dc.models.MultitaskRegressor(n_tasks=1, n_features=1024, dropouts=0.2)
model.fit(train, nb_epoch=50)
metric = dc.metrics.Metric(dc.metrics.pearson_r2_score)
print(f"Test R2: {model.evaluate(test, [metric])}")  # {'pearson_r2_score': ~0.7}

Core API

Module 1: Data Loading and Processing

Load molecular data from CSV files or MoleculeNet benchmark datasets.

import deepchem as dc

# Load from CSV (SMILES + property columns)
loader = dc.data.CSVLoader(
    tasks=["measured_log_solubility"],
    feature_field="smiles",
    featurizer=dc.feat.CircularFingerprint(size=2048, radius=3)
)
dataset = loader.create_dataset("solubility_data.csv")
print(f"Samples: {dataset.X.shape[0]}, Features: {dataset.X.shape[1]}")
# Samples: 1128, Features: 2048

# Load from SDF (3D structures)
sdf_loader = dc.data.SDFLoader(
    tasks=["activity"],
    featurizer=dc.feat.CoulombMatrix(max_atoms=50)
)
dataset_3d = sdf_loader.create_dataset("molecules.sdf")
# Load MoleculeNet benchmark datasets (auto-download + featurize + split)
# Available: load_delaney, load_bbbp, load_tox21, load_hiv, load_qm7, load_qm9, etc.
tasks, datasets, transformers = dc.molnet.load_tox21(featurizer="ECFP", splitter="scaffold")
train, valid, test = datasets
print(f"Tasks: {len(tasks)}, Train: {len(train)}, Test: {len(test)}")
# Tasks: 12, Train: ~6264, Test: ~631

# Inverse-transform predictions back to original scale
y_pred = model.predict(test)
y_original = transformers[0].untransform(y_pred)

Module 2: Molecular Featurization

Convert molecules to numerical representations for ML. DeepChem provides 50+ featurizers spanning fingerprints, descriptors, graph features, and Coulomb matrices.

import deepchem as dc

smiles = ["CCO", "CC(=O)O", "c1ccccc1", "CC(C)O"]

# Fingerprints (most common for classical ML)
ecfp = dc.feat.CircularFingerprint(size=2048, radius=3)
fp_features = ecfp.featurize(smiles)
print(f"ECFP shape: {fp_features.shape}")  # (4, 2048)

# RDKit descriptors (interpretable physicochemical properties)
rdkit_desc = dc.feat.RDKitDescriptors()
desc_features = rdkit_desc.featurize(smiles)
print(f"Descriptor shape: {desc_features.shape}")  # (4, 208)

# Graph features (for GNN models — returns ConvMol objects)
graph_feat = dc.feat.ConvMolFeaturizer()
graphs = graph_feat.featurize(smiles)
print(f"Atoms in first mol: {graphs[0].get_num_atoms()}")  # 3

# Mol2Vec embeddings (pretrained word2vec on molecular substructures)
mol2vec = dc.feat.Mol2VecFingerprint()
embeddings = mol2vec.featurize(smiles)
print(f"Mol2Vec shape: {embeddings.shape}")  # (4, 300)

Module 3: Model Training and Evaluation

DeepChem provides MultitaskRegressor and MultitaskClassifier as general-purpose models, plus specialized architectures for graph and sequence data.

import deepchem as dc

# Load dataset
tasks, datasets, transformers = dc.molnet.load_delaney(featurizer="ECFP")
train, valid, test = datasets

# Regression model (fingerprint input)
model = dc.models.MultitaskRegressor(
    n_tasks=1,
    n_features=1024,
    layer_sizes=[1000, 500],
    dropouts=0.25,
    learning_rate=0.001,
    batch_size=64,
)
model.fit(train, nb_epoch=100)

# Evaluate with multiple metrics
metrics = [
    dc.metrics.Metric(dc.metrics.pearson_r2_score),
    dc.metrics.Metric(dc.metrics.mean_absolute_error),
    dc.metrics.Metric(dc.metrics.rms_score),
]
results = model.evaluate(test, metrics)
print(f"R2: {results['pearson_r2_score']:.3f}, MAE: {results['mean_absolute_error']:.3f}")
# Classification model (e.g., Tox21 toxicity prediction)
tasks, datasets, transformers = dc.molnet.load_tox21(featurizer="ECFP")
train, valid, test = datasets

clf = dc.models.MultitaskClassifier(
    n_tasks=len(tasks),
    n_features=1024,
    layer_sizes=[1000, 500],
    dropouts=0.5,
    learning_rate=0.001,
)
clf.fit(train, nb_epoch=50)
roc_metric = dc.metrics.Metric(dc.metrics.roc_auc_score, np.mean)
print(f"Mean ROC-AUC: {clf.evaluate(test, [roc_metric])}")

Module 4: Graph Neural Networks

GNNs operate directly on molecular graphs (atoms as nodes, bonds as edges), avoiding information loss from fixed fingerprints.

import deepchem as dc

# Load with graph featurizer
tasks, datasets, transformers = dc.molnet.load_delaney(featurizer="GraphConv")
train, valid, test = datasets

# Graph Convolutional Network (Duvenaud et al.)
gcn_model = dc.models.GraphConvModel(
    n_tasks=1,
    mode="regression",
    graph_conv_layers=[64, 64],
    dense_layer_size=256,
    dropout=0.2,
    learning_rate=0.001,
    batch_size=64,
)
gcn_model.fit(train, nb_epoch=100)
metric = dc.metrics.Metric(dc.metrics.pearson_r2_score)
print(f"GCN R2: {gcn_model.evaluate(test, [metric])}")
# AttentiveFP (Xiong et al.) — attention-based GNN, strong on molecular properties
tasks, datasets, transformers = dc.molnet.load_delaney(
    featurizer=dc.feat.MolGraphConvFeaturizer(use_edges=True)
)
train, valid, test = datasets

attfp_model = dc.models.AttentiveFPModel(
    n_tasks=1,
    mode="regression",
    num_layers=2,
    graph_feat_size=200,
    num_timesteps=2,
    dropout=0.2,
    learning_rate=0.001,
    batch_size=64,
)
attfp_model.fit(train, nb_epoch=100)
print(f"AttentiveFP R2: {attfp_model.evaluate(test, [metric])}")

Module 5: Transfer Learning

Fine-tune pretrained chemical language models for downstream tasks with limited data.

import deepchem as dc
from deepchem.models.torch_models import ChemBERTaModel

# ChemBERTa — SMILES-based transformer (pretrained on 77M molecules)
tasks, datasets, transformers = dc.molnet.load_bbbp(featurizer=dc.feat.SmilesTokenizer())
train, valid, test = datasets

chemberta = ChemBERTaModel(
    task="classification",
    n_tasks=1,
    model_dir="chemberta_finetuned/",
)
# Fine-tune on downstream task (BBB permeability)
chemberta.fit(train, nb_epoch=10)
metric = dc.metrics.Metric(dc.metrics.roc_auc_score)
print(f"ChemBERTa ROC-AUC: {chemberta.evaluate(test, [metric])}")

Module 6: Predictions on New Molecules

Run inference on new molecules with a trained model.

import deepchem as dc
import numpy as np

# Assume trained model from Module 3
# Featurize new molecules using same featurizer
featurizer = dc.feat.CircularFingerprint(size=1024, radius=2)
new_smiles = ["c1cc(O)ccc1", "CC(=O)Nc1ccc(O)cc1", "OC(=O)c1ccccc1"]
new_features = featurizer.featurize(new_smiles)
new_dataset = dc.data.NumpyDataset(X=new_features)

predictions = model.predict(new_dataset)
for smi, pred in zip(new_smiles, predictions):
    print(f"{smi}: {pred[0]:.2f}")

# Ensemble predictions from multiple models for robustness
models = [model1, model2, model3]  # trained models
all_preds = np.array([m.predict(new_dataset) for m in models])
ensemble_mean = all_preds.mean(axis=0)
ensemble_std = all_preds.std(axis=0)
print(f"Ensemble prediction: {ensemble_mean[0][0]:.2f} +/- {ensemble_std[0][0]:.2f}")

Key Concepts

Unified API Pattern

All DeepChem workflows follow a consistent 5-step pattern:

Load Data → Featurize → Split → Train → Evaluate
  • Load: CSVLoader, SDFLoader, or dc.molnet.load_*() (auto-loads MoleculeNet datasets)
  • Featurize: Pass featurizer to loader, or call featurizer.featurize(smiles) directly
  • Split: ScaffoldSplitter (recommended for drug discovery), RandomSplitter, ButinaSplitter
  • Train: model.fit(train_dataset, nb_epoch=N)
  • Evaluate: model.evaluate(test_dataset, metrics_list)

Model Selection Guide

Data TypeModelKey FeatureUse When
SMILES + fingerprintsMultitaskRegressorFast, baselineFirst attempt, small datasets
SMILES + fingerprintsMultitaskClassifierMulti-labelMulti-task classification (Tox21)
Molecular graphsGraphConvModelLearned fingerprintsMedium datasets, general properties
Molecular graphsGATModelAttention mechanismWhen atom importance matters
Molecular graphsAttentiveFPModelGraph + timestep attentionState-of-art molecular properties
Molecular graphsMPNNModelMessage passingComplex molecular interactions
Molecular graphsDMPNNModelDirected MPNNBond-level predictions
SMILES stringsChemBERTaModelPretrained transformerLow-data regime, transfer learning
SMILES stringsGROVERModelGraph + transformerRich molecular representations
Crystal structuresCGCNNModelCrystal graph CNNMaterials property prediction
Crystal structuresMEGNetModelGraph networksMaterials and molecules
Protein sequencesProteinLigandComplexModelComplex modelingBinding affinity prediction
Tabular featuresXGBoostModel, RandomForestModelClassical MLInterpretability, baselines

Featurizer Selection Guide

FeaturizerClassOutputBest For
ECFP/MorganCircularFingerprintBinary vector (1024-2048)General QSAR, fast baselines
MACCS KeysMACCSKeysFingerprint167-bit vectorSubstructure filtering
RDKit 2DRDKitDescriptors200+ descriptorsInterpretable models
Mol2VecMol2VecFingerprint300-dim embeddingSimilarity, clustering
ConvMolConvMolFeaturizerGraph featuresGraphConvModel input
MolGraphMolGraphConvFeaturizerNode + edge featuresAttentiveFPModel, MPNNModel
WeaveWeaveFeaturizerPair featuresWeaveModel input
Coulomb MatrixCoulombMatrixAtom-pair distancesQM property prediction
SMILES tokensSmilesTokenizerToken IDsChemBERTa, transformer models

Data Splitting Strategies

SplitterUse CaseWhy
ScaffoldSplitterDrug discovery (default)Tests generalization to new chemotypes
RandomSplitterQuick experimentsBaseline, but overestimates performance
ButinaSplitterDiversity-basedClusters by Tanimoto similarity
FingerprintSplitterChemical similarityGroups structurally similar molecules
MaxMinSplitterMaximum diversity testExtreme generalization test

Common Workflows

Workflow 1: QSAR from CSV Data

Goal: Build a property prediction model from a CSV file with SMILES and activity columns.

import deepchem as dc
import pandas as pd

# Step 1: Load and featurize CSV data
loader = dc.data.CSVLoader(
    tasks=["pIC50"],
    feature_field="smiles",
    featurizer=dc.feat.CircularFingerprint(size=2048, radius=3),
)
dataset = loader.create_dataset("bioactivity_data.csv")

# Step 2: Normalize targets
transformer = dc.trans.NormalizationTransformer(
    transform_y=True, dataset=dataset
)
dataset = transformer.transform(dataset)

# Step 3: Scaffold split (realistic for drug discovery)
splitter = dc.splits.ScaffoldSplitter()
train, valid, test = splitter.train_valid_test_split(dataset)
print(f"Train: {len(train)}, Valid: {len(valid)}, Test: {len(test)}")

# Step 4: Train model
model = dc.models.MultitaskRegressor(
    n_tasks=1, n_features=2048,
    layer_sizes=[1000, 500], dropouts=0.25,
    learning_rate=0.001, batch_size=64,
)
model.fit(train, nb_epoch=100)

# Step 5: Evaluate
metrics = [
    dc.metrics.Metric(dc.metrics.pearson_r2_score),
    dc.metrics.Metric(dc.metrics.mean_absolute_error),
]
results = model.evaluate(test, metrics)
print(f"R2: {results['pearson_r2_score']:.3f}, MAE: {results['mean_absolute_error']:.3f}")

Workflow 2: MoleculeNet Benchmark Comparison

Goal: Compare multiple models on a MoleculeNet benchmark dataset.

import deepchem as dc

# Load dataset with graph featurizer (supports both fingerprint and GNN models)
tasks, datasets, transformers = dc.molnet.load_bbbp(
    featurizer="GraphConv", splitter="scaffold"
)
train, valid, test = datasets
metric = dc.metrics.Metric(dc.metrics.roc_auc_score)

# Model 1: Graph Convolutional Network
gcn = dc.models.GraphConvModel(n_tasks=1, mode="classification", dropout=0.2)
gcn.fit(train, nb_epoch=50)
gcn_score = gcn.evaluate(test, [metric])

# Model 2: Random Forest baseline (needs fingerprints)
tasks_fp, datasets_fp, _ = dc.molnet.load_bbbp(featurizer="ECFP", splitter="scaffold")
train_fp, _, test_fp = datasets_fp
rf = dc.models.SklearnModel(
    model=dc.models.sklearn_models.RandomForestClassifier(n_estimators=500),
    model_dir="rf_model/"
)
rf.fit(train_fp)
rf_score = rf.evaluate(test_fp, [metric])

print(f"GCN ROC-AUC: {gcn_score['roc_auc_score']:.3f}")
print(f"RF  ROC-AUC: {rf_score['roc_auc_score']:.3f}")

Workflow 3: Transfer Learning Pipeline

Goal: Fine-tune a pretrained model on a small dataset.

  1. Load pretrained ChemBERTa model (see Module 5 for code)
  2. Prepare downstream dataset with SmilesTokenizer featurizer
  3. Fine-tune with reduced learning rate (1e-5 to 5e-5) for 5-15 epochs
  4. Evaluate on held-out scaffold split — expect gains over fingerprint baselines when training data < 1000 samples
  5. Save fine-tuned model: model.save_checkpoint()
  6. See references/workflows_model_catalog.md Workflow 1 for complete hyperparameter optimization code

Key Parameters

ParameterModuleDefaultRange / OptionsEffect
n_featuresMultitaskRegressor/ClassifierRequiredMatches featurizer outputInput feature dimension
layer_sizesMultitaskRegressor/Classifier[1000][256] to [1000, 500, 250]Hidden layer dimensions
dropoutsAll neural models0.00.0-0.5Regularization strength
learning_rateAll neural models0.0011e-5-0.01Training step size
batch_sizeAll neural models10016-256Samples per gradient update
nb_epochmodel.fit()1010-300Training iterations
sizeCircularFingerprint2048512-4096Fingerprint bit length
radiusCircularFingerprint22-4Substructure neighborhood radius
graph_conv_layersGraphConvModel[64, 64][32] to [128, 128, 64]Graph convolution widths
num_layersAttentiveFPModel21-5GNN message passing depth
graph_feat_sizeAttentiveFPModel20064-512Graph feature dimension
splitterdc.molnet.load_*()"scaffold""scaffold", "random", "butina"Data splitting strategy

Best Practices

  1. Always use scaffold splitting for drug discovery: Random splits leak structural information and overestimate performance. Scaffold splits test generalization to novel chemotypes.

  2. Normalize regression targets: Apply NormalizationTransformer(transform_y=True) before training. Remember to untransform() predictions for interpretable values.

  3. Start with fingerprint baselines: Train MultitaskRegressor + ECFP first. Only move to GNNs if fingerprint baseline is insufficient — GNNs need more data and compute.

    # Baseline first
    baseline = dc.models.MultitaskRegressor(n_tasks=1, n_features=2048)
    
  4. Match featurizer to model: GNN models require graph featurizers (ConvMolFeaturizer, MolGraphConvFeaturizer). Fingerprint models need CircularFingerprint. Mixing causes silent errors.

  5. Anti-pattern -- Do not use random split for drug discovery benchmarks: Results with RandomSplitter are not publishable for molecular property prediction. Reviewers expect scaffold or temporal splits.

  6. Handle missing labels in multi-task datasets: Tox21 and many bioactivity datasets have missing values. DeepChem handles NaN labels automatically during training (masked loss), but verify with np.isnan(dataset.y).sum().

  7. Use early stopping via validation set: Monitor validation loss to prevent overfitting, especially with GNN models.

Common Recipes

Recipe: Hyperparameter Search

When to use: Optimize model performance before final evaluation.

import deepchem as dc

tasks, datasets, transformers = dc.molnet.load_delaney(featurizer="ECFP")
train, valid, test = datasets

# Define parameter grid
params = {
    "n_features": [1024],
    "layer_sizes": [[500], [1000, 500], [1000, 500, 250]],
    "dropouts": [0.1, 0.25, 0.5],
    "learning_rate": [0.001, 0.0005],
}

optimizer = dc.hyper.GridHyperparamOpt(lambda **p: dc.models.MultitaskRegressor(**p))
metric = dc.metrics.Metric(dc.metrics.pearson_r2_score)
best_model, best_params, all_results = optimizer.hyperparam_search(
    params, train, valid, metric, logdir="hyperparam_logs/"
)
print(f"Best params: {best_params}")
print(f"Best R2: {best_model.evaluate(test, [metric])}")

Recipe: Save and Reload Models

When to use: Deploy trained models or resume training.

# Save model checkpoint
model.save_checkpoint(model_dir="saved_model/")

# Reload model
loaded_model = dc.models.MultitaskRegressor(n_tasks=1, n_features=2048)
loaded_model.restore(model_dir="saved_model/")
predictions = loaded_model.predict(test)

Recipe: Custom Metric

When to use: Evaluate models with domain-specific metrics.

import deepchem as dc
import numpy as np

def enrichment_factor(y_true, y_pred, top_fraction=0.01):
    """Enrichment factor at top X% of ranked predictions."""
    n = len(y_true)
    n_top = max(int(n * top_fraction), 1)
    top_indices = np.argsort(y_pred.flatten())[-n_top:]
    hits_in_top = y_true.flatten()[top_indices].sum()
    expected = y_true.sum() * top_fraction
    return hits_in_top / expected if expected > 0 else 0.0

ef_metric = dc.metrics.Metric(enrichment_factor, mode="regression")
print(f"EF@1%: {model.evaluate(test, [ef_metric])}")

Troubleshooting

ProblemCauseSolution
ModuleNotFoundError: torchPyTorch not installedpip install deepchem[torch] for GNN models
ValueError: n_features mismatchFeaturizer output size does not match model n_featuresCheck dataset.X.shape[1] and set n_features accordingly
NaN loss during trainingLearning rate too high or unnormalized targetsApply NormalizationTransformer, reduce learning rate to 1e-4
Low scaffold-split performanceModel memorizes scaffolds, not propertiesUse more data, try GNN models, or add regularization (dropout 0.3-0.5)
RuntimeError: CUDA out of memoryBatch size too large for GPUReduce batch_size (32 or 16), or use CPU for small datasets
FeaturizationError on some SMILESInvalid or complex SMILES stringsPre-filter with RDKit: Chem.MolFromSmiles(smi) is not None
Model predicts constant valuesTargets not normalized or too few epochsApply NormalizationTransformer, increase nb_epoch
Slow featurizationLarge dataset with expensive featurizerUse CircularFingerprint (fast) or parallelize with n_jobs parameter

Bundled Resources

  • references/workflows_model_catalog.md -- Extended workflows (hyperparameter optimization with full code, MolGAN generative models, materials property prediction with CGCNN/MEGNet, protein-ligand modeling, custom model architecture) plus complete model catalog (60+ models organized by category) and complete featurizer catalog (50+ featurizers). Covers: workflows 4-8 from original, extended model and featurizer inventories, MoleculeNet dataset catalog. Relocated inline: top 3 workflows (QSAR, MoleculeNet benchmark, transfer learning) are in Common Workflows; core model/featurizer tables are in Key Concepts. Omitted: detailed installation troubleshooting for TensorFlow 1.x (deprecated) and Docker-specific setup (covered by official docs).

Related Skills

  • rdkit-cheminformatics -- molecular manipulation, fingerprints, substructure search (upstream featurization)
  • molfeat-molecular-featurization -- 100+ featurizers with scikit-learn API (featurization-only alternative)
  • datamol-cheminformatics -- Pythonic molecular processing (upstream data prep)
  • pytdc-therapeutics-data-commons -- curated ADMET/DTI datasets with standardized splits (complementary data source)
  • torch-geometric-graph-neural-networks -- lower-level PyG for custom GNN architectures (alternative for advanced users)
  • scikit-learn-machine-learning -- classical ML baselines that DeepChem wraps via SklearnModel

References

What ships with it: 1 file

16.2 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.