PostgreSQL 模糊匹配

PostgreSQL Fuzzy Matching

我有 2 个表,其中包含以下字段:

我正在尝试查找 2 个表之间匹配的记录和最有可能匹配但由于输入错误、数据缺失、名称拼写差异等原因不完全匹配的记录...

部分数据缺失。但是对于那里的所有数据,两个表的每个数据元素都具有相同的格式/数据类型。

理想情况下,我希望对结果采用某种加权机制。

现在,如果 SSN 是直接匹配项,那么我们就有匹配项了。但我还想考虑是否存在用户输入错误以及混淆了 2 位数字或类似情况。

我在 PG 中有哪些选择?

如果我 运行 多个变体(示例),直接匹配就可以了。

不过,我很想部署一个更完整的解决方案,并且正在寻找有关如何进行的任何提示。

我认为 fuzzystrmatch and/or pg_trgm 模块正是您要找的。

这个叫Probabilistic Record Linkage(其实有好几个名字)

您要做的第一件事是标准化每一列的值,以便它们可以直接比较。例如,日期应为 ISO 格式并经过修整。

简单的方法

统计匹配列数:

select
 n.id as needle_id,
 h.id as haystack_id,
 case when n.col1 = h.col1 then 1 else 0 end 
 + case when some_comparison_function(n.col2, h.col2) then 1 else 0 end
 + ...
 as relevance
from 
 needles n
join 
 haystack h -- haystack table could be the same as needles table
on  -- only compare rows where at least one column matches
 n.col1 = h.col1 
 or some_comparison_function(n.col2, h.col2)
 or ...
order by 
 relevance desc;

更难但更正确的方法

这在数学上 proven 是最优的。它根据值的稀有程度为您计算列的权重。

  1. 选择两个值应该相等但不同的概率。例如,两条记录应具有相同的 SSN,但出现了拼写错误。一减去这个值就是你的 m-prob(称之为 99%)。

  2. 为每一列计算每个值的相对频率。这是你的 u-prob

  3. 对于每个可能的匹配项(needle.dob vs haystack.dob),如果他们同意则计算优势比:m-prob / u-prob,或者如果他们不同意则计算优势比: (1 - m-prob) / (1 - u-prob)

  4. 将所有赔率相乘得到总赔率

  5. 计算匹配概率:total_odds / (1 + total_odds)

  6. 如果概率超过阈值则匹配,否则不匹配