Tutorial

Predicting Drug-Target Binding Affinity with DeepPurpose

Difficulty: Intermediate Time: 15 min read

Introduction

In early-stage drug discovery, predicting how tightly a small molecule (drug) binds to a target protein is a critical step. DeepPurpose is a deep learning library that rapidly predicts Drug-Target Interaction (DTI) and Binding Affinity without requiring complex 3D docking simulations. It uses 1D sequences: SMILES strings for drugs, and amino acid sequences for proteins.

Architecture Overview


graph LR
    SMILES(Drug SMILES String) --> MPNN(Message Passing Neural Network)
    FASTA(Target FASTA Sequence) --> CNN(1D Convolutional Neural Network)
    
    MPNN --> DrugEmbed(Drug Embedding)
    CNN --> TargetEmbed(Target Embedding)
    
    DrugEmbed --> Concat(Concatenate Embeddings)
    TargetEmbed --> Concat
    
    Concat --> FFN(Feed Forward Network)
    FFN --> Kd(Predicted Binding Affinity - Kd)
        

Prerequisites

  • Python 3.8+
  • DeepPurpose, PyTorch, RDKit
  • Basic knowledge of SMILES and FASTA formats

Step 1: Install Dependencies

conda create -n deeppurpose python=3.8
conda activate deeppurpose
conda install -c conda-forge rdkit
pip install DeepPurpose

Step 2: Load and Encode Data

DeepPurpose includes built-in datasets like DAVIS, KIBA, and BindingDB. It provides multiple ways to encode drugs (e.g., Morgan fingerprints, Message Passing Neural Networks) and proteins (e.g., CNNs on amino acids, Transformer embeddings).

from DeepPurpose import utils, models, dataset

# Load the DAVIS dataset (contains SMILES, Target Sequences, and binding affinities in Kd)
X_drugs, X_targets, y = dataset.load_process_DAVIS(path='./data', binary=False, convert_to_log=True, threshold=30)

# We will use an MPNN for the drug and a CNN for the protein
drug_encoding = 'MPNN'
target_encoding = 'CNN'

# Encode the dataset and split into train, validation, and test sets
train, val, test = utils.data_process(X_drugs, X_targets, y, 
                                      drug_encoding, target_encoding, 
                                      split_method='random', frac=[0.7, 0.1, 0.2],
                                      random_seed=1)

Step 3: Define and Train the Model

Next, we configure the neural network architecture and train it.

# Generate default model configuration based on chosen encodings
config = utils.generate_config(drug_encoding=drug_encoding, 
                               target_encoding=target_encoding, 
                               cls_hidden_dims=[1024, 1024, 512], 
                               train_epoch=50, 
                               LR=0.001, 
                               batch_size=128,
                               hidden_dim_drug=128,
                               mpnn_hidden_size=128,
                               mpnn_depth=3, 
                               cnn_target_filters=[32,64,96],
                               cnn_target_kernels=[4,8,12])

# Initialize the model
model = models.model_initialize(**config)

# Train the model
model.train(train, val, test)

Step 4: Predicting Affinities for New Drugs using PubChem

Once trained, you can feed the model a list of novel SMILES strings against a specific protein target. Instead of manually finding SMILES, we can use the pubchempy library to dynamically fetch the SMILES string for a known drug (e.g., Imatinib) and test it against our target.

pip install pubchempy
import pubchempy as pcp

# Fetch SMILES string for a known drug (Imatinib)
compound = pcp.get_compounds('Imatinib', 'name')[0]
imatinib_smiles = compound.isomeric_smiles
print(f"Imatinib SMILES: {imatinib_smiles}")

# Target FASTA sequence (e.g., ABL1 kinase)
novel_target = ['MLEICLKLVGCKSKKGLSSSSSCYLEEALQRPVASDFEPQGLSEAARWNSKENLLAGPSENDPNLFVALYDFVASGDNTLSITKGEKLRVLGYNHNGEWCEAQTKNGQGWVPSNYITPVNSLEKHSWYHGPVSRNAAEYLLSSGINGSFLVRESESSPGQRSISLRYEGRVYHYRINTASDGKLYVSSESRFNTLAELVHHHSTVADGLITTLHYPAPKRNKPTVYGVSPNYDKWEMERTDITMKHKLGGGQYGEVYEGVWKKYSLTVAVKTLKEDTMEVEEFLKEAAVMKEIKHPNLVQLLGVCTREPPFYIITEFMTYGNLLDYLRECNRQEVNAVVLLYMATQISSAMEYLEKKNFIHRDLAARNCLVGENHLVKVADFGLSRLMTGDTYTAHAGAKFPIKWTAPESLAYNKFSIKSDVWAFGVLLWEIATYGMSPYPGIDLSQVYELLEKDYRMERPEGCPEKVYELMRACWQWNPSDRPSFAEIHQAFETMFQESSISDEVEKELGKQGVRGAVSTLLQAPELPTKTRTSRRAAEHRDTTDVPEMPHSKGQGESDPLDHEPAVSPLLPRKERGPPEGGLNEDERLLPKDKKTNLFSALIKKKKKTAPTPPKRSSSFREMDGQPERRGAGEEEGRDISNGALAFTPLDTADPAKSPKPSNGAGVPNGALRESGGSGIRGDLRQREKSSSRSKRPRNTEQRRKSRRSEEPVPGPGQGPRGGEDGDLSSPGQRAGGGGGSGGGGGTGGGGTGGGGGGGGG']

# Encode the new data
X_pred = utils.data_process(X_drug=[imatinib_smiles], X_target=novel_target, y=[0],
                            drug_encoding=drug_encoding, target_encoding=target_encoding, 
                            split_method='no_split')

# Run prediction
predicted_affinity = model.predict(X_pred)
print(f"Predicted Binding Affinity (Kd): {predicted_affinity}")

Conclusion

DeepPurpose abstracts away the complexity of building custom PyTorch models for DTI. By allowing you to rapidly mix and match state-of-the-art encoders (MPNNs, Transformers), and dynamically hooking into databases like PubChem, it accelerates the virtual screening phase of drug discovery by orders of magnitude.