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 实战流程:怎么把数据串起来
下面这张图是我在实际项目中总结出来的数据获取流程。每次启动新项目,我都按这个步骤走:
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"。引用清楚,后面审稿人问你也不慌。
数据获取这件事,看起来是体力活,但它直接决定了你后面所有工作的地基。地基歪了,模型再好也是白搭。