PostgreSQL模糊匹配

时间:2015-11-10 17:57:38

标签: regex postgresql fuzzy-search

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

  • 名字
  • 姓氏
  • 中间名
  • Zip
  • SSN
  • DOB
  • 电话

我正在尝试查找两个表和记录之间匹配的记录,这些记录很可能是matche但由于输入错误,缺少数据,名称拼写的变化等而不是完全匹配...

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

理想情况下,我希望为结果提供某种加权机制。

现在如果SSN是直接匹配,那么我们就匹配了。但是我还想考虑是否存在用户输入错误并且2位数字混淆了或类似的东西。

我在PG中有哪些选择?

如果我运行多个变体(例子),直接匹配会很好。

  • 社交比赛
  • 姓氏,DOB,邮编
  • 姓氏,DOB,州
  • 姓氏,名字,DOB,ZIP

但是,我希望能够部署更完整的解决方案并寻找有关如何继续的任何提示。

2 个答案:

答案 0 :(得分:2)

这称为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. 如果概率超过阈值则匹配,否则不匹配

答案 1 :(得分:0)

我认为fuzzystrmatch和/或pg_trgm模块正是您所需要的。