3.1 公共数据库生态:PubChem、ChEMBL 与 ZINC 本节摘要:公共数据库是化学信息学的免费馆藏:PubChem 管登记广度,ChEMBL 管活性深度,ZINC 管可获取性。本节讲清三大库的定位差异与组合用法,给出活性数据从原始 IC50 到建模标签的换算方法,并用"为激酶靶点准备数据集"的完整案例串起检索、清洗、合并全流程。 第3章从进货开始。你在 1.2 节已经见过这些名字登场的年代,本节要回答的是更实际的问题:手里拿到一个项目,该去哪座库、取哪张表、怎样把拿回来的东西用起来。 免费馆藏从哪里来 PubChem 由美国国家医学图书馆维护,定位是"尽可能广的登记库":上亿条物质记录、亿级左右的独特化合物,附带文献关联与大量筛选实验数据。
本节摘要:公共数据库是化学信息学的免费馆藏:PubChem 管登记广度,ChEMBL 管活性深度,ZINC 管可获取性。本节讲清三大库的定位差异与组合用法,给出活性数据从原始 IC50 到建模标签的换算方法,并用"为激酶靶点准备数据集"的完整案例串起检索、清洗、合并全流程。
第3章从进货开始。你在 1.2 节已经见过这些名字登场的年代,本节要回答的是更实际的问题:手里拿到一个项目,该去哪座库、取哪张表、怎样把拿回来的东西用起来。
PubChem 由美国国家医学图书馆维护,定位是"尽可能广的登记库":上亿条物质记录、亿级左右的独特化合物,附带文献关联与大量筛选实验数据。它的强项是覆盖广、检索接口友好、批量下载方便;弱项是数据深浅不一——很多条目只有结构没有性质,活性数据的实验协议质量参差。把它当总目录用:查分子、查文献关联、拿大批量结构文件。
ChEMBL 由欧洲生物信息学研究所维护,定位是"经过人工整理的活性库":从几十万篇文献与专利中提取药物样小分子的生物活性记录,百万级化合物、千万级活性数值,每条记录带靶点、实验类型、单位、来源文献。它是 QSAR 建模与虚拟筛选基准的默认数据源。强项是活性数据的结构化程度;弱项是偏重经典靶点家族(激酶、GPCR),新兴靶点覆盖稀疏,且同分子不同实验室的数值分歧需要清洗处理。
ZINC 由加州大学旧金山分校维护,定位是"可获取分子的货架目录":聚合商业化合物供应商的现货目录,外加可合成枚举库,规模从十亿到万亿级(后者属超大规模枚举,见 10.4 节)。每个分子标注采购状态与子库归属,专门服务对接筛选。强项是"筛完就能买"的工程闭环;弱项是枚举库的质量依赖生成规则,商业化合物的浓度纯度仍需供应商确认。
| 数据库 | 馆藏性质 | 规模量级 | 活性数据 | 典型用途 |
|---|---|---|---|---|
| PubChem | 登记总目录 | 亿级化合物 | 大量但质量参差 | 查结构、文献关联、批量下载 |
| ChEMBL | 人工整理活性库 | 百万级化合物 | 千万级、带协议来源 | QSAR 建模、筛选基准 |
| ZINC | 可获取货架目录 | 十亿级起 | 无 | 对接筛选、采购落地 |
| DrugBank | 已上市与在研药物 | 万级 | 有代谢与适应症注释 | 药物对照集、副作用研究 |
| BindingDB | 靶点结合数据 | 百万级记录 | 结合常数为主 | 特定靶点补数据 |
三库联查是常态:ChEMBL 告诉你"哪些分子值得追",ZINC 告诉你"追到的哪些买得到",PubChem 补充"这些分子还有什么已知背景"。

文献里的活性以 IC50(抑制一半所需浓度)或 Ki(解离常数)报告,单位纳摩尔或微摩尔。直接拿 IC50 建模有两个坑:数值跨越多个数量级,且分布严重右偏——大部分分子活性平平,少数极强,线性模型会被拖歪。标准做法是取负对数换算:pIC50 等于 9 减去以纳摩尔为单位的 IC50 的常用对数。IC50 越小活性越强,pIC50 越大活性越强,一换算两顺——数量级被压平,方向被捋顺。
背景。项目要为某个激酶靶点构建 QSAR 模型(第6章),第一步是凑齐一份"分子-活性"数据集:分子结构用 SMILES,活性统一成 pIC50,尽量覆盖多个活性数量级。数据来源选 ChEMBL——它恰好以靶点为轴组织活性数据。
操作。从 ChEMBL 网站按靶点检索并导出制表符分隔的活动记录,然后用 pandas 清洗:
import pandas as pd from rdkit import Chem from rdkit.Chem import inchi import numpy as np df = pd.read_csv("chembl_egfr_activity.tsv", sep="\t") print(df.shape) # 示例:约六千条记录 # 只保留标准单位为纳摩尔的 IC50 记录 df = df[df["standard_type"] == "IC50"] df = df[df["standard_units"] == "nM"] df["pic50"] = 9 - np.log10(df["standard_value"]) # 同一分子多次测定:取中位数,保留测定次数 df["inchikey"] = [inchi.MolToInchiKey(Chem.MolFromSmiles(s)) if Chem.MolFromSmiles(s) else "" for s in df["smiles"]] df = df[df["inchikey"] != ""] agg = df.groupby("inchikey").agg( smiles=("smiles", "first"), pic50=("pic50", "median"), n_meas=("pic50", "count")).reset_index() print(len(agg)) # 去重后约四千个独特分子 print(agg["pic50"].describe()) # 跨度通常四到六个数量级
结果。六千条原始记录收敛为约四千个独特分子的数据集:解析失败的记录(结构写法非法)在 InChIKey 生成环节被剔除,重复测定的分子以中位数合并且测量次数留痕。pIC50 分布大致呈钟形,主体落在五到九之间,两端各有一小撮极端分子。
解读。三处处理各司其职:单位过滤把"标准值"统一到同一量纲,是换算合法的前提;以 InChIKey 而非 SMILES 字符串去重,躲开了写法差异的坑(第2.1节的老朋友);取中位数而非平均,是因为活性重复测定常有一两个离群值,中位数更抗扰动。留下 n_meas 列还有个隐藏用途——测定次数多的分子活性更可信,后面加权训练时用得上。
变式。若项目升级为对接筛选,数据需求从"带标签的小数据集"变成"无标签的大货柜":此时改去 ZINC 按子库与供应商批量导出可采购分子,用第4章的类药过滤器预筛,再按第5章的多样性挑选铺满化学空间。同一个项目,活性库与货架库一前一后,各供一段流水线。