第二章 · 2.5

2.5 摩根指纹与 Tanimoto 系数:相似性的度量

Morgan Fingerprints and Tanimoto Similarity
指纹把变长的分子图压成定长位向量,为相似性计算提供表示。本节从词典指纹的覆盖局限引出扩展连接性指纹:原子标识符沿邻域逐轮哈希、滚动扩张成圆形子结构集合,再折叠为位向量;正文给出折叠位数的生日问题定量分析与碰撞的系统性偏差,定义 Tanimoto 系数及其与 Dice、Tversky 的亲缘,以相似性质原理统摄相似性搜索。

2.5.1 从词典到无词典:指纹的谱系与动机

“指纹(fingerprint)”泛指把变长的分子图映射为固定形式向量的编码——最常见的是定长位向量(bit vector),计数向量与不定长的稀疏表示也属此列:出现某个子结构,就在相应位置 1 或计数。位向量把“两个分子有多像”变成“两个集合的交并之比”,按位逻辑运算代价极低,百万级分子库的相似性检索因而可行(Willett et al., 1998)。第一代实现是词典指纹(dictionary-based fingerprint):预先编纂一张子结构清单,每个键对应一位。用得最久的是 MACCS 键——公开版本含 166 个子结构,键语义预定义、逐条可查(RDKit 的实现里绝大多数键就是一条 SMARTS,个别键如 125、166 需在程序里特殊处理)。词典指纹的长处是彻底透明:哪一位亮,去清单上就能查到分子含什么。短板同样是结构性的:词典之外的结构不产生任何位,覆盖被清单封顶;大环、肽、金属有机等化学型常常落在清单之外;词典靠人工维护,扩充缓慢而昂贵。

第二代走向自动枚举。路径指纹不再依赖人工清单,沿分子图枚举所有不超过给定长度的路径(原子—键序列),每条路径哈希成一位。覆盖不再受词典限制,但仍由枚举策略决定:经典路径枚举是线性的,分支与环系只能间接表达(RDKit 的拓扑指纹默认也纳入带分支的子图,branchedPaths 参数可关——枚举策略的边界要看具体实现)。第三代圆形指纹(circular fingerprint)换了参照系:不再枚举“什么样的子结构算数”,而是对每个原子问“你的邻域是什么”。谱系要回溯到 Morgan(1965)在化学文摘社的工作。原始 Morgan 算法的目标不是相似性,而是规范编号(canonical numbering):给同一分子的任何画法生成同一套原子编号。做法是迭代精化——按“自身属性 + 邻居的当前等级”反复重排原子类别,直到划分稳定。Rogers 与 Hahn(2010)据此提出扩展连接性指纹(extended-connectivity fingerprint, ECFP):把同一套邻域迭代改造成指纹生成器,不迭代到收敛,而是每轮截断一次,把中间结果记录为整数标识符(identifier)。词典指纹“覆盖什么”的难题,从此变成一个干净的参数:看多远。

注记

Morgan、ECFP 与 RDKit 的名实。RDKit 把自家的圆形指纹叫 Morgan fingerprint,是对 1965 年原始算法的致敬;ECFP 之名则来自 Rogers 与 Hahn 的论文及其在原 Accelrys 软件中的实现。三者思想同源,细节各异:原子不变量的取项、哈希的具体构造都有出入。工程口径上“Morgan 指纹、半径 2、2048 位 ≈ ECFP4”可以接受,但跨工具生成的指纹不可直接比较——A 工具的“位 1187”与 B 工具的“位 1187”没有任何对应关系。

表 2.5-1三代指纹范式的对比
范式覆盖来源主要参数可解释性代表
词典指纹预定义子结构清单几乎不可调(键固定)逐键透明:一位对应清单里的一条MACCS 166 键
路径指纹图上枚举的路径/子图路径长度上限、位数路径可回溯Daylight 指纹
圆形指纹每个原子的邻域,按需生成半径、位数、原子不变量取项来源可回溯(需原分子与生成信息)ECFP / Morgan

从词典指纹到圆形指纹,子结构覆盖由预先定义的清单转为分子邻域的逐层枚举。ECFP 可用于检索与建模;若要解释具体比特的来源,还应保存原子环境信息,并检查哈希和折叠碰撞。

2.5.2 ECFP 的四步算法:初始化、迭代、收集、折叠

ECFP 的生成可以拆成四步:初始化、迭代、收集、折叠(Rogers & Hahn, 2010)。先立定义,再逐步展开。

定义

扩展连接性指纹。对分子中每个原子 v、每个半径 r ∈ {0, 1, …, R},把“以 v 为中心、r 步之内的圆形邻域”——中心原子属性,加上逐层纳入的邻居与键级——哈希成一个整数标识符 idr(v)。哈希保证相同环境必得相同标识符,不保证不同环境必得不同标识符:标识符是对原子环境的哈希编码,不保证全局唯一(ECFP 原文对此有专门讨论)。全部候选标识符经冗余消除与合并后组成特征集合,即该分子的 ECFP;集合折叠成定长位向量,即常用的位指纹。半径 R 是唯一的主要自由度。

第一步:初始标识符。给每个原子写一张属性卡:元素、重原子连度、显式价、形式电荷、连接氢数、环隶属……(2.1 节的节点属性正派上用场)。把这张元组 τ(v) 哈希成一个 32 位整数:

\[id^{0}(v) = h( \tau(v) ) \quad \tau(v) = (\text{元素}, \text{连度}, \text{显式价}, \text{形式电荷}, \text{氢计数}, \text{环隶属}, \dots )\]
(2.5-1)h 为整数哈希函数。保证是单向的:同一元组必得同一整数(确定性)、同构环境给出同一值;反过来不成立——不同元组仍可能撞出同一整数,这是哈希的本性,与后面的折叠无关。标识符首先是不变量,其次才是整数。

哈希在这里不是加密,而是把结构化的不变量压成可比较、可存储、可作字典键的整数。元组的取项决定指纹“看得见”什么:RDKit 默认的连接性不变量就包含形式电荷;若换用不含电荷的不变量,质子化差异也未必完全隐形——氢数等属性往往随质子化一同改变。含同位素项时,氘代才可分辨。取项是设计决策,不是实现细节。

第二步:迭代更新。第 k 轮,每个原子把上一轮邻居的标识符连同键级收进来,与自身上一轮的标识符一起再哈希一次:

\[id^{k}(v) = h( id^{k-1}(v), { ( b(v,u), id^{k-1}(u) ) : u \in N(v) } )\]
(2.5-2)b(v,u) 是 v 与邻居 u 之间键的键级;N(v) 是 v 的邻居集合;花括号为多重集 ⊎——允许重复、不计次序。第 k 轮后,idk(v) 编码的是以 v 为中心、半径 k 的圆形邻域。

两个机理要点。其一,邻域滚动扩张:第 1 轮标识符编码“我 + 直接邻居”,第 2 轮编码“我 + 邻居 + 邻居的邻居”(图 2.5-1)。迭代次数即半径,这正是“扩展连接性”的含义。其二,多重集的引入并非修辞:邻居以什么次序进入哈希,结果必须相同,否则同一分子换一种原子编号就得到不同指纹。这与 1.2 节的置换不变性、2.4 节图不变量的要求一脉相承——Morgan 式迭代本身就是逐轮精化的图不变量,图论中的 WL 顶点精化算法是它的同族。

以中心碳原子为原点,半径 0、1、2 的圆形邻域与各轮标识符的构成 半径 2 半径 1 半径 0 N C C O 中心原子 第一层邻居 第一层邻居 第二层邻居 半径 0 · 迭代 0 id0 = h(原子属性元组) 半径 1 · 迭代 1 id1 = h(id0 ⊎ 邻居 id0) 半径 2 · 迭代 2 id2 = h(id1 ⊎ 邻居 id1) 相同环境必得相同标识符(单向保证) 迭代每轮把邻域向外滚动一层; 邻居以多重集进入哈希,次序无关。 第 k 轮标识符吃进第 k−1 轮全部邻居的信息:环境滚动扩张,1.2 节的置换不变性由多重集聚合保证。 两个原子若环境完全相同,标识符相同——分子内去重后进入指纹(第三步:收集)。
图 2.5-1 ECFP 的圆形邻域与迭代。以中心碳原子(深色描边)为原点:半径 0 只含中心自身的属性元组;半径 1 纳入直接邻居与键级;半径 2 再向外一层。第 k 轮把邻居的上一轮标识符聚合进哈希,标识符编码的环境随之扩张;多重集聚合与邻居列举次序无关。右栏为各轮标识符的构成,⊎ 表示多重集并。

第三步:收集。先把每个原子在每一轮的候选标识符都收进来:半径 0 到 R,每原子 R+1 个。原始 ECFP 在此还有一道结构冗余消除:两个环境若覆盖完全相同的键集合,即便标识符不同,也按规则只保留其一(RDKit 默认同样去冗余,includeRedundantEnvironments 选项可保留全部)。环境完全相同的原子给出相同标识符,合并相同 ID 后即特征集合;若改而保留每个标识符的出现次数,得到计数版本(ECFC),信息更多,位向量则一律只记“出现与否”。半径 2 下,典型药物分子有几十个互不相同的圆形子结构——指纹的大小随分子复杂度自然伸缩,这正是无词典设计的好处。

第四步:折叠。整数集合不定长,按位运算也不方便,于是把每个标识符映射到定长位向量的某一位并置 1:

\[bit(id) = id mod L \quad L \in {1024, 2048, \dots };\text{对应位置} 1\]
(2.5-3)L 为折叠位数。模运算丢弃整数的高位、只保留余数——压缩是有损的:一个位可被多个标识符共享(图 2.5-2)。

折叠的收益是定长与高效:两个 2048 位向量的交、并、异或都是常数条机器指令。代价——碰撞——是本节后半的主角,先在图 2.5-2 里看清它的几何。

四个 32 位子结构标识符经 mod 2048 折叠到定长位向量,其中两个不同标识符同落一位 子结构标识符(32 位整数) 折叠指纹(2048 位,示意 3 个置位) 1818625187 1843200443 2048001187 3072002023 位 445 位 2023 位 1187(碰撞) 折叠:bit = id mod 2048(有损压缩) 折叠只保留 id mod L 的余数:整数标识符有分辨力的高位被丢弃,压缩是有损的。 两个不同子结构同落一位,位向量无从区分——相似度从此带上系统性偏差(2.5.4 节)。
图 2.5-2 折叠与碰撞。四个 32 位标识符经 mod 2048 映到三个位:1 818 625 187 与 2 048 001 187 的余数同为 1187,两个不同的圆形子结构共享一位。位条按比例示意 2048 位指纹,深色方块为置位。

下面用一对只差一个原子的分子印证上述流程:半径 2(两轮迭代)加 2048 位折叠,注释对应各步骤。Tanimoto 系数(Tanimoto coefficient)的正式定义在 2.5.6 节,这里先看数值形态。

from rdkit import Chem
from rdkit.Chem import rdFingerprintGenerator, DataStructs

gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048)  # 半径2=两轮迭代;2048=折叠位数
m1 = Chem.MolFromSmiles("c1ccccc1CCO")   # 2-苯乙醇
m2 = Chem.MolFromSmiles("c1ccccc1CCN")   # 2-苯乙胺:末端 O 换成 N
fp1, fp2 = gen.GetFingerprint(m1), gen.GetFingerprint(m2)
print(fp1.GetNumOnBits(), fp2.GetNumOnBits())      # a 与 b:折叠后的置位数
print(len(gen.GetSparseCountFingerprint(m1).GetNonzeroElements()),
      len(gen.GetSparseCountFingerprint(m2).GetNonzeroElements()))
# 未折叠特征数(本例 16 = 16:这对分子内部没有发生折叠合并;换分子就未必)
print(DataStructs.TanimotoSimilarity(fp1, fp2))    # c/(a+b−c) ≈ 0.52:一原子之差即明显小于 1

两个分子只在末端差 O 与 N,多数圆形子结构仍然相同,置位大量重叠;但含末端原子的环境不同,交就不是全集,相似度明显小于 1(本例两分子折叠前后置位数同为 16——折叠有没有吞并特征因分子而异,须对照未折叠表示才知道)。一个原子的改写只扰动“以它为中心的那些环境”——半径 2 时至多波及它两步以内的中心。指纹对局部改动的响应是局部的,这一性质在后面的章节反复出现。

2.5.3 参数的语义:半径与位数

命名习惯里,ECFP 的下标是直径而非半径:ECFP4 指直径 4 条键,即半径 2、两轮迭代;ECFP6 对应半径 3。RDKit 摩根指纹的 radius 参数就是半径,radius=2 与 ECFP4 相当。半径是“分辨率”旋钮:半径 0–1 看见官能团与一阶环境,对电性、氢键供受体敏感;半径 2–3 看见骨架片段,对整体拓扑敏感。半径越大,稀有环境越多、区分度越高,但对局部变化也更敏感。变体 FCFP 把原子属性换成药效团(pharmacophore)类别(氢键供体、芳香环……),“看什么”随之改变。

半径的影响可以用取代苯看清楚——先看实测,别信示意图的直觉。邻、间、对二甲苯在半径 0 下的特征集合完全相同(三种原子环境而已);到半径 1,未折叠标识符集合已经分成三样:7、8、6 个特征,两两集合交并比约在 0.63–0.75——默认原子不变量不止元素一种:取代基附着碳与带氢碳的度数、氢数在初始标签就不同,一轮邻域聚合把部分连接模式区分开。哪些异构体在哪个半径能分开,取决于初始不变量、特征聚合方式与是否保留计数,不能只凭邻域画法下结论。总的趋势仍然成立:官能团层次的分辨要小半径,骨架与位置的分辨要大半径——半径不是越大越好,而是要与“想看见的化学差异”匹配。

位数 L 是另一个旋钮,它的后果可以用生日问题(birthday problem)精确刻画。m 个互不相同的标识符独立均匀落入 L 位,至少两位相撞的概率为:

\[P_{\text{碰撞}}(m, L) = 1 - \prod_{i=0}^{m-1} (1 - i/L) \approx 1 - e^{-m(m-1)/(2L)}\]
(2.5-4)指数近似来自对乘积取对数后的一阶展开,要求 m/L 较小;若要求近似给出的无碰撞概率相对误差小,常用的充分条件是 m³/L² ≪ 1,而不是 m ≪ L²。直觉的陷阱:碰撞不要求某个特定标识符撞上另一个特定标识符,只要求 C(m,2) 对中任何一对相撞——对数按 m² 增长。碰撞概率过半只需 m ≈ √(2L ln 2):L=2048 时约 54 个标识符。注意“至少一次碰撞”≠“表示已被显著破坏”:m=54 时期望被合并的特征数还不到一个(习题 2.5-1)。

一个中型分子库的不同子结构数以万计,折叠位向量必然布满碰撞——但全库层面的碰撞不等于每个分子对都受伤:一对分子的相似度误差,只取决于实际出现在这两个分子里的特征如何相撞。位数的取舍要看碰撞规模、相似度误差、排序稳定性与下游任务(2.5.4 节),不能只看“是否发生过碰撞”。位数从 2048 提到 4096、8192,过半门槛只抬高 √2 倍、2 倍——按位数对抗生日悖论,推迟而非消除。

习题 2.5-1

某化合物库经 ECFP4 计算后共得到 m = 10⁴ 个互不相同的子结构标识符,折叠到 L = 2048 位,设各标识符独立均匀落入每一位。(1) 写出至少一次碰撞的概率公式并给出指数近似与数值;(2) 求碰撞位置对的期望数;(3) 求碰撞概率首次超过 1/2 的最小标识符数 m*;(4) 若把位数提高到 L = 2²⁰ = 1 048 576,碰撞是否可以忽略?这说明什么?

参考解答

(1) m = 10⁴ > L = 2048,对象数超过位置数,按抽屉原理至少一次碰撞的概率严格等于 1,无须近似;指数近似 P ≈ 1 − e−m(m−1)/(2L) 给出同一结论:标识符对数 C(m,2) = 10⁴ × 9999 / 2 = 4.9995×10⁷,除以 2048 得 λ ≈ 2.44×10⁴,P ≈ 1 − e−24412 ≈ 1。(2) 每一对以 1/L 的概率同位,期望碰撞对数 = C(m,2)/L ≈ 24 412 对——注意这是全库特征层面的账,摊到每个分子对要小得多。(3) P ≥ 1/2 ⟺ m(m−1)/(2L) ≥ ln 2,即 m* ≈ √(2L ln 2) = √(2×2048×0.6931) ≈ 53.3,取 54;精确计算约 50.6%。但把握解读尺度:m=54 时期望占用位数为 L[1−(1−1/L)m] ≈ 53.3,平均被合并的特征只有 54 − 53.3 ≈ 0.69 个,占 1.3%——“过半概率至少一次碰撞”与“半数信息损失”是两回事。(4) λ = 4.9995×10⁷ / 1 048 576 ≈ 47.7,P ≈ 1 − e−47.7 ≈ 1,仍不可忽略。位数翻倍只能推迟、不能消除折叠碰撞;不折叠标识符集合则彻底去掉折叠这一步(哈希自身的碰撞概率低得多,2.5.4 节)。

2.5.4 碰撞的机理与后果

碰撞来自折叠操作:折叠把“哪个子结构”压缩成“落在哪一位”,不同的子结构可以共用落点。后果不是随机噪声,而是系统性偏差,两个方向同时起作用。其一,交叉碰撞制造假共享:分子 A 的子结构 x 与分子 B 的子结构 y 同落一位,位向量只看到“两位都亮”,把它记入交 c——真实的子结构交集中并没有这一项。其二,分子内碰撞压缩置位数:同一分子两个不同子结构共位后只贡献一个 1,a、b 变小——注意在位数固定时,置位数减少意味着位密度 a/L 下降;“指纹越短、典型位密度越高”是另一个方向的比较(同一批分子折进更少的位)。两个方向的净效应,在典型数据分布上呈现为相似度高估:Swamidass 与 Baldi(2007)把它表述为折叠的系统误差并给出修正公式。但“典型高估”不是逐对成立的定理——若两个共享特征折叠后合并成一位、其余不撞,相似度反而降低({x, y, u} 对 {x, y, v} 原为 2/4 = 0.5,x 与 y 同位后变 1/3)。偏差的方向与大小要看实测:RDKit 开发者的抽样比较显示,半径 2、1024 位相对未折叠表示,Tanimoto 的平均偏差约 0.014,相似度排序的 Spearman 相关约 0.99——碰撞存在,排序基本稳定;换成极短指纹,误差显著增大。

不折叠去掉的是“折叠”这一步新增的碰撞;标识符自身的哈希碰撞依然可能(32 位整数面对天文数字的环境空间,概率低得多,但不是零)。更要紧的是:即便完全无碰撞,指纹相同也不等于分子相同。环己烷与环庚烷在半径 2 下未折叠特征集合完全一致(只是各特征的计数不同),位指纹 Tanimoto = 1.0,而它们显然是两种分子——有限半径只记录“哪些环境出现”,超出半径的排布本就丢了。不折叠的真实收益是无折叠偏差、可携带出现次数、可作精细重排与来源解释。代价是不定长——不能按位运算,百万级检索要改走倒排索引或 MinHash 等近似路线,存储与比较成本都高;但对训练集特征建立列索引后,稀疏表示同样能列对齐地进模型。两种形态的取舍可以并排看清:

折叠位向量

  • 定长(2048 位),按位交并只需常数条指令
  • 列对齐,可直接作机器学习模型的输入
  • 有损:折叠碰撞在典型数据上抬高相似度(个别对可反向)
  • 一位可对应多个子结构,解释有歧义

不折叠标识符集合

  • 不定长(典型药物分子几十个整数),比较走集合运算
  • 无折叠碰撞(哈希自身碰撞概率低得多),可携带出现次数(计数版本)
  • 相似度无折叠偏差,适合精细重排
  • 解释回到标识符层面:结合原分子与生成时的来源信息(2.5.5 节)

工程折衷因此常见:位向量做粗筛与机器学习输入,标识符集合做精细重排与可解释性分析。

警示

碰撞偏差与阈值滥用。折叠碰撞在典型数据上抬高相似度,且幅度随位数、半径、不变量取项而变——同一对分子换一种指纹配置,Tanimoto 可以移动零点几。由此,“Tanimoto 大于 0.7 就算相似”这类绝对阈值没有普适性:0.7 在某配置下是强相似,在另一配置下只是背景水平。阈值必须相对指纹配置、并在目标数据集的两两相似度分布上标定。跨论文、跨工具直接抄用阈值,是相似性分析里最常见的隐性错误。

2.5.5 可解释性红利:把位读回子结构

位向量还有一个隐性代价:黑箱化。第 1187 位亮了,它是什么?ECFP 的回答是来源回溯,不是哈希求逆。生成指纹时可以顺手记录每个标识符来自哪些(中心原子、半径)——RDKit 的 bitInfo / AdditionalOutput 保存的就是这份来源清单;结合原分子,才能把某个标识符画成“中心原子 + 逐层邻居”的环境图。拿到一个孤立整数直接还原唯一结构是做不到的:哈希只保证相同环境必得相同整数,不保证整数与环境一一对应(ECFP 原文对标识符碰撞有专门讨论),同一个来源清单也只对这次生成、这个分子有效。

这仍是 ECFP 与一大类纯数值表示的本质区别。描述符向量(2.4 节)的一个数字有单位与定义,但不指回任何可画出的片段;学习模型的权重就更间接了。词典指纹的每一位锚定清单里的一条;摩根位向量的一位对应一个或多个圆形环境——模型说“位 1187 重要”,化学家可以列出它的全部来源环境、画出它们、审查它们。可解释性的实质是来源可查,不是字典式的唯一指认。诊断环节同样受益:某几位在活性分子中富集,读出的就是一个候选药效团假设,可交给 2.3 节的 SMARTS 检索验证。要防的仍是折叠与哈希碰撞:一位可能对应多个环境,严肃的解释应回到不折叠的标识符并核对来源。

下面这段代码演示来源回溯的完整流程:同一个分子、同一次生成——先看不折叠的计数表示,再查某一位的全部来源并画图。

from rdkit.Chem import Draw, rdMolDescriptors

sparse = gen.GetSparseCountFingerprint(m1).GetNonzeroElements()  # 不折叠:标识符 → 出现次数
print(len(sparse))                    # 去重后的圆形子结构数
info = {}
fp = rdMolDescriptors.GetMorganFingerprintAsBitVect(m1, 2, nBits=2048, bitInfo=info)
b = fp.GetOnBits()[3]
print(info[b])                        # 这一位的全部来源:(原子, 半径) 对,可能不止一个
Draw.DrawMorganBit(m1, b, bitInfo=info)   # 结合原分子画出该位对应的环境

稀疏计数的键就是整数标识符;bitInfo 列出该位的全部(原子、半径)来源,画出的环境即该位在此分子中的语义——“这一位是什么”从此有图可查,但它是本分子的来源清单,不是全局唯一的词典条目。

2.5.6 Tanimoto 系数与它的亲族

有了指纹,相似性度量登场。化学信息学的默认选择是 Tanimoto 系数——两个置位集合的交并比:

\[T(A, B) = |A \cap B| / |A \cup B| = c / (a + b - c)\]
(2.5-5)a、b 为两指纹的置位位数,c 为共同置位数。T ∈ [0,1],相同取 1、无共享取 0;两指纹全零时为 0/0,数学上无定义——软件各有约定:RDKit 2026.03 对两个全零位向量返回 0,较早的 2025.09 返回 1,跨版本复现要留意。几何关系见图 2.5-3。

性质四条。值域闭于 [0,1]。全零指纹无定义——空集之间谈交并比没有意义(软件约定的版本差异见上)。二元向量下 T 就是集合论的 Jaccard 指数(Jaccard index):名字不同、公式同一,Tanimoto 之名来自 1957 年一份技术报告(综述见 Willett et al., 1998)。最后,两位均为 0 的位置不进入任何计数——共同缺席不奖赏相似。这一条对稀疏的存在性特征至关重要:简单匹配系数把共同 0 计入“匹配”,数千个共同缺席会把毫不相似的分子评得接近;Tanimoto 只看共同拥有什么。

两个指纹集合 A、B 的交、并与 Tanimoto 系数 c/(a+b−c) 的几何 指纹 A(a 个置位) 指纹 B(b 个置位) A 独有:a − c B 独有:b − c 共享:c 两位均为 0 的位置不进入任何计数——共同缺席对 Tanimoto 不设奖赏 并集 |A∪B| = a + b − c(分母) · Tanimoto T = c / (a + b − c) 例:a = b = 6,c = 4 ⟹ T = 4/8 = 0.5(与习题 2.5-2 同例)
图 2.5-3 Tanimoto 系数的几何。分子 A 与 B 的指纹置位各成一集:交集大小为 c,并集大小为 a + b − c,Tanimoto 即交占并的比例。二元向量下它与 Jaccard 指数同一;共同的 0 位不参与任何计数,度量只对“共同拥有什么”敏感。

近亲 Dice 系数(Dice coefficient)把分母里的并集换成平均:

\[D(A, B) = 2c / (a + b) \quad D = 2T / (1 + T) \quad T = D / (2 - D)\]
(2.5-6)Dice 与 Tanimoto 互为严格单调变换:任何数据集上的排序完全一致,数值却系统性错位;0 < T < 1 时恒有 D > T。跨来源比较数值前,先统一系数。

两系数的换算关系说明:选 Tanimoto 还是 Dice,不改变任何一对分子的先后次序,只改变数值刻度。为什么默认 Tanimoto?Bajusz 等(2015)在多套数据上比较 8 种相似性系数,以排序与各系数平均排序的一致性(排序差异求和,SRD)为标准,Tanimoto、Dice、cosine 与 Soergel 同属表现最好的一组——但这是统计评价上的接近,不是数学等价。数学上严格与 Tanimoto 同序的只有 Dice(式 2.5-6 的单调换算);cosine 并不由 T 单调决定,它还依赖两指纹各自的置位数,排序可以与 Tanimoto 相反——例如查询 {1,2,3,4} 对候选 {1} 与 {1,2,5,6,7}:Tanimoto 给 0.25 < 2/7 ≈ 0.286(偏向后者),cosine 给 0.50 > 2/√20 ≈ 0.447(偏向前者)。在“多数任务下选哪个差别不大”的前提下,Tanimoto 胜在两点:交并比语义直白;1 − T 即 Soergel 距离,满足度量性质,可作几何使用,便于近邻索引与可视化。

习题 2.5-2

分子 A 与 B 的折叠指纹置位位置分别为 A = {17, 42, 101, 205, 333, 512} 与 B = {17, 42, 101, 205, 508, 700}。(1) 求 a、b、c 与 Tanimoto 系数;(2) 求 Dice 系数并验证 D = 2T/(1 + T);(3) 证明 0 < T < 1 时恒有 D > T。

参考解答

(1) a = b = 6,c = |{17, 42, 101, 205}| = 4,T = 4/(6 + 6 − 4) = 4/8 = 0.5。(2) D = 2×4/(6+6) = 8/12 ≈ 0.667;验证:2T/(1+T) = 1/1.5 ≈ 0.667,一致。(3) D − T = 2T/(1+T) − T = T(1−T)/(1+T),当 0 < T < 1 时分子为正、分母为正,故 D > T。Dice 把并集换成平均,天然抬高数值——同一“相似度 0.7”,在两种系数下的含义并不相同。

家族里更一般的是 Tversky 指数(Tversky index):

\[S_{\alpha,\beta}(A, B) = c / ( c + \alpha(a - c) + \beta(b - c) )\]
(2.5-7)α、β 分别给“A 独有”“B 独有”的置位加权。α = β = 1 退化为 Tanimoto;α = β = 1/2 退化为 Dice;不对称取值服务有方向的检索(超结构、子结构检索)。

α 与 β 拆开了“你的独有”与“我的独有”。对称取值回到 Tanimoto 与 Dice;不对称取值则承认一件事:相似与否,取决于提问的方向。超结构检索不希望目标多出的骨架挨罚,碎片检索正相反。这一自由度是对称系数看不见的。但方向性权重有一条硬边界:它调整的是特征集合的重叠账目,不是子结构判断。分子图上 Q ⊆ T,不保证 Q 的 Morgan 特征集包含于 T 的特征集——乙烷是丙烷的子结构,半径 2 下乙烷却有一个标识符不出现在丙烷的特征集里(部分原子的氢数与邻接环境在扩链后变了,相关特征随之改变)。严格包含判断走 2.3 节的子结构匹配;面向子结构检索的预筛要用专门的 Pattern 指纹——它为保证不漏筛而设计,与普通 Morgan 指纹的用途不可混同。Tversky 高分是“有方向的特征相似性”证据,不是包含关系的证明。

表 2.5-2重叠系数家族一览(c 为共同置位数,a、b 为各自置位数)
系数 / 距离公式与 Tanimoto 的关系典型用途
Tanimotoc / (a + b − c)—二元指纹相似性的默认选择
Dice2c / (a + b)D = 2T/(1+T),恒 ≥ T与 Tanimoto 排序等价,数值刻度不同
cosinec / √(ab)不由 T 单调决定;置位数不同时排序可与 Tanimoto 相反计数向量的常用相似度
Tverskyc / (c + α(a−c) + β(b−c))α = β = 1 时即 Tanimoto超结构 / 子结构等有方向的检索
Soergel 距离1 − TTanimoto 的度量化满足度量性质,可作几何与索引使用
习题 2.5-3

超结构检索:给定查询 Q,要在库中找出以 Q 为子结构的目标 T(Q 的每个子结构都被 T 覆盖,T 还可以有额外的骨架)。以式 (2.5-7) 讨论:α 与 β 应如何设置?对称的 Tanimoto(α = β = 1)为何不适用?

参考解答

a − c 是查询独有的置位,b − c 是目标独有的置位。超结构检索的期望情形是 a − c ≈ 0(查询的子结构都被覆盖),而 b − c 大(目标多出的骨架)且恰是检索想要的东西。故取 α = 1:查询中一旦有未被覆盖的子结构,严厉惩罚;取 β 为小值(如 0.1):容忍目标的额外结构。对称 Tanimoto 把两者同权,目标越大分越低,结果偏向与查询等大的分子,真正的超结构被系统性排到后面。反过来做碎片检索(找包含于查询之内的小分子),则 α 取小、β 取 1。最后留意边界:如此调权得到的是特征层面的有方向排序,不能保证检出全部真正包含 Q 的分子——Morgan 特征集的包含与图上的子结构包含不是一回事(正文反例),严格筛选应回到子结构匹配与 Pattern 指纹。

度量之上是化学的中心经验假设:相似性质原理(similar property principle)——结构相似的分子倾向具有相似的性质。它是虚拟筛选(virtual screening)、类似物设计与 read-across 预测的共同前提:用近邻的已知性质外推新分子的未知性质。假设并不总成立,活性悬崖(activity cliff)上一原子之差即可让性质剧变;但它给出了一个可操作的默认立场,其适用边界留待第 4 章结合任务讨论(综述见 Willett et al., 1998)。

最朴素的学习器由此诞生:k 近邻。新分子进来,算它与库内全部分子的 Tanimoto,取最相近的 k 个的标注作预测。没有参数训练,只有检索;预测质量押在两件事上——表示(指纹配置)与度量(系数选择)。这也使它成为绝佳的基线:任何更复杂的模型都要先回答,比近邻检索好在哪里。MoleculeNet 基准把 ECFP 配随机森林与图卷积模型同台比较(Wu et al., 2018),ECFP 系列至今仍是最强的传统基线之一,第 3 章正面再遇。

案例

近邻迁移:最朴素的学习器(示意数据)。设库内分子均带 LogP 标注,新分子经 ECFP4 计算后与库内最相近的三个邻居 T = 0.81、0.77、0.74,三者标注分别为 3.1、3.3、2.9。1-NN 预测 3.1,3-NN 取均值 3.1——没有训练任何参数,预测完全由“检索 + 聚合”给出。这正是虚拟筛选与 read-across 的骨架:复杂模型都要从这个基线出发证明自己。

阈值问题没有原理性答案。某个 Tanimoto 界线之上算“命中”,取决于指纹配置、数据集的相似度分布与检索目的:找类似物要高阈值,找骨架跃迁(scaffold hopping)的新分子反而要看中低相似区的陌生骨架。文献里的经验带(约 0.6–0.85)只是特定配置下的产物,换配置即漂移。可操作的做法:画出目标库内两两相似度的分布,把阈值定在分布的相应分位上——让数据说话,不让文献代劳。

习题 2.5-4

两位研究者对同一对分子报告 Tanimoto 相似度,一个 0.85、一个 0.62,且两人都没有算错。给出至少三种可能的原因,并说明报告相似度数值时应同时报告什么。

参考解答

至少四种来源。① 指纹配置不同:折叠位数(碰撞越多相似度越高)、半径、原子不变量取项,任一改变都会移动数值(2.5.3、2.5.4 节)。② 表示形态不同:一位折叠成位向量、另一位用不折叠的标识符集合或计数版本,碰撞的影响不同。③ 系数不同:Dice 与 Tanimoto 单调换算 D = 2T/(1+T),T = 0.62 对应 D ≈ 0.77;混用系数即混用刻度(习题 2.5-2)。④ 预处理不同:质子化状态、互变异构、盐形式的处理改变了图本身(2.6 节)。结论:相似度是“指纹配置 + 系数”的函数,报告数值必须同时报告这套配置,否则数字不可比。

2.5.8 通向第 3 章:从哈希指纹到神经指纹

本节的两条线索都通向第 3 章。表示线索:ECFP 配随机森林是属性预测中常用的传统基线(见 3.3 节),可用于检验更复杂模型是否在相同评估条件下带来改进。机制线索:Duvenaud 等(2015)的神经指纹(neural fingerprint)把 ECFP 逐层改造成可微运算——哈希的“非此即彼”换成 softmax 的软选择,“哪一位收下这个环境”从固定规则变成可学习参数;迭代层数即感受野,对应半径。指纹从特征工程变成可端到端训练的层(3.5 节展开)。理解这些模型仍需回到本节的编码机制:神经指纹能学到什么,取决于它对 ECFP 的哪一步做了松弛。

下一节转向数据的另一端:分子在进入任何表示之前先要洗净——清洗与标准化(2.6 节)。


关键术语

位向量指纹 (bit-vector fingerprint)
把变长分子图编码为定长二进制向量,子结构出现则相应位置 1。
圆形指纹 (circular fingerprint)
以每个原子为中心、按半径逐层扩张邻域生成的指纹,Morgan/ECFP 属此类。
扩展连接性指纹 (extended-connectivity fingerprint, ECFP)
Rogers 与 Hahn 提出的圆形指纹,标识符为原子环境经哈希得到的整数,可结合原分子与来源信息回溯环境。
摩根指纹 (Morgan fingerprint)
RDKit 对圆形指纹的实现名,致敬 Morgan 的迭代分类算法。
子结构标识符 (substructure identifier)
原子环境哈希得到的整数:相同环境必得相同值,不同环境不保证不同值。
折叠 (folding)
把标识符按 mod L 映入定长位向量的有损压缩步骤。
位碰撞 (bit collision)
两个不同子结构折叠到同一位,是相似度典型高估偏差的来源。
生日问题 (birthday problem)
m 个对象落入 L 个位置的碰撞概率问题,P ≈ 1 − e−m(m−1)/(2L)。
Tanimoto 系数 (Tanimoto coefficient)
交并比 c/(a+b−c),二元向量下即 Jaccard 指数。
Dice 系数 (Dice coefficient)
2c/(a+b),与 Tanimoto 单调换算:D = 2T/(1+T)。
Tversky 指数 (Tversky index)
带不对称权重 α、β 的广义重叠系数,服务超结构/子结构检索。
相似性质原理 (similar property principle)
结构相似蕴含性质相似的经验假设,相似性搜索与近邻迁移的根基。

参考文献与延伸阅读

  1. Morgan HL. 1965. The generation of a unique machine description for chemical structures—a technique developed at Chemical Abstracts Service. Journal of Chemical Documentation 5:107–113.
  2. Rogers D, Hahn M. 2010. Extended-connectivity fingerprints. Journal of Chemical Information and Modeling 50:742–754.
  3. Willett P, Barnard JM, Downs GM. 1998. Chemical similarity searching. Journal of Chemical Information and Computer Sciences 38:983–996.
  4. Bajusz D, Rácz A, Héberger K. 2015. Why is Tanimoto index an appropriate choice for fingerprint-based similarity calculations? Journal of Cheminformatics 7:20.
  5. Swamidass SJ, Baldi P. 2007. Mathematical correction for fingerprint similarity measures to improve chemical retrieval. Journal of Chemical Information and Modeling 47:952–964.
  6. Duvenaud DK, Maclaurin D, Aguilera-Iparraguirre J, et al. 2015. Convolutional networks on graphs for learning molecular fingerprints. Advances in Neural Information Processing Systems 28 (NIPS 2015).
  7. Wu Z, Ramsundar B, Feinberg EN, et al. 2018. MoleculeNet: a benchmark for molecular machine learning. Chemical Science 9:513–530.
  8. Landrum G, et al. 2026. RDKit Documentation: Fingerprints and Similarity. RDKit 官方文档,2026.03 系列.