4. 化合物数据获取:ChEMBL、PubChem、DrugBank 等主流数据库的使用方法

做 QSAR 建模,数据获取是第一步,也是最容易被低估的一步。我记得刚开始做的时候,光在几个数据库之间切换就花了不少时间。有些同学从网上随便扒点数据就跑模型,结果训练集和测试集重复了都不知道,模型虚高到离谱。

说白了,数据质量决定了模型的天花板。这章我就把三个最常用的公开数据库——ChEMBL、PubChem、DrugBank——怎么用、用哪个、注意什么,一次性说清楚。

核心原则:活性数据优先找 ChEMBL,化合物基础信息查 PubChem,药物级批准数据翻 DrugBank。别搞反了。

4.1 ChEMBL:生物活性数据的宝藏库

ChEMBL 是我最常用的数据库,没有之一。它由欧洲生物信息学研究所(EBI)维护,收录了超过 200 万种化合物的生物活性数据,而且大部分都人工校验过。

Web 界面搜索:直接访问 ChEMBL 官网,在搜索框输入化合物名、SMILES 或 ChEMBL ID 就能查到。我个人习惯是先用 Web 界面摸一下数据量,确认有货再写脚本批量拉。

REST API 批量获取:正经干活肯定要用 API。ChEMBL 提供了完整的 RESTful API,支持 JSON 和 XML 格式。

import requests

# 搜索阿司匹林相关的分子
url = "https://www.ebi.ac.uk/chembl/api/data/molecule"
params = {"q": "aspirin", "format": "json", "limit": 5}
resp = requests.get(url, params=params)
data = resp.json()

for mol in data["molecules"]:
    print(mol["pref_name"], mol["molecule_chembl_id"])

拿到分子列表后,再通过 ChEMBL ID 去拉活性数据:

# 拉某个分子的活性数据
mol_id = "CHEMBL25"  # 阿司匹林的 ChEMBL ID
act_url = f"https://www.ebi.ac.uk/chembl/api/data/activity"
params = {"molecule_chembl_id": mol_id, "format": "json"}
resp = requests.get(act_url, params=params)
activities = resp.json()

for act in activities["activities"]:
    print(act["standard_type"], act["standard_value"],
          act["standard_units"], act["assay_chembl_id"])

小技巧:ChEMBL API 有频率限制,每秒别超过 3 个请求。我一般加个 time.sleep(0.4) 就稳了。

我在项目中遇到过,用 ChEMBL 批量下载时,如果不指定 assay_type 会拿到很多结合实验数据,而不是功能实验数据。建议加上 assay_type: "F" 来过滤。

4.2 PubChem:最大的免费化合物数据库

PubChem 由美国 NIH 维护,号称收录了 1.1 亿种化合物。它的强项是化合物基础信息——分子量、logP、H 键供体/受体数、SMILES 等等。

PUG REST API:PubChem 的 API 叫 PUG REST,用起来很直接。

# 获取阿司匹林的理化性质
url = ("https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/"
       "name/aspirin/property/"
       "MolecularFormula,MolecularWeight,"
       "XLogP,HBondDonorCount,HBondAcceptorCount,"
       "CanonicalSMILES/JSON")
resp = requests.get(url)
props = resp.json()

print(props["PropertyTable"]["Properties"][0])

返回结果长这样:

{
  "MolecularFormula": "C9H8O4",
  "MolecularWeight": 180.16,
  "XLogP": 1.2,
  "HBondDonorCount": 1,
  "HBondAcceptorCount": 4,
  "CanonicalSMILES": "CC(=O)Oc1ccccc1C(=O)O"
}

批量下载:PubChem 支持按 SMILES、CID 列表或 SDF 文件批量拉数据。我以前在项目里需要一次拉 5000 个化合物的 logP,用 /property/ 接口配合 CID 列表,一次性搞定。

# 按 CID 列表批量获取属性
cid_list = "2244,3672,5161"  # 阿司匹林、扑热息痛、布洛芬
url = ("https://pubchem.ncbi.nlm.nih.gov/rest/pug/"
       "compound/cid/{}/property/"
       "MolecularWeight,XLogP,CanonicalSMILES/JSON".format(cid_list))
resp = requests.get(url)
data = resp.json()
for item in data["PropertyTable"]["Properties"]:
    print(item["CID"], item["MolecularWeight"], item["XLogP"])

注意:PubChem 的数据来源非常杂,有些 SMILES 是自动生成的,不一定适合 QSAR。我建议拿到数据后先做一遍标准化——比如用 RDKit 统一芳香性表示、去除立体异构歧义。这一步能省你后面至少一半的 debug 时间。

4.3 DrugBank:药物级数据的权威来源

DrugBank 和其他两个数据库不太一样。它收录的是已经获批或在研的药物分子,数据质量极高,每个分子都有详细的靶点、通路、代谢信息。适合做靶点预测和 ADMET 建模。

访问方式:DrugBank 需要注册账号才能用 API,免费版每天有调用次数限制。Web 界面可以直接查询。

# DrugBank API v1 示例(需要自己的 API key)
import requests

url = "https://api.drugbank.com/v1/drugs"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
params = {"q": "aspirin", "limit": 5}
resp = requests.get(url, headers=headers, params=params)
data = resp.json()

for drug in data["data"]:
    print(drug["name"], drug["drugbank_id"],
          drug.get("indication", "")[:50])

数据特点:DrugBank 的靶点数据是经过专家审核的,每个靶点都有 Uniprot ID 和作用类型。我在做靶点预测模型时,经常用 DrugBank 的数据做验证集——因为它的标签比 ChEMBL 更干净。

我个人习惯:做 QSAR 建模时,用 ChEMBL 的数据做训练集,用 DrugBank 的数据做外部验证集。这样能看出模型在真实药物分子上的泛化能力。

4.4 三大数据库对比

你想想看,三个数据库各有侧重,选哪个取决于你要干什么。下面这张表我每次培训都会给学员看:

维度 ChEMBL PubChem DrugBank
数据规模 ~200 万化合物 ~1.1 亿化合物 ~1.5 万药物
强项数据 生物活性(IC₅₀/Kᵢ/EC₅₀) 理化性质、SMILES、结构 靶点、通路、代谢、适应症
数据质量 高(人工校验) 中(自动+用户提交) 极高(专家审核)
API 频率 3 req/s 5 req/s 按注册计划,一般够用
适用场景 QSAR 活性建模 分子属性计算、筛选 靶点预测、ADMET 验证
是否需要注册 否 否 是(API key)

嗯,这里要提醒一下:PubChem 虽然数据量大,但噪声也多。你拉到的活性数据可能来自不同实验条件,不归一化的话模型会学到实验偏差而不是生物活性。

4.5 实战流程:怎么把数据串起来

下面这张图是我在实际项目中总结出来的数据获取流程。每次启动新项目,我都按这个步骤走:

化合物数据获取流程 查询条件 SMILES / 名称 / 结构 ChEMBL 活性数据(IC₅₀/Kᵢ) PubChem 理化性质 / SMILES DrugBank 靶点 / 适应症 / 通路 结构化数据集 合并、清洗、标准化 💡 选择指南 活性数据优先 ChEMBL | 化合物基础信息查 PubChem | 药物级靶点数据用 DrugBank

4.6 几件必须注意的事

数据拿到了,别急着建模。我踩过几个坑,写出来你们绕开走。

  • 数据去重:同一个化合物在不同数据库里可能有不同的 ID 和名称。用 SMILES 做归一化后再合并。
  • 单位归一化:ChEMBL 的活性数据有的用 nM,有的用 μM。一律转成 pIC₅₀ 或 pKᵢ 再建模。
  • 版权问题:这三家数据库都允许学术免费使用,但如果你想商业化,PubChem 和 DrugBank 有额外限制。记得看授权协议。

我的工作流:先用 ChEMBL API 拉活性数据 → 用 PubChem 补理化性质 → 用 DrugBank 验证靶点。三个数据源用 SMILES 做关联,整个过程写成一个 Python 脚本跑批量。

我曾经因为没注意数据版权问题,差点在发表论文时遇到麻烦。后来养成了习惯:每次用数据都在方法部分注明来源和版本号,比如 "ChEMBL v32, PubChem 2024-06 release, DrugBank v5.1.12"。引用清楚,后面审稿人问你也不慌。

数据获取这件事,看起来是体力活,但它直接决定了你后面所有工作的地基。地基歪了,模型再好也是白搭。