5.2 聚类、骨架分析与库多样性


文档摘要

5.2 聚类、骨架分析与库多样性 本节摘要:把分子库组织成可导航的结构,有三件工具:Butina 聚类按相似度切分区,Murcko 骨架分解盘点骨架家底,MaxMin 挑选在预算内铺满化学空间。本节讲清三者机制与参数脾气,并用"五千分子挑五百采购"的完整案例串起全部流程。 上一节解决"点对点",本节解决"全局":不设查询中心,把整个库组织成主题区、盘点家底、按预算铺设覆盖。这三件工具是库设计(买什么、合成什么)与数据集划分(第6章建模前怎么分组)的共同基础。 一群分子怎么分成几堆 聚类在分子库上的主流做法与前述相似性底座严丝合缝。

5.2 聚类、骨架分析与库多样性

本节摘要:把分子库组织成可导航的结构,有三件工具:Butina 聚类按相似度切分区,Murcko 骨架分解盘点骨架家底,MaxMin 挑选在预算内铺满化学空间。本节讲清三者机制与参数脾气,并用"五千分子挑五百采购"的完整案例串起全部流程。

上一节解决"点对点",本节解决"全局":不设查询中心,把整个库组织成主题区、盘点家底、按预算铺设覆盖。这三件工具是库设计(买什么、合成什么)与数据集划分(第6章建模前怎么分组)的共同基础。

一群分子怎么分成几堆

聚类在分子库上的主流做法与前述相似性底座严丝合缝。Butina 聚类(文献里也称 Diamond-Broker 风格的中心聚类)是化学信息学的本地特产:算好全库两两距离后,先给每个分子数一数"近亲数量"(距离小于阈值的邻居数),从社交最广的分子开始,把它和它的近亲圈成一个簇、整体撤出,再选下一个社交最广的,直到无人圈养。它的好处是不需要预设簇数、天然产出簇心(每个簇的分子就是"代表"),代价是要一次算全距离矩阵——几千到几万个分子可行,十万级就要换近似方法。

阈值是 Butina 的灵魂旋钮:距离阈值取小,簇碎而多(每个簇很小,代表性强但分区琐碎);取大,簇大而松(区少但簇内化学异质)。没有万能值,惯用做法是扫一组阈值看簇数曲线,结合业务口径("我们想要大约二十个主题区"还是"要三百个微簇")拍板。对比一下k-均值:它要求预设簇数、天然偏向球形簇,在描述符空间里用得多,在指纹空间里因质心无意义而水土不服——指纹是比特串,没有"平均分子"这种东西。

验骨架:Murcko 分解

骨架分析回答另一个维度的问题:"这个库在骨架层面重复建设了多少?"Murcko 分解把每个分子剥去侧链,留下环系与连接链构成的核心骨架(乙酰水杨酸的骨架是联苯环系骨架)。对全库分解后统计骨架频率,常常能暴露惊人的集中度——不少历史库的前十个骨架占据三成以上分子,都是当年某个成功系列留下的"恐龙化石层"。

骨架统计的判读口径:骨架集中度高不必然是坏事——项目聚焦某个系列时集中是常态;坏事的是"无意识的集中",即采购与合成从未审视过骨架分布。修正手段也直接:骨架分桶,每桶限额取样,或在下轮采购的多样性约束里加入骨架新颖度。

图 5-2:从指纹云到采购清单的三条路

图 5-2:从指纹云到采购清单的三条路

案例:五千分子挑五百采购

背景。采购预算只够买五百个样品,候选池五千个分子(已过类药过滤)。目标有两个:覆盖尽量多的化学空间(多样性),且每个区域选出的分子在区内有代表性(代表性)——只顾前者会挑出一堆孤僻的怪分子,只顾后者会买一堆近亲。

操作。Butina 聚类定基调,MaxMin 在簇内与全局补多样性:

from rdkit import Chem from rdkit.Chem import AllChem, DataStructs # 1) 全库指纹与距离矩阵 fps = [AllChem.GetMorganGenerator().GetFingerprint(m) for m in mols] # 五千个分子 n = len(fps) dism = [[1 - DataStructs.TanimotoSimilarity(fps[i], fps[j]) for j in range(i + 1, n)] for i in range(n - 1)] # 2) Butina 聚类:阈值 0.4(相似度 0.6 以上算近亲) from rdkit.ML.Cluster import Butina clusters = Butina.ClusterData(dism, n, 0.4, isDistData=True) print("簇数:", len(clusters)) # 典型输出:六百上下 print("最大簇规模:", len(clusters[0])) # 3) MaxMin:贪心挑五百个彼此远离的分子 from rdkit.SimDivFilters import rdSimDivPickers picker = rdSimDivPickers.MaxMinPicker() picked = picker.LazyBitVectorPick(fps, n, 500) print("已选:", len(picked))

结果。阈值零点四下五千分子聚出六百个左右的簇,最大簇数百上下(通常是某类常见骨架家族);MaxMin 的五百个选中分子在指纹距离上彼此远离,逐簇落点均匀,骨架终检显示选中集的骨架数接近簇数——没有哪个系列垄断名额。

解读。流程里藏着三次取舍。聚类阈值零点四不是算出来的,是业务口径翻译出来的("六百个主题区"恰好与预算五百同量级,保证多数簇能分到一个名额);MaxMin 挑选对簇内代表性是间接保障(起点用簇心可强化),严格的做法是"每簇先 MaxMin 配额、再跨簇平衡"的两级挑选;骨架终检是防呆——指纹多样性不保证骨架多样性,两个指纹远距离的分子可能共享同一骨架,最后的骨架表兜住这种遗漏。

变式。预算改变策略不变但参数变:预算提高到两千,阈值应放宽(零点五)让簇变大,或直接跳过聚类用 MaxMin 全局挑选。任务换成建模数据集划分时(第6章),聚类还有个隐藏用途——按簇划分训练集与测试集,逼模型面对"没见过的骨架"外推,测出来的性能比随机划分诚实得多。

聚类的第二个用途:诚实的建模数据集划分

聚类的技能清单里还有一项常被漏记:给第6章的建模提供按簇划分的数据集切分。

随机划分训练集与测试集的漏洞(近亲泄漏)在 6.2 节已经审过;Butina 聚类给出了修补的标准工序:先按指纹把全库聚簇,再按为单位分到训练集与测试集——同一簇的分子同进同出,测试集因此由"模型没见过的新化学区"组成。参数上,簇数越多划分越细、测试集越接近随机划分;想要最严格的外推评估,就粗聚成几十个大簇,把整片化学空间留给测试。这套划分还有个诊断价值:若模型在簇划分下成绩骤降,降幅集中在哪些簇,答案直接告诉你模型的外推弱点在哪个化学区——比一个孤零零的 RMSE 数字有营养得多。

同样的逻辑沿用到第8章依然成立:深度模型时代,簇划分升级为"骨架划分加批次划分"的双保险(同一实验批次的分子也同进同出),因为批次效应是深度模型最爱钻的又一条近亲通道。

本节要点回顾

  • Butina 三板斧:数近亲、选社交王、整体撤出——不预设簇数、自带代表,是化学库聚类首选。
  • 阈值即口径:阈值翻译业务需求,扫阈值看簇数曲线再拍板,别迷信默认值。
  • 骨架表防呆:Murcko 分解暴露无意识的重复建设,指纹多样性兜不住骨架多样性。
  • 挑选是代表性加多样性的双目标:聚类定基调、MaxMin 铺覆盖、骨架终检,三道工序各管一段。
  • 下一站:排架完成、检索在手,第6章给书架装上"荐书引擎"——QSAR 建模把相似性升级成可量化的活性预测。

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