第3章 分子表示方法:SMILES字符串、分子图与分子指纹
这一章咱们聊聊分子怎么“告诉”计算机自己长什么样。你想想看,在自注意力模型里,分子得先变成数字,模型才能处理。我这些年折腾过不少分子表示方法,说白了三套方案最常用:SMILES字符串、分子图(Atom-Bond)、分子指纹(Morgan Fingerprints)。每个都有它的脾气,也有它的用武之地。
3.1 SMILES字符串:线性化的分子“速记法”
SMILES,全称是Simplified Molecular Input Line Entry System。说白了,就是用一行文本来描述分子的结构。我第一次接触它的时候,觉得这东西简直就是化学领域的“咒语”——一串字符就能代表一个分子,太神奇了。
SMILES的基本规则并不复杂:
- 原子用元素符号表示:C代表碳,O代表氧,N代表氮等等
- 单键默认,双键用
=,三键用# - 分支用圆括号:括号内的结构是连在前一个原子上的侧链
- 环用数字标记:相同的数字表示同一个环的起点和终点
举个例子,乙醇的SMILES是 CCO,苯是 c1ccccc1(小写c表示芳香碳)。我之前做过一个项目,需要从数百万个SMILES中快速筛选出含特定子结构的分子。那时候我才真正体会到,SMILES的简洁性在字符串匹配任务中是多么高效。
关键理解:虽然SMILES看着像文本,但在Transformer模型里,它会被拆成token序列,就像处理自然语言一样。这也是为什么很多分子语言模型都从SMILES出发。
避坑指南:我曾遇到过一个问题——同一个分子可以有多个有效的SMILES表示。比如,从不同原子开始编码,得到的字符串完全不同。所以在处理数据时,建议统一使用规范化(canonical)SMILES,否则模型会以为它们是不同的分子。
3.2 分子图(Atom-Bond):让模型“看见”分子结构
SMILES虽然方便,但它丢失了空间信息。你想想看,一个分子本质上就是个图——原子是节点,化学键是边。这就是分子图的思路。
分子图表示法包括两大部分:
| 组件 | 含义 | 常见特征 |
|---|---|---|
| 节点(原子) | 每个原子代表一个节点 | 原子类型、电荷、手性、芳香性、氢原子数 |
| 边(化学键) | 原子之间的连接关系 | 键的类型(单/双/三/芳香键)、是否共轭、是否在环内 |
我个人的习惯是,在做图神经网络(GNN)时,优先用分子图。因为GNN天然就适合处理这种结构化的数据。每个原子节点接收邻居原子的信息,通过消息传递来更新自己的特征。嗯,这里要注意:分子图的节点特征工程直接影响模型上限。
经验之谈:我记得有一次,我在处理一个药物分子的活性预测任务。刚开始只用原子类型和键类型作为特征,模型的AUC一直在0.75左右徘徊。后来我把原子电荷、手性特征加进去,效果直接提升到了0.83。说白了,特征质量的“天花板”决定了模型的天花板。
用代码构造分子图,Rdkit是个好帮手:
from rdkit import Chem
from rdkit.Chem import AllChem
mol = Chem.MolFromSmiles('CCO')
# 获取原子特征
for atom in mol.GetAtoms():
print(f"原子: {atom.GetSymbol()}, 原子序数: {atom.GetAtomicNum()}")
# 获取键信息
for bond in mol.GetBonds():
print(f"键: {bond.GetBeginAtomIdx()} - {bond.GetEndAtomIdx()}, 类型: {bond.GetBondType()}")
3.3 分子指纹(Morgan Fingerprints):以子结构为中心的描述符
那么,如果我不用神经网络,有没有一种方法能把分子结构编码成固定长度的向量?有——分子指纹。Morgan指纹(也叫ECFP)是其中最经典的一种。
Morgan指纹的核心思想很简单:
- 从每个原子出发,以不同半径(通常r=0,1,2,3)扩展,提取局部子结构
- 对每个子结构计算唯一的哈希值,映射到一个固定长度的位向量(bit vector)
- 把这些位向量拼接或做OR操作,最终得到一个分子的全局指纹
举个例子,一个半径为2的Morgan指纹(ECFP4),能将分子编码成一个长度为1024或2048的二进制向量。这个向量可以直接作为传统机器学习模型的输入,比如随机森林或XGBoost。
深度思考:在自注意力模型里,你可能会问——“那我为什么还要用分子指纹?”其实,指纹可以作为分子的全局特征,跟SMILES的token序列或图结构的节点特征做拼接。有时候,这种“双通道”的特征融合能带来意想不到的收益。
3.4 三种表示法的对比与选择
我在一个项目中,曾经因为选错了表示方法吃了大亏。那次任务是预测某个分子的毒性,我一开始只用了SMILES序列,结果模型完全学不到分子的拓扑结构。后来换了分子图,效果才正常。你得根据实际场景来选:
| 表示方法 | 编码维度 | 是否保持拓扑结构 | 计算成本 | 典型应用 |
|---|---|---|---|---|
| SMILES | 可变 | 否(线性化) | 低 | 语言模型、序列生成 |
| 分子图 | 可变(节点+边) | 是 | 中高 | GNN、自注意力(图Transformer) |
| Morgan指纹 | 固定(1024/2048) | 部分保持(局部子结构) | 低 | 分子相似性搜索、传统ML |
避坑指南:我曾经在构建自注意力层的时候,直接把SMILES当作纯文本处理,忘了做原子级别的token对齐。结果模型的注意力权重全跑偏了,完全学不到化学意义。切记:SMILES的token化一定要保留原子级别的对应关系,否则你看到的“注意力热图”就是一张废纸。
3.5 本知识体系图谱
下面这张SVG图,帮你把三种分子表示方法和它们在自注意力模型中的角色串起来。它不是我随便画的,而是我从多个项目中沉淀下来的一个逻辑框架:
这张图可以帮助你理解,不管用哪种分子表示法,它们最终都会被喂进自注意力层,从而生成你想要的“分子片段关注热图”。我个人的建议是:如果你刚开始做分子AI相关的项目,先从SMILES入手熟悉套路,然后在模型优化阶段切换到分子图以提升性能。至于Morgan指纹,它更适合做分子之间的快速相似度比对,或者作为模型的辅助特征。
一个小建议:在数据预处理阶段,你可以同时保留三种表示法。虽然在内存上会多占一点,但在模型设计时就有了更多的选择余地和回旋空间。我在做一个多任务学习项目时,就是这样干的——效果出乎意料地好。