MoleculeNet 到底是什么?
说真的,当你真正开始用机器学习做分子性质预测时,第一个问题往往不是什么模型更厉害,而是:数据从哪来?
我自己就踩过这个坑。早年做化学信息学项目时,数据东拼西凑,格式五花八门,光清洗就花了我两周。后来遇到了 MoleculeNet,才算是找到了“组织”。
MoleculeNet 诞生于 DeepChem 项目,由普林斯顿大学团队维护。它不是什么单一数据集,而是一个 数据集集合。说白了,就是一群搞计算化学和机器学习的专家,把散落在各处的分子数据统一收编,还帮你做了标准化处理。
它的目标是啥?就一个:让你能专心搞模型,别再花时间折腾数据格式。
它从哪来?谁在管?
MoleculeNet 的数据来源很广。小到几百个分子的实验测定,大到上千万个分子的虚拟筛选库,都有收录。你可以把它理解成一个数据集的“集市”,每个摊位卖的东西不一样,但包装规格统一。
我个人习惯把它按数据来源分成几类:
- 实验测量数据:比如从 PubChem、ChEMBL 这些公共数据库里扒下来的实测性质。
- 计算结果数据:用量子化学、分子动力学算出来的理论值。我记得最开始我还不大信任这类数据,后来发现只要方法靠谱,算出来的比测的还准。
- 人工标注数据:一些药物化学专家根据经验给出的分类标签,比如“这个分子有毒”。
项目现在由 DeepChem 社区持续维护。版本更新很快,我建议你直接关注 GitHub 上的 deepchem/deepchem 仓库。
核心子数据集一览
MoleculeNet 包含了二十多个子数据集。每个都有不同的任务目标。我把常用的几个列在下面,你以后做项目时可以直接对号入座:
| 子数据集 | 任务类型 | 样本量 | 预测目标 | 推荐用途 |
|---|---|---|---|---|
| ESOL | 回归 | 1,128 | 水溶性(log mol/L) | 入门练手 |
| FreeSolv | 回归 | 643 | 水合自由能(kcal/mol) | 评估模型泛化 |
| Lipophilicity | 回归 | 4,200 | 脂溶性(logD) | ADME 预测 |
| BACE | 分类 | 1,513 | β-分泌酶抑制活性 | 药物活性筛选 |
| HIV | 分类 | 41,127 | 抗 HIV 活性 | 大规模分类 |
| MUV | 分类 | 93,087 | 多个靶点活性 | 虚拟筛选 |
| Tox21 | 多任务分类 | 7,831 | 12种毒性效应 | 多标签学习 |
| ClinTox | 二元分类 | 1,491 | 临床毒性 + 失败 | 安全性预测 |
常见任务类型
从上面表格就能看出来,MoleculeNet 里的任务主要分两派:
- 回归任务:预测连续数值。比如溶解度、能垒、结合能。这类问题基本上就是拟合一个函数,用均方误差(MSE)或决定系数(R²)来评估。
- 分类任务:判定分子有没有某种性质。有毒没毒、活性高低、能不能透过血脑屏障。评估用 ROC-AUC 或 F1 分数比较稳妥。
为什么会这么分类?你想想看,药物研发里,有的是要精确数值('这个分子的logP是多少'),有的只要一个定性判断('这个分子会不会导致肝毒性')。两种任务的处理思路完全不同。
我实际做的过程中就发现,像 logP 这样的回归问题,单纯用分子指纹喂给随机森林就能拿到不错的结果;但到了 hERG 抑制这种分类问题,概率模型几乎一定会预测为中性,你需要从数据配比或者分子图结构上想办法。
一段代码快速上手
下面是我当时用 MoleculeNet 的第一个例子。这段代码会加载 ESOL 数据集,并显示基本的统计信息:
import deepchem as dc
from deepchem.utils import load_simple_data
# 加载 ESOL 数据集
tasks, datasets, transformers = dc.molnet.load_esol()
train_dataset, valid_dataset, test_dataset = datasets
# 看一眼数据长什么样
print(f'任务名: {tasks}')
print(f'训练集样本数: {len(train_dataset)}')
print(f'验证集样本数: {len(valid_dataset)}')
print(f'测试集样本数: {len(test_dataset)}')
# 看看第一条数据
first_mol = train_dataset.X[0]
first_label = train_dataset.y[0]
print(f'第一个分子的 SMILES: {first_mol}')
print(f'对应溶解度 (log mol/L): {first_label}')
嗯,这里要注意一点。MoleculeNet 的返回结构是 (tasks, datasets, transformers),而不是很多人以为的 (X, y)。我第一次用的时候就踩了这个坑,加载之后直接拿 datasets 当 X 用,结果报了一堆类型错误。
MoleculeNet 的独特之处
你可能会问:网上公开的化学数据集那么多,干嘛非得用 MoleculeNet?
我总结了几点:
- 统一:所有子数据集都转成了 DeepChem 的
Dataset对象。不需要你自己写 parser。 - 权威:每一个子数据集都来自公认的文献或公共数据库,质量有保障。
- 公平比较:它提供了固定的训练/验证/测试划分。你跑出来的结果,可以直接跟别的论文对比。
我印象很深的一件事是,有一次我把自己的模型结果跟某篇顶会论文对比,发现对方划分数据集时用了随机拆分。而我用 MoleculeNet 的官方划分——那个论文的模型直接就过拟合了。所以你想想看,统一的基准有多重要。
一张图看懂体系
下面这张 SVG 图把 MoleculeNet 的整体结构画了出来。你一看就明白了:
- MoleculeNet 数据集集合来自哪里?
- 你能列出至少 5 个核心子数据集吗?
- 你清楚回归任务和分类任务的区别吗?
- 你知道如何用 DeepChem 加载一个 MoleculeNet 子数据集吗?