You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Postgres pg_trgm模块相似度计算方法及结果差异疑问

好问题!很多人刚开始接触pg_trgm的时候,都会把它的相似度和常见的Dice-Sorensen指标搞混,其实它的计算逻辑有自己的特点,我来一步步给你拆解清楚。

pg_trgm模块similarity函数的核心计算逻辑

第一步:生成三元组(Trigram)

pg_trgm的所有相似度计算都基于三元组集合,生成三元组时有几个关键规则:

  • 字符串会被预处理:开头添加两个空格,结尾添加一个空格
  • 从预处理后的字符串中,滑动截取所有连续的三个字符,每个截取结果就是一个三元组
  • 最终的三元组是去重后的集合(不过大多数情况下原字符串不会生成重复三元组)

你可以用Postgres内置的show_trgm函数直接查看字符串的三元组:

SELECT show_trgm('sage');
-- 返回:{"  s"," sa","sag","age","ge "}

第二步:相似度的计算公式

pg_trgm的similarity(a, b)本质是Jaccard相似度,公式为:

similarity = 两个字符串三元组的交集大小 / 两个字符串三元组的并集大小

而你预期的Dice-Sorensen公式是:

Dice = 2 * 交集大小 / (a的三元组数量 + b的三元组数量)

这就是两者结果差异的核心原因!

用你的例子一步步验证:'sage' vs 'message'

我们亲手算一遍,还原得到0.3的过程:

1. 生成两个字符串的三元组

  • 对于'sage',预处理后是' sage ',生成的三元组有5个:{" s"," sa","sag","age","ge "}
  • 对于'message',预处理后是' message ',生成的三元组有8个:{" m"," me","mes","ess","ssa","sag","age","ge "}

2. 计算交集和并集

  • 交集:两个集合共有的三元组是"sag","age","ge ",共3个
  • 并集:总三元组数量 = 5 + 8 - 3 = 10个(减去重复的交集数量)

3. 计算相似度

代入公式:3 / 10 = 0.3,和你得到的结果完全一致!

补充:和Dice-Sorensen的换算

如果你需要得到Dice-Sorensen的结果,可以通过Jaccard值反向推导:

Dice = 2 * Jaccard / (1 + Jaccard)

比如这个例子里,Dice值就是2*0.3/(1+0.3) ≈ 0.46,和你最初的预期一致。

内容的提问来源于stack exchange,提问作者swami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:10:48