2.5.1 从词典到无词典:指纹的谱系与动机
「指纹(fingerprint)」泛指把变长的分子图映射为定长位向量(bit vector)的编码:出现某个子结构,就在相应位置 1。位向量把「两个分子有多像」变成「两个集合的交并之比」,按位逻辑运算代价极低,百万级分子库的相似性检索因而可行(Willett et al., 1998)。第一代实现是词典指纹(dictionary-based fingerprint):预先编纂一张子结构清单,每个键对应一位。用得最久的是 MACCS 键——公开版本含 166 个子结构,每条都以 SMARTS 可读(2.3 节)。词典指纹的长处是彻底透明:哪一位亮,分子就含哪个片段,解释零成本。短板同样是结构性的:词典之外的结构不产生任何位,覆盖被清单封顶;大环、肽、金属有机等化学型常常落在清单之外;词典靠人工维护,扩充缓慢而昂贵。
第二代走向自动枚举。路径指纹不再依赖人工清单,沿分子图枚举所有不超过给定长度的路径(原子—键序列),每条路径哈希成一位。覆盖不再受词典限制,但仍由枚举策略决定:路径是线性的,分支与环系只能间接表达。第三代圆形指纹(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」没有任何对应关系。
| 范式 | 覆盖来源 | 主要参数 | 可解释性 | 代表 |
|---|---|---|---|---|
| 词典指纹 | 预定义子结构清单 | 几乎不可调(键固定) | 逐键透明:一位即一个片段 | MACCS 166 键 |
| 路径指纹 | 图上枚举的线性路径 | 路径长度上限、位数 | 路径可反解 | Daylight 指纹 |
| 圆形指纹 | 每个原子的邻域,按需生成 | 半径、位数、原子不变量取项 | 标识符可反解为圆形环境 | ECFP / Morgan |
表中最后一列的递进值得一句话总结:从词典到圆形,覆盖从「清单说了算」变成「分子自己说了算」,可解释性则始终保住——这正是 ECFP 能同时服务检索、建模与人审的原因。
2.5.2 ECFP 的四步算法:初始化、迭代、收集、折叠
ECFP 的生成可以拆成四步:初始化、迭代、收集、折叠(Rogers & Hahn, 2010)。先立定义,再逐步展开。
扩展连接性指纹。对分子中每个原子 v、每个半径 r ∈ {0, 1, …, R},生成一个整数标识符 idr(v),它唯一编码「以 v 为中心、r 步之内的圆形邻域」——中心原子属性,加上逐层纳入的邻居与键级。全体原子、全体半径的标识符去重后组成集合,即该分子的 ECFP;集合折叠成定长位向量,即常用的位指纹。半径 R 是唯一的主要自由度。
第一步:初始标识符。给每个原子写一张属性卡:元素、重原子连度、显式价、形式电荷、连接氢数、环隶属……(2.1 节的节点属性正派上用场)。把这张元组 τ(v) 哈希成一个 32 位整数:
哈希在这里不是加密,而是把结构化的不变量压成可比较、可存储、可作字典键的整数。元组的取项决定指纹「看得见」什么:默认不含电荷项时,质子化状态的差异对指纹不可见;含同位素项时,氘代才可分辨。取项是设计决策,不是实现细节。
第二步:迭代更新。第 k 轮,每个原子把上一轮邻居的标识符连同键级收进来,与自身上一轮的标识符一起再哈希一次:
两个机理要点。其一,邻域滚动扩张:第 1 轮标识符编码「我 + 直接邻居」,第 2 轮编码「我 + 邻居 + 邻居的邻居」(图 2.5-1)。迭代次数即半径,这正是「扩展连接性」的含义。其二,多重集的引入并非修辞:邻居以什么次序进入哈希,结果必须相同,否则同一分子换一种原子编号就得到不同指纹。这与 1.2 节的置换不变性、2.4 节图不变量的要求一脉相承——Morgan 式迭代本身就是逐轮精化的图不变量,图论中的 WL 顶点精化算法是它的同族。
第三步:收集。把每个原子在每一轮的标识符都收进集合:半径 0 到 R,每原子 R+1 个。两个原子的环境完全相同时标识符相同,集合语义自动去重;若改而保留每个标识符的出现次数,得到计数版本(ECFC),信息更多,位向量则一律只记「出现与否」。半径 2 下,典型药物分子有几十个互不相同的圆形子结构——指纹的大小随分子复杂度自然伸缩,这正是无词典设计的好处。
第四步:折叠。整数集合不定长,按位运算也不方便,于是把每个标识符映射到定长位向量的某一位并置 1:
折叠的收益是定长与高效:两个 2048 位向量的交、并、异或都是常数条机器指令。代价——碰撞——是本节后半的主角,先在图 2.5-2 里看清它的几何。
下面用一对只差一个原子的分子印证上述流程:半径 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(DataStructs.TanimotoSimilarity(fp1, fp2)) # c/(a+b−c):一原子之差即明显小于 1
两个分子只在末端差 O 与 N,多数圆形子结构仍然相同,置位大量重叠;但含末端原子的环境不同,交就不是全集,相似度明显小于 1。一个原子的改写只扰动「以它为中心的那些环境」——半径 2 时至多波及它两步以内的中心。指纹对局部改动的响应是局部的,这一性质在后面的章节反复出现。
2.5.3 参数的语义:半径与位数
命名习惯里,ECFP 的下标是直径而非半径:ECFP4 指直径 4 条键,即半径 2、两轮迭代;ECFP6 对应半径 3。RDKit 摩根指纹的 radius 参数就是半径,radius=2 与 ECFP4 相当。半径是「分辨率」旋钮:半径 0–1 看见官能团与一阶环境,对电性、氢键供受体敏感;半径 2–3 看见骨架片段,对整体拓扑敏感。半径越大,稀有环境越多、区分度越高,但对局部变化也更敏感。变体 FCFP 把原子属性换成药效团(pharmacophore)类别(氢键供体、芳香环……),「看什么」随之改变。
半径的影响可以用取代苯看清楚。二取代苯的邻、间、对三种异构体,在半径 1 下不可分:取代基附着碳的环境都是「芳香碳 + 两个环碳 + 一个取代基」,三种情形完全同标签。半径 2 起,间位与对位附着碳的邻域开始不同,指纹随之分开。官能团层次的分辨要小半径,骨架与位置异构的分辨要大半径——半径不是越大越好,而是要与「想看见的化学差异」匹配。
位数 L 是另一个旋钮,它的后果可以用生日问题(birthday problem)精确刻画。m 个互不相同的标识符独立均匀落入 L 位,至少两位相撞的概率为:
一个中型分子库的不同子结构数以万计,折叠位向量必然布满碰撞。位数从 2048 提到 4096、8192,门槛只抬高 √2 倍、2 倍——按位数对抗生日悖论是指数打平方便,治标不治本。真正的出路在 2.5.4 节。
习题 2.5-1
某化合物库经 ECFP4 计算后共得到 m = 10⁴ 个互不相同的子结构标识符,折叠到 L = 2048 位,设各标识符独立均匀落入每一位。(1) 写出至少一次碰撞的概率公式并给出指数近似与数值;(2) 求碰撞位置对的期望数;(3) 求碰撞概率首次超过 1/2 的最小标识符数 m*;(4) 若把位数提高到 L = 2²⁰ = 1 048 576,碰撞是否可以忽略?这说明什么?
参考解答(1) P = 1 − ∏i=0m−1(1 − i/L) ≈ 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。区区 54 个不同子结构即可让碰撞过半,2048 位在生日悖论面前不堪一击。(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 变小,位密度随之升高。净效应的方向是一致的:指纹越短,位密度与偶然重叠越大,相似度整体被抬高。Swamidass 与 Baldi(2007)把这一点表述为折叠的系统误差并给出修正公式;RDKit 社区对真实库的实测同样显示:折叠位数越小,平均 Tanimoto 越高。个别分子对上也有反向扰动——两个共享子结构互相碰撞会合并计数、压低 c——但就整个库而言,高估是主导方向。
彻底的出路是不折叠:保留整数标识符的集合(或「标识符 → 计数」映射)。子结构不同则整数不同,相似度在集合上直接计算,无碰撞,还能分清「出现一次」与「出现多次」。代价是不定长——不能按位运算,百万级检索要改走倒排索引或 MinHash 等近似路线,存储与比较成本都高。两种形态的取舍可以并排看清:
折叠位向量
- 定长(2048 位),按位交并只需常数条指令
- 列对齐,可直接作机器学习模型的输入
- 有损:碰撞系统性抬高相似度(2.5.4 节)
- 一位可对应多个子结构,解释有歧义
不折叠标识符集合
- 不定长(典型药物分子几十个整数),比较走集合运算
- 无碰撞,可携带出现次数(计数版本)
- 相似度无折叠偏差,适合精细重排
- 标识符与子结构一一对应,解释无歧义
工程折衷因此常见:位向量做粗筛与机器学习输入,标识符集合做精细重排与可解释性分析。
碰撞偏差与阈值滥用。折叠碰撞抬高相似度,且抬高幅度随位数、半径、不变量取项而变——同一对分子换一种指纹配置,Tanimoto 可以移动零点几。由此,「Tanimoto 大于 0.7 就算相似」这类绝对阈值没有普适性:0.7 在某配置下是强相似,在另一配置下只是背景水平。阈值必须相对指纹配置、并在目标数据集的两两相似度分布上标定。跨论文、跨工具直接抄用阈值,是相似性分析里最常见的隐性错误。
2.5.5 可解释性红利:把位读回子结构
位向量还有一个隐性代价:黑箱化。第 1187 位亮了,它是什么?ECFP 的回答是可以反解。Rogers 与 Hahn(2010)在设计时就保留了标识符到子结构的映射:每个整数标识符由哈希前的属性元组与邻域结构唯一决定,反查即得「中心原子 + 逐层邻居」的完整环境。RDKit 的 bitInfo 记录每个位来自哪些(中心原子、半径)对,配合绘图工具可以直接把某一位画成结构图。
这是 ECFP 与一大类纯数值表示的本质区别。描述符向量(2.4 节)的一个数字有单位与定义,但不指回任何可画出的片段;学习模型的权重就更间接了。指纹的每一位都锚定一个子结构:模型说「位 1187 重要」,化学家可以画出它、审查它、质疑它。可解释性不是事后附会,而是编码方案内生的性质。诊断环节同样受益:某几位在活性分子中富集,读出的就是一个候选药效团假设,可交给 2.3 节的 SMARTS 检索验证。要防的仍是折叠:位向量上的一位可能对应多个子结构,严肃的解释应回到不折叠的标识符。
下面这段代码对应「反解」:先生成不折叠的稀疏计数指纹,再取出某一位对应的环境画出来。
from rdkit.Chem import Draw, rdMolDescriptors
sparse = gen.GetSparseCountFingerprint(m1).GetNonzeroElements() # 不折叠:标识符 → 出现次数
print(len(sparse)) # 去重后的圆形子结构数;对照 a,差额即折叠吞掉的信息
info = {}
rdMolDescriptors.GetMorganFingerprintAsBitVect(m2, 2, nBits=2048, bitInfo=info)
b = fp2.GetOnBits()[3]
Draw.DrawMorganBit(m2, b, bitInfo=info) # 反解:画出这一位对应的圆形环境
稀疏计数的键就是整数标识符;位图工具画出的环境即该位的语义,「这一位是什么」从此有图可查。
2.5.6 Tanimoto 系数与它的亲族
有了指纹,相似性度量登场。化学信息学的默认选择是 Tanimoto 系数——两个置位集合的交并比:
性质四条。值域闭于 [0,1]。全零指纹无定义——空集之间谈交并比没有意义。二元向量下 T 就是集合论的 Jaccard 指数(Jaccard index):名字不同、公式同一,Tanimoto 之名来自 1957 年一份技术报告(综述见 Willett et al., 1998)。最后,两位均为 0 的位置不进入任何计数——共同缺席不奖赏相似。这一条对稀疏数据至关重要:欧氏距离或相关系数面对数千个共同 0,会把毫不相似的分子也评得接近。
近亲 Dice 系数(Dice coefficient)把分母里的并集换成平均:
两系数的换算关系说明:选 Tanimoto 还是 Dice,不改变任何一对分子的先后次序,只改变数值刻度。为什么默认 Tanimoto?Bajusz 等(2015)在多套数据上比较 12 种相似性系数,结论是 Tanimoto、Dice、cosine 与 Soergel 距离同属最优,且在二元数据上排序等价;在「选哪个都一样」的前提下,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):
α 与 β 拆开了「你的独有」与「我的独有」。对称取值回到 Tanimoto 与 Dice;不对称取值则承认一件事:相似与否,取决于提问的方向。超结构检索不希望目标多出的骨架挨罚,碎片检索正相反。这一自由度是对称系数看不见的。
| 系数 / 距离 | 公式 | 与 Tanimoto 的关系 | 典型用途 |
|---|---|---|---|
| Tanimoto | c / (a + b − c) | — | 二元指纹相似性的默认选择 |
| Dice | 2c / (a + b) | D = 2T/(1+T),恒 ≥ T | 与 Tanimoto 排序等价,数值刻度不同 |
| Tversky | c / (c + α(a−c) + β(b−c)) | α = β = 1 时即 Tanimoto | 超结构 / 子结构等有方向的检索 |
| Soergel 距离 | 1 − T | Tanimoto 的度量化 | 满足度量性质,可作几何与索引使用 |
习题 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。
2.5.7 相似性搜索的逻辑:相似性质原理
度量之上是化学的中心经验假设:相似性质原理(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 提出的圆形指纹,标识符为 32 位整数,可反解回子结构。
- 摩根指纹 (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)
- 结构相似蕴含性质相似的经验假设,相似性搜索与近邻迁移的根基。
参考文献与延伸阅读
- 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.
- Rogers D, Hahn M. 2010. Extended-connectivity fingerprints. Journal of Chemical Information and Modeling 50:742–754.
- Willett P, Barnard JM, Downs GM. 1998. Chemical similarity searching. Journal of Chemical Information and Computer Sciences 38:983–996.
- 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.
- Swamidass SJ, Baldi P. 2007. Mathematical correction for fingerprint similarity measures to improve chemical retrieval. Journal of Chemical Information and Modeling 47:952–964.
- 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).
- Wu Z, Ramsundar B, Feinberg EN, et al. 2018. MoleculeNet: a benchmark for molecular machine learning. Chemical Science 9:513–530.
- Landrum G, et al. 2026. RDKit Documentation: Fingerprints and Similarity. RDKit 官方文档,2026.03 系列.