分子表示基础:SMILES字符串、分子图、指纹

做分子生成,第一步就是得找个方式把分子「喂」给模型。你不能直接把原子扔进去吧?

我刚开始接触这个领域时,也困惑过:一个分子,有原子、有键、有三维结构,到底该怎么数字化?

目前工业界和学术界主流的表示方法有三种:SMILES字符串、分子图、Morgen指纹。各有各的玩法,也各有各的坑。我们逐一来看。

SMILES字符串——最直观的「分子简写」

SMILES全称是Simplified Molecular Input Line Entry System。说白了,就是把分子结构写成一行ASCII字符串。你可以把它想象成一个化学式的「缩写」。比如乙醇,它的SMILES是:

CCO

简单吧?C是碳,O是氧,按顺序写出来就是。环状分子用数字标记环的起点和终点,比如苯:

c1ccccc1

我经常跟团队成员说,SMILES是最容易上手的一种表示法。你不需要安装任何化学库,手写就能表达一个分子。

优点:

  • 文本化,储存方便:一行字符串,数据库里直接存成VARCHAR就行。
  • 可读性尚可:训练有素的化学家看着CCO就知道是乙醇。
  • 生态成熟:RDKit、Open Babel等工具直接支持读写。

缺点:

  • 语法歧义:同一个分子可以有多种不同的SMILES写法。比如乙醇也可以是OCC。我刚开始学的时候踩过这个坑——同样的分子,不同程序算出来的SMILES不一样,一比对就以为不是同一个东西。
  • 缺乏空间信息:SMILES只描述拓扑连接,三维构象完全丢失。
  • 对模型不友好:字符串长度不固定,长分子可能达到几百个字符,序列模型处理起来有天然劣势。
注意:SMILES有标准化解法——Canonical SMILES(标准SMILES)。比如RDKit的MolToSmiles(mol, canonical=True)。但即便如此,它依然不是唯一的表示方式,不同库的标准化规则可能不同。

分子图——最接近化学直觉的拓扑表示

如果SMILES是一维的文本串,那分子图就是二维的拓扑结构。图(Graph)由节点和边组成:节点是原子,边是化学键。

这样的表示方式符合化学家的直觉——你想想,一个有机物分子本来就是个图嘛。

我习惯用邻接矩阵来理解它。假设一个分子有N个原子,邻接矩阵就是一个N×N的0-1矩阵。如果第i个原子和第j个原子之间有键,那对应的位置就是1,否则是0。再加上每个原子的特征向量(比如原子类型、杂化状态、电荷等),就构成了完整的图表示。

举个简单的例子,水分子(H₂O):

原子类型:O, H, H
邻接矩阵:
  [0, 1, 1]
  [1, 0, 0]
  [1, 0, 0]
原子特征:氧的one-hot编码为[1,0,0,...],氢的one-hot编码为[0,1,0,...]

优点:

  • 完整保留拓扑信息:原子的连接关系、键类型、环结构,统统在图上。
  • 适合GNN模型:图卷积神经网络(GCN)天然处理这种数据结构。
  • 可扩展性强:你可以在节点上加各种特征,比如原子质量、电负性、部分电荷。

缺点:

  • 数据稀疏:大多数原子之间没有键,邻接矩阵里大部分是0。大分子时稀疏性更明显。
  • 变长输入:不同分子原子数不同,图的大小也不一样。模型要支持动态图输入。
  • 生成困难:VAE要生成一个图,你需要同时输出节点类别和邻接矩阵,这比生成一个序列复杂得多。

我在做分子性质预测项目时,一开始用了SMILES+RNN,效果一般。后来换成图表示+GAT(图注意力网络),收敛速度快了一大截。嗯,这里要注意,图的构造质量直接影响后续模型性能——用错了键类型或者漏了氢原子,预测结果会差很多。

Morgan指纹——把分子「哈希」成固定长度的向量

有时候,我们需要一个固定维度的向量来表示分子。最经典的法子就是Morgan指纹(也叫扩展连通性指纹,ECFP)。

它的核心思想很简单:对每个原子,看它周围半径R内的子结构,然后用一个哈希函数把子结构映射成比特位。结果就是一个固定长度的0-1向量。

比如,用半径为2的ECFP4对一个分子生成1024位的指纹:

from rdkit import Chem
from rdkit.Chem import AllChem

mol = Chem.MolFromSmiles('CCO')
fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, nBits=1024)
# fp是一个长度1024的BitVector
print(fp.ToBitString())
# 输出示例:10010000001000100000000000100001...

优点:

  • 固定长度:不管你分子是大是小,指纹长度都一样(比如1024位或2048位)。
  • 计算快:RDKit里有C++后端实现,几毫秒就能算一个分子。
  • 局部结构敏感:两个分子如果有相同的子结构,它们的指纹在这些位上应该是相同的。做相似度搜索时特别好用。

缺点:

  • 信息损失:哈希过程是不可逆的。你没法从指纹反向还原出原来的分子。
  • 哈希碰撞:不同的子结构可能映射到同一个比特位。不过实践中,nBits设得足够大(比如2048),碰撞概率可控。
  • 稀疏性:1024位的向量里,活跃位通常只有几十到几百个,大部分是0。
小技巧:我一般在做分子相似度筛选或聚类时优先用Morgan指纹。但在VAE生成模型中,指纹很少直接作为输入,更多是作为辅助特征或损失函数的一部分。

三种表示法的对比

我整理了一张表,方便你快速对照:

表示法 维度 可逆性 模型友好度 典型应用
SMILES字符串 变长 可逆(标准SMILES) 适合RNN/Transformer 分子序列生成
分子图 变长 完全可逆 适合GNN/GCN 性质预测、图生成
Morgan指纹 固定 不可逆 适合MLP/相似度 虚拟筛选、聚类
工程师的选型建议:
如果你做的是序列生成(比如字符级VAE),SMILES是最直接的选择。
如果你追求更完整的结构信息,分子图是方向。
指纹则适合做快速相似度计算或辅助损失监督,不单独作为主流生成模型的输入。

本章知识结构

我把这个章节的核心逻辑整理成了一幅图,方便你理解三种表示法之间的关系:

分子表示方法的知识体系 真实分子 (C₂H₆O) SMILES字符串 CCO 分子图 (Graph) 节点=原子,边=化学键 Morgan指纹 固定长度0-1比特向量 序列生成模型 (RNN/Transformer) 拓扑建模模型 (GNN/VAE) 选择哪种表示,取决于你的模型架构和任务目标

接下来我们在课程中会重点用到SMILES和分子图这两种表示法。Smiles方便做序列生成,分子图适合做图VAE。你选哪一种,取决于你最终想要解决的问题是什么。我个人建议初学者从SMILES开始,因为工具链成熟,调试起来也方便。

一点建议:先别急着决定用哪种。等看完第4章VAE基本原理后,你会发现不同的生成目标自然决定了不同的分子表示法。