2.2 分子图与连接表


文档摘要

2.2 分子图与连接表 本节摘要:在机器内部,分子既不是字符串也不是图片,而是图——原子是顶点,键是边。本节讲清连接表如何组织这张图、图同构为什么是子结构检索的成本大头,以及工业检索"指纹粗筛加精确匹配"组合拳的原理。读完你将能徒手读 MOL 文件、用 RDKit 遍历分子图,并解释亚结构查询为何要预筛。 上一节把字符串交给了解析器,本节走进解析器的输出物:分子图。这是全册技术含量最高的一块地基——第4章的指纹是对图的压缩编码,第5章的相似性是对图的比较,第8章的图神经网络更是直接在图上做机器学习。看不懂图,后面全是黑箱;看懂了图,后面全是常识。 邻接表里住着苯环 打开一个 MOL 文件(连接表格式),你会看到三段:头部注释行、原子块、键块。原子块每行一个原子——横纵坐标、元素符号;

2.2 分子图与连接表

本节摘要:在机器内部,分子既不是字符串也不是图片,而是图——原子是顶点,键是边。本节讲清连接表如何组织这张图、图同构为什么是子结构检索的成本大头,以及工业检索"指纹粗筛加精确匹配"组合拳的原理。读完你将能徒手读 MOL 文件、用 RDKit 遍历分子图,并解释亚结构查询为何要预筛。

上一节把字符串交给了解析器,本节走进解析器的输出物:分子图。这是全册技术含量最高的一块地基——第4章的指纹是对图的压缩编码,第5章的相似性是对图的比较,第8章的图神经网络更是直接在图上做机器学习。看不懂图,后面全是黑箱;看懂了图,后面全是常识。

邻接表里住着苯环

打开一个 MOL 文件(连接表格式),你会看到三段:头部注释行、原子块、键块。原子块每行一个原子——横纵坐标、元素符号;键块每行一条键——两个原子的编号与键级。下面是乙醇的最小连接表(省略了固定格式的列对齐):

atoms(原子块) C -0.0141 0.8240 0.0000 # 1 号原子:甲基碳 C 0.7705 -0.4491 0.0000 # 2 号原子:亚甲基碳 O -0.0263 -1.2690 0.0000 # 3 号原子:羟基氧 bonds(键块) 1 2 1 # 1-2 之间单键 2 3 1 # 2-3 之间单键

仅此而已——没有环号、没有括号、没有隐式氢的谜题,一切都在表里。用图的术语重述:原子块是顶点集,键块是边集,坐标只是顶点的可选属性。程序里最常用的组织方式是邻接表:每个原子挂一个列表,记录它与哪些原子相连、键级几何。遍历邻居、做深度优先搜索、找环,都顺着这张表走。

图 2-2:同一个分子的三种形态

图 2-2:同一个分子的三种形态

三种形态信息等价,但提问成本天差地别:"分子里有没有苯环上带羟基的片段",在字符串上几乎无法回答,在邻接表上是一个标准的图匹配问题。

图同构:精确比对的本质与代价

"两个分子是不是同一个"在图上是图同构问题;"这个片段是不是那个分子的一部分"是子结构同构问题。后者是前者的推广,计算复杂度在最坏情况下是指数级的——查询图的每一个原子都可能匹配目标图的任何一个同类原子,组合爆炸随分子规模陡增。日常小分子感觉不到慢,是因为分子图很小、元素种类天然剪枝;一旦查询模式复杂、目标库上了百万级,全库精确匹配就变成不可承受的开销。

工业界的解法不是发明更快的同构算法,而是避免对大多数分子做精确匹配:先用廉价的有损比较排除掉绝大多数不可能的分子,只对剩下的极小候选集做精确图匹配。有损比较用的就是指纹——把结构特征逐位编码成比特串,两个比特串按位比较就能以极低成本断定"不可能匹配"。指纹的构造细节在第 4.2 节展开,这里只需要接受结论:指纹预筛把 O(全库)的精确匹配压缩成 O(极小候选集)的精确匹配加上 O(全库)的位运算,后者比前者快几个数量级。

案例:给子结构查询装上预筛器

背景。假设我们要在一万个分子的内部库里回答:"哪些分子含有羧酸片段?"这是药化登记、杂质排查、库设计里的高频查询。目标是理解检索工具内部发生了什么,而不是背函数名。

操作。先定义查询模式(SMARTS 语法,可理解为"带通配符的 SMILES"),再分别用直接匹配与两步匹配跑一遍:

from rdkit import Chem library = [ "CC(=O)Oc1ccccc1C(=O)O", # 阿司匹林,含羧酸 "CC(C)Cc1ccc(cc1)C(C)C(=O)O", # 布洛芬,含羧酸 "CN1C=NC2=C1C(=O)N(C)C(=O)N2C", # 咖啡因,不含羧酸 "OC(=O)CC(=O)O", # 琥珀酸,两处羧酸 ] patt = Chem.MolFromSmarts("C(=O)O") # 羧酸与酯基共同的碳氧骨架 direct = [s for s in library if Chem.MolFromSmiles(s).HasSubstructMatch(patt)] print(direct) # 命中含羧酸或酯的分子:阿司匹林、布洛芬、琥珀酸 # 两步法示意:先按分子式排除(示意层面的廉价预筛) formulas = {s: Chem.rdMolDescriptors.CalcMolFormula(Chem.MolFromSmiles(s)) for s in library} print(formulas) # 每个分子一次 O 原子计数,成本远低于逐键图匹配

结果。直接匹配返回三个分子。注意一个精细之处:模式 C(=O)O 匹配的不只是羧酸——阿司匹林的酯基同样满足这个拓扑。若业务上只要游离羧酸,模式应收紧为 C(=O)[OX2H1]。查询语言的精度,取决于你对模式语义的把握。

解读。这一小段代码演示了检索系统的分层哲学:SMARTS 定义"要什么",指纹预筛负责"快速排除",子结构匹配负责"最终确认"。真实的百万级库检索中,预筛通常会排除九成以上分子,精确匹配只碰剩下的零头。代价是指纹偶尔"漏筛"(它是有损编码),所以最终答案永远以精确匹配为准——宁可慢一点,不可错一点,这是检索与建模在哲学上的分野

变式。把查询从"找片段"升级为"找相似"(片段放宽为整体拓扑的近似重合),精确匹配彻底退场,全靠指纹与相似系数打分排序——那是第 5.1 节的主题。再变一步:查询对象从静态结构换成"可反应的位置"(比如只找芳环上邻位无取代的氯),SMARTS 配合环境原子描述符同样能表达——查询语言的表达力,常被初学者严重低估。

从邻接表出发的两个日常问题

图表示的两桩日常应用,值得单独一提,因为它们是更高级操作的零件。

环感知。"哪些原子在环上、环有多大、几个环共享一条边"——顺着邻接表做深度优先搜索即可回答,它是芳香性感知(2.1 节解析流水线)、Murcko 骨架分解(5.2 节)与环系描述符(4.1 节)的共同前置。实现要点是把"树边"与"回边"分开:回边即环的 closure,从一个回边出发绕回起点就走出了一个环。原子等价类。"这几个原子在图上等价吗"——通过规范算法(摩根算法的直系应用)给原子打上对称性标签。它最实用的场景是规范化与映射:SMILES 规范化时选择从哪个等价类开始遍历,等价类保证写法唯一;反应原子映射(9.1 节)与 NMR 谱峰归属这类"认原子"的任务,第一步都是等价类。这两桩应用的共同启示:邻接表加基础图算法,已经能回答化学信息学里一大半"结构层面"的问题——高级框架解决的是效率与规模,不是可能性。

本节要点回顾

  • 分子即图:原子块加键块的连接表是机器内分子的真实形态,坐标只是可选属性。
  • 同构本质困难:子结构匹配最坏指数复杂度;日常感觉快,是因为分子小、剪枝强。
  • 组合拳原理:指纹做有损粗筛,图匹配做精确确认;预筛让全库检索从不可能变成毫秒级。
  • 模式语义决定精度C(=O)OC(=O)[OX2H1] 差一个羟基,结果就差出酯类一大家子。
  • 下一站:图还缺一样东西——空间。2.3 节给原子装上坐标,处理手性与构象这些二维看不见的事实。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U