4. 分子片段划分方法:BRICS算法、官能团匹配、自定义子结构划分

好,咱们进入正题。上一章我讲了为啥要把大分子拆成小片段,这一章就聊聊具体怎么拆。说白了,分子片段划分就是把一个完整的分子图,切成一堆有意义的子图。切法不同,后面的注意力热图结果也会差很多。

我自己的经验是,这个环节特别容易翻车。你想想看,切得太粗,片段里边还混着各种官能团,那热图基本看不出啥规律;切得太细,一个甲基一个羟基都被拆开,又失去了化学语义。所以找对划分方法,是整条技术链的基石。

业内常用的方法有这么三类:BRICS算法、官能团匹配、自定义子结构划分。咱们一个一个说。

4.1 BRICS算法:自动拆解的行业标准

BRICS 的全称是 Breaking of Retrosynthetically Interesting Chemical Substructures。名字挺长,但意思很简单——它模仿有机合成化学家逆合成分析的思路,找到那些容易断裂的化学键,然后咔嚓一下切开。

我当年第一次用 BRICS 处理一个激酶抑制剂数据集,结果让我挺意外。它把一个复杂的杂环骨架完整保留了下来,只切掉了外围的取代基。这种天然的层次感,特别适合后面做自注意力分析。

BRICS 内部维护了一套预定义的裂解规则,大概有 16 类可断裂键。比如酯键、酰胺键、醚键这些,都是它重点关注的对象。

BRICS 裂解规则示例(SMARTS 模式):
# 酰胺键断裂
[C:1](=[O:2])-[N:3]  ->  [C:1](=[O:2])  +  [N:3]

# 酯键断裂
[C:1](=[O:2])-[O:3]  ->  [C:1](=[O:2])  +  [O:3]

# 醚键断裂
[C:1]-[O:2]-[C:3]   ->  [C:1]-[O:2]  +  [C:3]
个人习惯:我会先用 BRICS 跑一遍全数据集,看每个片段出现的频率。低于 5 次的片段我通常直接过滤掉,不然注意力图里会冒出太多孤零零的噪声点。
特性 说明
划分依据 逆合成可断裂键 + 保护策略
优点 自动化、可重复、化学语义强
缺点 对非标准键处理差、过度裂解
适用场景 高通量筛选、骨架跃迁分析
分子片段划分方法对比流程 完整分子图 BRICS 算法 逆合成裂解规则 官能团匹配 SMARTS 模板库 自定义子结构 专家规则 + 手动指定 片段集合 注意力热图输入

4.2 官能团匹配:基于模板的精准切割

官能团匹配的方法更直观。你预先定义好一组化学官能团的SMARTS模式,然后用RDKit之类的工具去分子上找匹配。匹配到的地方,就作为一个独立的片段摘出来。

举个例子,假设你对羰基、羧基、苯环这块特别感兴趣,那就定义对应的SMARTS模板。跑一遍匹配,所有命中位置就变成了片段边界。

from rdkit import Chem
from rdkit.Chem import FragmentCatalog

# 定义官能团模板库(部分)
func_group_smarts = {
    'carbonyl': '[CX3]=[OX1]',
    'carboxyl': '[CX3](=[OX1])[OX2H1]',
    'amino': '[NX3;H2,H1;!$(NC=O)]',
    'phenyl': 'c1ccccc1'
}

mol = Chem.MolFromSmiles('CC(=O)Nc1ccc(O)cc1')
for name, smarts in func_group_smarts.items():
    patt = Chem.MolFromSmarts(smarts)
    matches = mol.GetSubstructMatches(patt)
    print(f'{name}: {matches}')
我曾经踩过的一个坑:SMARTS 模式写得不够严谨,导致把吡啶环误认为苯环。后来我养成了习惯,每个模板都要配合氢原子计数和环类型检查,不然出来的片段化学意义会扭曲。

官能团匹配的好处是可控性强。你做药物化学分析时,往往只关心特定的药效团片段。这时候 BRICS 那种暴力裂解反倒多余。我个人习惯在这样的场景下优先用官能团匹配。

4.3 自定义子结构划分:专家知识的落地

有时候,既有的算法和模板都不够用。比如你的分子是一个天然产物,结构里有个独特的螺环骨架,BRICS 可能把它切得七零八落,官能团模板也匹配不上——那就只能自己动手。

自定义子结构划分说白了就是:你指定哪些原子属于片段 A,哪些属于片段 B。RDKit 提供了 GetSubstructMatch 和 ReplaceSubstructs 这类底层接口,可以让你手动实现任意切法。

# 手动指定原子索引划分片段
mol = Chem.MolFromSmiles('C1CC(=O)NC1')
# 我想把羰基碳(C3)单独作为一个片段
frag_atoms = [[0,1,3,4], [2]]  # 两个片段
frags = Chem.GetMolFrags(mol, asMols=True, sanitizeFrags=False)

for i, frag in enumerate(frags):
    smi = Chem.MolToSmiles(frag)
    print(f'Fragment {i}: {smi}')
我的一个小窍门:自定义划分时,建议先用可视化工具(比如PyMOL或RDKit的Draw)把分子画出来,手动标好原子序号再写代码。盲写索引很容易搞错环系统。

这种方法的灵活性最高,但代价也很明显——无法自动化。处理几百个分子还行,几万个就不现实了。所以通常只在构建小规模高精度测试集时使用。

4.4 三种方法对比与选型建议

维度 BRICS 官能团匹配 自定义子结构
自动化程度 高,全自动 中,需定义模板 低,手动指定
化学语义保真度 高(合成路径合理) 中(依赖模板质量) 最高(完全控制)
大规模处理能力 强 强 弱
过切风险 中 低 无(手动控制)
适用阶段 初期探索、批量处理 中期聚焦、药效团分析 后期精调、验证集构建

我的建议是:先用 BRICS 跑通全流程,在热图上发现特定区域关注度异常高时,再用官能团匹配缩小范围。最后如果需要验证某个新假设,比如某个罕见杂环的注意力机制,那就用自定义子结构来精确定位。

说白了,这三类方法不是互斥的,而是递进的。工程师思维就是——先拿到结果,再迭代优化。