分子数据基础:SMILES、InChI 与图结构
做 ADMET 预测,第一道坎就是怎么把分子“喂”给模型。
你可能手头有几十万个化合物,每个都是字符串或结构文件。模型看不懂化学式,它只认向量、图或者序列。所以,分子表示就是搭在化学世界和深度学习之间的桥。
我个人习惯先搞清楚三套表示法:SMILES、InChI 和分子图。前两个是文本形式,最后一个是显式拓扑结构。下面一个一个说。
1. SMILES 表示法
SMILES 全称 Simplified Molecular Input Line Entry System。说白了,就是一条字符串,把分子“打平”写出来。
- 原子:大写字母代表元素,比如 C 是碳,O 是氧。小写字母 c 表示芳香碳。
- 键:单键默认不写,双键用
=,三键用#。 - 分支:用圆括号
()括起来。比如乙醇:CCO;异丙醇:CC(C)O。 - 环:用数字标记环的起点和终点,比如苯:
c1ccccc1。
Chem.MolToSmiles(mol, canonical=True) 转一下,否则模型会学到“写法不同即分子不同”的假规律。
举个例子,阿司匹林(阿斯匹林)的 SMILES:
CC(=O)Oc1ccccc1C(=O)O
看着复杂,拆开其实很简单:一个苯环,连着羧基和酯基。我在做 Tox21 数据清洗时,发现原始数据里有几百个 SMILES 写错了环数字或者漏了括号——跑出来的模型性能直接掉 5 个点。所以,数据预处理时务必用 RDKit 校验。
2. InChI 与国际化学标识符
SMILES 虽然流行,但它不唯一。同一个分子,不同工具、不同规则能写出不同 SMILES。InChI 就是来解决这个问题的。
InChI(International Chemical Identifier)由 IUPAC 制定,是一种分层表示的规范标识符。它包含了分子的连接性、同位素、立体化学和电荷信息。
比如水的 InChI:
InChI=1S/H2O/h1H2
结构是:版本 1S,分子式 H2O,连接层 /h1H2(表示一个氢原子两个氢)。
InChIKey 是哈希后的 27 字符定长串,适合数据库索引。我一般在做跨数据集合并时用 InChIKey 去重,很少用 SMILES——因为不同来源的 SMILES 写法差异太大。
MolToInchi 是纯 Python 实现的……后来换成 MolToInchiKey 快了三倍。
3. 分子图结构
图神经网络的兴起让分子图成为主流输入。每个原子是一个节点,每个化学键是一条边。节点特征通常包含:原子种类、度数、电荷、是否在环中、杂化类型等。边特征包含键类型(单/双/三/芳香键)、是否共轭等。
我从 SMILES 构建分子图的典型流程:
- 用 RDKit 读取 SMILES,生成
Mol对象。 - 提取原子特征(比如 one-hot 编码元素、隐式氢数、形式电荷)。
- 提取键特征(键类型、是否在环中)。
- 组装成
torch_geometric.data.Data或dgl.DGLGraph。
你不必每次自己写特征提取,rdkit.Chem.rdMolDescriptors 和 dgllife.utils 都有现成函数。但要注意特征对齐:训练集和测试集必须用同一套特征定义。有一次我换了 RDKit 版本,原子特征顺序变了,模型直接崩了。
4. 开源 ADMET 数据集概览
做 ADMET 预测离不开高质量标注数据。下面是我常用的几个公开数据集:
| 数据集 | 任务类型 | 分子数 | 关键标签 | 来源 |
|---|---|---|---|---|
| Tox21 | 多分类(12 个毒性终点) | ~7,800 | NR-AR, NR-AR-LBD, SR-ARE 等 | NIH Tox21 挑战 |
| ESOL | 回归(水溶性 logS) | 1,128 | 实验测量的溶解度 | Delaney (2004) |
| FreeSolv | 回归(水合自由能) | 643 | ΔG (kcal/mol) | Mobley Lab |
| Lipophilicity | 回归(logD7.4) | 4,200 | 实验 logD | ChEMBL 子集 |
| BBBP | 二分类(血脑屏障透过性) | ~2,000 | 是否透过 | MoleculeNet |
下载方式:MoleculeNet 已经整合了大部分数据集,用 deepchem.molnet.load_tox21 或 dgllife.data.Tox21 就能直接拉。不建议自己爬,一是伦理问题,二是数据清洗太耗时。
5. 知识体系图
下面这张 SVG 概括了从分子表示到数据集的完整路径:
6. 实用小工具和日常避坑
- 快速查看分子:
from rdkit.Chem import Draw; Draw.MolToImage(mol)直接画图。 - SMILES 统一:训练前跑一遍
Chem.MolFromSmiles(smi)+Chem.MolToSmiles(mol)做规范化。 - 数据集拆分:不要用随机拆分,用 scaffold 拆分(基于分子骨架),否则测试集和训练集太像,结果虚高。
- 内存管理:处理 10 万以上分子时,我建议用
pandas分批读,每批 5000 个分子转图,不然显存爆掉。
好了,这些就是分子数据基础的全部要点。下一步咱们就可以拿着这些数据,开始搭建自监督预训练模型了。