Machine-learning classifiers that separate active from inactive 3C-like proteinase inhibitors, trained on experimental ChEMBL data.
Every dot is a molecule placed by its measured IC50. Lower means it blocks the enzyme at a smaller dose. Drag the two lines, or use the sliders, and watch the labels, and the class balance, change. This is the labelling step of the project.
The 3C-like protease (3CLpro) is the enzyme SARS-CoV-2 uses to cut its long protein chain into working parts. Block it and the virus cannot replicate, which makes it a major drug target.
Screening every candidate in the lab is slow and costly. A model that scores molecules as likely active or inactive helps choose which ones deserve bench time.
An end-to-end cheminformatics workflow: it pulls measured IC50 values from ChEMBL, turns each molecule into a fingerprint, trains three classifiers and compares them side by side.
The results are explorable in a Streamlit app, and the whole analysis is in a notebook you can run.
Each molecule is tested at a range of concentrations and the enzyme's remaining activity is measured. Fitting a dose-response curve gives the concentration that halves the activity, the IC50. Change the potency and the steepness of the curve, and the label it earns follows the cutoffs you set in the first plot.
Hill equation inhibition % = 100 / (1 + 10^((logIC50 − logC) × slope))
Query ChEMBL Web Services for 3CLpro bioactivity records and extract measured IC50 values.
records = new_client.activity.filter(
target_chembl_id=TARGET_ID, standard_type="IC50")
raw = pd.DataFrame(list(records))Keep exact nM measurements, average duplicates, then label by IC50 cutoff, as in the interactive plot above.
df = df[(df.ic50_nM <= ACTIVE_NM) | (df.ic50_nM >= INACTIVE_NM)] df["active"] = (df.ic50_nM <= ACTIVE_NM).astype(int)
Turn every molecule into a fixed-length Morgan fingerprint with RDKit.
gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) X = gen.GetFingerprintAsNumPy(Chem.MolFromSmiles(smiles))
Fit Random Forest, XGBoost and LightGBM on a stratified train and test split.
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2, stratify=y)
for name, model in models.items():
model.fit(Xtr, ytr)Compare AUC-ROC, F1-score and complementary metrics to check discrimination across both classes.
p = model.predict_proba(Xte)[:, 1] roc_auc_score(yte, p), f1_score(yte, p >= 0.5)
Use Seaborn plots and a Streamlit app to inspect molecular features, predictions and classifier performance.
Do potent molecules look different from weak ones? These are standard drug-likeness descriptors computed with RDKit for the curated molecules, split by the cutoffs you set at the top of the page. Move those cutoffs and every panel here updates.
Morgan fingerprints describe each atom by the neighbourhood around it. Radius 0 is the atom alone, and each step outward adds the atoms one bond further away. Every neighbourhood is hashed into a bit position, so a whole molecule becomes a fixed-length row of 0s and 1s. These are real compounds from the dataset, fingerprinted with RDKit.
The Tanimoto score is the share of set bits two molecules have in common, and it is one way to ask how alike two compounds are. The table lists real compounds from the dataset, picked to be structurally diverse. Select a cell in the heat map to compare a pair.
Highest and lowest values are off-diagonal pairs — the diagonal is each molecule against itself (1.00). Select any map cell or any row of the pair table to compare that pair below.
Fingerprints place every molecule in a space with thousands of dimensions. Projecting that space onto two dimensions shows families of related molecules (clusters found with k-means) and where actives sit. Colour by label, potency or cluster, then select a molecule to see its five most similar neighbours.
Select a point on the map.
All curated measurements in one searchable table. Filter by ChEMBL ID or SMILES fragment, by label at your current cutoffs, or by IC50 range. Click a ChEMBL ID to open its assay record. Everything here is real data.
Paste a full SMILES for an exact match, or any fragment of a SMILES or ChEMBL ID. Exact matches show the measured IC50, the label at your cutoffs, molecular weight, LogP and a link to ChEMBL.
Type above to search the 3425 curated molecules.
A model outputs a probability, and a threshold turns it into active or inactive. Drag the line through the score distributions and every panel responds: the ROC and precision-recall curves, the confusion matrix and the metrics for the three classifiers side by side.
A reliability diagram checks whether a predicted 80% really means 80% of those molecules are active. Points below the diagonal mean the model is overconfident; above it, underconfident. Choose the number of bins and which models to compare.
ECE is the average gap between predicted and observed rates. Brier score is the mean squared error of the probabilities; lower is better for both.
Solid lines are validation scores with a band for fold-to-fold spread; dashed lines are training scores. A persistent gap suggests overfitting, and a flat validation curve suggests more data will add little. Dots on the right are five cross-validation folds.
Aggregate scores hide which molecules a model gets wrong. At the chosen threshold, these are the held-out compounds that each model misjudges most confidently, and a count of how many models agree on each molecule.
All held-out test molecules with the true label and each model's probability of being active. Search by ID or SMILES, filter by whether the models get it right at the threshold below, and sort by disagreement or confidence. Scores are real held-out predictions.
Active molecules are usually rare. A model that calls everything inactive can look accurate while finding nothing, and even a good model produces mostly false alarms when actives are scarce. Change the dataset balance and the model's strengths to see how accuracy, precision and F1 diverge.
Attribution methods such as SHAP split a prediction into contributions from each fingerprint bit. Each dot is one molecule: its position shows how much the bit pushed the prediction up (right) or down (left), and its colour shows whether the bit was present. Bars on the right rank bits by average impact.
Many decision trees voting together. A sturdy baseline for fingerprint data.
Gradient-boosted trees that correct earlier errors one round at a time.
A fast gradient-boosting variant built for high-dimensional features.
Tree-based models have settings that trade flexibility against overfitting. A grid search scores every combination with cross-validation. Each cell shows mean AUC-ROC; the ringed cell is the best. Select a cell for its spread across folds.
A random split puts near-identical molecules on both sides of the train and test line, which can flatter a model. A scaffold split keeps every ring scaffold on one side only, so the test molecules are chemically new. The gap between the two bars is how much of the score depends on having seen close relatives.
IC50 values come from different labs and assay set-ups, so two measurements of the same molecule can disagree. Averaging duplicates helps but does not remove this.
A random train and test split puts near-identical molecules on both sides. Splitting by chemical scaffold is a stricter test of how well a model handles new chemistry.
A strong IC50 shows a molecule blocks the enzyme in an assay. Safety, absorption and effect in cells still need separate work.
The concentration of a compound needed to cut an enzyme's activity by half. A smaller IC50 means a more potent inhibitor.
An enzyme (also called the main protease) that SARS-CoV-2 uses to cut its long protein chain into functional pieces. Blocking it stops the virus from replicating.
A line of text that writes a molecule's structure, such as CCO for ethanol. RDKit reads SMILES and turns them into molecules.
AUC-ROC measures how well a model ranks actives above inactives across every threshold. F1 combines precision and recall at one chosen threshold.
Molecules near the boundary are hard to call either way. Removing them gives cleaner labels for training, at the cost of a smaller dataset.
Change cutoffs, train the models and score your own molecule.
The full analysis as a Jupyter notebook.
Run the notebook in your browser, no setup.
App, notebook and requirements.
The live Streamlit app, embedded. Change cutoffs, train the models and score your own molecule — or open it full-screen.
Questions about the analysis, the data or the models? Reach me at harshinisuresha7@gmail.com.