3. 常用分子数据集:ZINC、ChEMBL、PubChem 与 DrugBank

做分子生成的,说白了就是跟数据打交道。模型再牛,没有好的数据喂,它也学不出啥名堂。

我个人习惯,拿到一个新任务,第一件事不是调模型,而是花时间去摸数据集。你想想看,选错了数据集,后面所有的工作都可能白费。

3.1 四大数据集概览

目前学术界和工业界,最常用的分子数据集就这四个:ZINC、ChEMBL、PubChem 和 DrugBank。它们各有各的脾气,也各有各的用处。

我刚开始做分子生成那会儿,就踩过一个坑。想用 PubChem 做预训练,结果数据太大,预处理就花了两天,模型训练还老是崩溃。后来才明白,不同数据集玩的是不同游戏。

数据集 规模 核心特点 我的用法
ZINC ~2.3亿 (子集常用 250K) 类药、可购买、商业友好 预训练、虚拟筛选基线
ChEMBL ~200万 活性分子 带靶点活性标注、人工审核 微调、活性预测
PubChem ~1.1亿 化合物 数据量大、来源杂、含实验数据 大规模预训练、多样性探索
DrugBank ~1.4万 药物分子 FDA批准、高质量、小样本 验证生成药物的合理性

3.2 ZINC:分子世界的亚马逊

ZINC 全称是 ZINC Is Not Commercial,但它其实特别商业友好。几乎所有分子都能直接从供应商那里买到。

我记得有一次做虚拟筛选,模型生成了一堆看起来完美的分子。结果一查 ZINC,发现根本买不到,没法做湿实验验证。从那以后,我生成分子都会先去 ZINC 里搜一搜,看看是不是现成的。

最常用的 ZINC 子集:

  • ZINC-250K:250,000 个类药分子,轻量级,适合快速验证模型。
  • ZINC-15:最大版本,含 2.3 亿分子,适合大规模预训练。
  • ZINC20:2020年更新版,加了更多结构多样性。

下载和使用示例:

# 从 ZINC 官网下载 SMILES 文件
# 常用的是 ZINC-250K 子集
wget https://zinc15.docking.org/substances/subsets/250k.smi

# 读取并解析
import pandas as pd
zinc_df = pd.read_csv('250k.smi', sep='\t', header=None)
zinc_df.columns = ['SMILES', 'ZINC_ID']
小提示:ZINC 的 SMILES 是标准化的,自带类药过滤。如果你刚开始做分子生成,建议从 ZINC-250K 入手,训练速度快,效果也够用。

3.3 ChEMBL:药化界的维基百科

ChEMBL 是我个人最偏爱的数据集。为什么?因为它有人工审核,数据质量高。每个分子几乎都带着明确的生物活性数据。

我做靶向药物生成时,ChEMBL 是必须用的。拿它做微调,模型生成的分子活性普遍比用 ZINC 训出来的高一个量级。

ChEMBL 的核心特点:

  • 靶点关联:每个分子都标注了作用于哪个蛋白靶点。
  • 活性值:IC50、Ki、EC50 等关键指标都有。
  • 人工审核:数据来自科学文献,可靠性高。

我建议你下载 ChEMBL 的 SQLite 版本,查数据特别方便。我曾经用这个数据库,几分钟就找到了某个靶点所有已知的活性分子。

# 安装 ChEMBL 数据库的 Python 接口
pip install chembl_webresource_client

# 查询某个靶点的所有分子
from chembl_webresource_client.new_client import new_client
target = new_client.target
target_id = target.search('EGFR')[0]['target_chembl_id']

# 获取活性数据
activities = new_client.activity
egfr_activities = activities.filter(target_chembl_id=target_id)

3.4 PubChem:大数据时代的巨人

PubChem 是四个数据集里最大的。它不挑食,什么分子都收,不管来源如何。你想想看,1.1 亿个化合物,什么花样都有。

但这里有个问题。PubChem 的数据质量参差不齐。有些分子 SMILES 格式不规范,有些缺少关键信息。我在大规模预训练时用过一次,结果模型学会了生成一些奇怪的结构,后来我加了很重的过滤规则才搞定。

PubChem 的常用下载方式:

# 通过 FTP 下载 PubChem 的 SDF 文件
wget ftp://ftp.ncbi.nlm.nih.gov/pubchem/Compound/CURRENT-Full/SDF/

# 也可以用 PUG REST API 批量下载
# 例:获取 CID 为 2244 的分子信息
curl "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/2244/record/JSON"

使用 PubChem 的建议:

  • 按需过滤:只下载你需要的子集,否则存储都是大问题。
  • 规范校验:下载后一定要做 SMILES 标准化和去重。
  • 别信来源:最好只保留来自文献或专利的数据。

3.5 DrugBank:金标准

DrugBank 的分子最少,只有一万多个,但分量最重。它收录的全是 FDA 批准的药物。

为什么这个数据集重要?因为它代表了“真正的药”。我做分子生成模型评估时,一定会拿 DrugBank 里的分子做对比。如果生成的分子跟 DrugBank 里的结构完全不同,那大概率有问题。

DrugBank 的核心数据字段:

  • 药物名称、结构式、SMILES
  • 靶点信息、作用机制
  • 药代动力学数据(ADMET)

在生成模型中的应用:

我个人习惯用 DrugBank 做 验证集。训练时不用它,但评估时看生成的分子跟已知药物有多像。有点像考试时看标准答案。

# DrugBank 提供 XML 格式下载
# 解析示例(需要先下载 DrugBank XML)
import xml.etree.ElementTree as ET
tree = ET.parse('drugbank_all_full_database.xml')
root = tree.getroot()

# 提取所有药物的 SMILES
for drug in root.findall('.//{http://www.drugbank.ca}drug'):
    smiles = drug.find('.//{http://www.drugbank.ca}smiles')
    if smiles is not None:
        print(smiles.text)

3.6 选数据集的实战策略

说到这里,你可能会问:我到底该用哪个?

我根据经验给你总结一下:

  • 学分子语法:用 ZINC-250K,轻量、干净,适合从头训练。
  • 生成可买到的分子:用 ZINC-15 完整版。
  • 生成有活性的分子:用 ChEMBL 做微调。
  • 探索化学空间:用 PubChem,但要做好过滤。
  • 验证生成质量:用 DrugBank 做标准答案。
注意:不要直接拿着 PubChem 全量数据去训练 Transformer。我之前试过,训练时间翻倍,效果反而下降。因为数据噪点太多了。建议先过滤,或者用 ZINC 子集。

3.7 本章知识图谱

下面这张图,帮你把四个数据集的关系理清楚。时间轴从左到右,展示了各自适用的场景。

分子数据集选择策略 任务起点 产出验证 ZINC 预训练·语法学习 ChEMBL 微调·活性预测 PubChem 大规模·多样性 DrugBank 验证·金标准 实战建议 • 从 ZINC 开始学分子语言 • 用 ChEMBL 训练活性生成 • 借 PubChem 探索化学空间 • 最后用 DrugBank 验证结果是否靠谱

3.8 数据处理:通用流程

不管你选哪个数据集,有一件事逃不掉——数据清洗。

我曾经偷懒没做清洗,直接把 ChEMBL 数据丢进模型。结果训练完了,生成出来的分子有一半在 SMILES 语法上就是错的。那叫一个惨。

我现在的标准流程:

  1. 规范 SMILES:统一用 RDKit 做标准化,去盐、去溶剂。
  2. 去重:InChI Key 是去重的金标准,别只用 SMILES。
  3. 过滤:去除不合理的分子(原子数太多、环太大等)。
  4. 切分:按 8:1:1 划分训练、验证、测试集。
# 使用 RDKit 做 SMILES 标准化
from rdkit import Chem

def standardize_smiles(smiles):
    mol = Chem.MolFromSmiles(smiles)
    if mol is None:
        return None
    # 去盐
    mol = Chem.RemoveInorganicSalts(mol)
    # 标准化
    smiles_out = Chem.MolToSmiles(mol, canonical=True)
    return smiles_out

3.9 本章总结

选对数据集,分子生成项目就成功了一半。ZINC 是入门首选,ChEMBL 是活性神器,PubChem 是数据巨无霸,DrugBank 是质量标杆。

我的建议是:别贪多。先从一个数据集开始,把流程跑通,再慢慢加别的。