How to Perform Data Curation and Classify Bioactivity Data on ChEMBL Database

Sep 7, 2022·
Yassir Boulaamane
Yassir Boulaamane
· 6 min read

A classifier does not learn activity. It learns the labels you attached to the molecules.

ChEMBL will give you the measurements. It will not give you the labels. For one target the download has many rows, often several for the same compound, some with no number, and a continuous IC50 that is not yet a class. This note turns the human acetylcholinesterase table into a file a classifier can train on: one row per molecule, a mean potency, and a class that leaves the uncertain middle out.

From a ChEMBL search to a labelled fileFive steps: search human acetylcholinesterase, keep IC50 rows, average replicates of the same molecule, drop empty values, then label only the extremes.1. SearchHuman acetylcholinesterase, CHEMBL2202. Keep IC50One activity type, in nanomolar3. Average replicatesMean standard value for each ChEMBL ID4. One row per moleculeDrop duplicate IDs and empty values5. Label the extremesActive or inactive. The middle stays out.
Figure 1. The label is not in the download. It is the last step, after replicates have been collapsed and rows with no number have been removed.

What the download actually contains

ChEMBL is a curated collection of bioactive, drug-like molecules and the measurements reported for them. Two counts on the release notes are easy to mix up. Compound records count depositions. Unique compounds are fewer, because the same structure can arrive from more than one source.

The ChEMBL 30 release, prepared on 22 February 2022, contained 2,786,911 compound records, 2,157,379 compounds, 1,458,215 assays, and 14,855 targets [1]. ChEMBL 33, prepared on 31 May 2023, contained 3,051,613 compound records, 2,399,743 compounds, 1,610,596 assays, and 15,398 targets [2]. A later paper describes the same platform and the kinds of data it holds [3]. Use the current release notes if you need today’s size. The curation steps below do not depend on it.

One target, one activity type

Search the target name, not a disease and not a compound, when the model is meant to describe that protein. Acetylcholinesterase returns many targets. The one used here is the human protein, CHEMBL220. Pick the organism on purpose. A homolog is a different label.

On the target report, the activity chart shows how those measurements were reported. In the interface used for this tutorial, IC50 was the common type, listed 8,205 times. That count grows as new papers are added. Treat it as a snapshot of the download, not as a property of the enzyme.

Download the IC50 slice as CSV or TSV. Then keep four columns, and delete the rest before you open the file in a notebook:

  • Molecule ChEMBL ID
  • Smiles
  • Standard Type
  • Standard Value

ChEMBL standard IC50 values are in nanomolar. If a later export renames a column, rename it back to this list. The notebook expects these headers, and it expects Standard Value to be a number.

One row per molecule

The same ChEMBL ID often appears more than once. Laboratories did not run the same assay. The values disagree, and both rows are “the” measurement until you decide on a rule.

The rule in this tutorial is a mean of Standard Value on the linear nanomolar scale, grouped by ChEMBL ID. That is a teaching choice. A factor of ten in potency is not symmetric on a linear scale, and a mean mixes assays that were not run under the same conditions. It is enough to build a labelled practice set. It is not assay-aware curation.

After the mean is attached, keep the first row for each ID and drop rows that still have a missing value. Averaging first matters: the mean has to see every replicate before the extras are deleted.

import pandas as pd

columns = ["Molecule ChEMBL ID", "Smiles", "Standard Type", "Standard Value"]
x = pd.read_csv("ache.csv")
x = x[columns]
x["Standard Value"] = pd.to_numeric(x["Standard Value"], errors="coerce")

x["mean_value"] = x.groupby("Molecule ChEMBL ID")["Standard Value"].transform("mean")
x = x.drop_duplicates("Molecule ChEMBL ID", keep="first")
x = x.dropna()

to_numeric(..., errors="coerce") turns anything that is not a number into a missing value, so a footnote or a blank cell cannot silently become text and break the mean. Restricting the frame to the four columns first stops dropna from rejecting a molecule because some unused field was empty.

The class is a gap, not a line

Potent enzyme inhibitors in this literature often sit in the nanomolar range. For a classification exercise, call a molecule active when its mean IC50 is at most 1000 nM, which is 1 µM. Call it inactive when the mean is above 10000 nM, which is 10 µM. Everything between those two cuts is left out of the file.

Activity labels leave a gapMolecules at or below 1000 nanomolar are labelled active. Molecules above 10000 nanomolar are labelled inactive. The interval between those cuts is discarded.The label uses two cuts, and drops the middleMean IC50, nanomolar. Bar widths are the decision, not a linear axis.ActiveLeft outInactiveat most 1000 nMclass 11000 to 10000 nMno row in the fileabove 10000 nMclass 0
Figure 2. Adjacent IC50 values can fall on opposite sides of a single threshold because of assay noise. The gap keeps those borderline molecules out of both classes. The widths in the drawing are equal so the three decisions are visible. They are not proportional to potency.
active = x.loc[x["mean_value"] <= 1000].copy()
inactive = x.loc[x["mean_value"] > 10000].copy()
active["Class"] = 1
inactive["Class"] = 0

combined = pd.concat([active, inactive], axis=0)
combined.to_csv("ache_labelled.csv", index=False)

.copy() matters. Assigning Class on a sliced frame is how pandas loses the new column or warns that it might. The saved file contains only the two tails. It is smaller than the curated table, and it is enriched for molecules whose mean fell clearly on one side.

What this file is

The CSV is a practice set for one target and one endpoint. A few limits travel with it.

  • The class is a cutoff on a mean, not a second experiment.
  • Replicates were averaged on a linear scale, across assays that were not matched.
  • Molecules between 1 µM and 10 µM are absent, so a model never has to make the close call.
  • The same cuts on a different target, or on Ki rather than IC50, would be a different labelling decision. Do that in a separate file.

Those choices are the model, as much as the classifier you train afterwards.

References

[1] ChEMBL 30 release note, 10 March 2022. Data prepared 22 February 2022. https://chembl.blogspot.com/2022/03/chembl-30-released.html

[2] ChEMBL 33 release note, 13 June 2023. Data prepared 31 May 2023. https://chembl.blogspot.com/2023/06/release-of-chembl-33.html

[3] Zdrazil, B. et al. The ChEMBL Database in 2023: a drug discovery platform spanning multiple bioactivity data types and time periods. Nucleic Acids Research, 2024, 52, D1180–D1192. https://doi.org/10.1093/nar/gkad1004