预选近似字符串匹配的概率

时间:2013-02-19 23:56:11

标签: c++ string matching metric approximate

我最近的任务是开发一种算法,用于检查数据库中的重复客户记录。 数据库布局非常简单:数万行包含FullName,Street,City,ZIP,Phone等字段......

首先有一点背景:

我已经对算法进行了一些广泛的研究,并且已经确定每个字段都应该在一定的量上进行权衡 使用不同的算法,因为并非所有情况都表现得同样好。 例如,LastName的权重系数为0.50。当我评估时,我选择使用哪种算法以及它们对最终决策的权重: 因素0.25:JaroWinkler
因子0.60:余弦2-Gram相似度
因子0.15:DamerauLevenshtein

一切都运作良好,只需稍加调整,我就会发现误差很小的积极因素。 到现在为止还挺好。但是,正如您可以想象的那样,在处理成千上万条记录时,运行O(n ^ 2) - 或实际上E形式i = 0到i = n - 并不是非常有效。 毋庸置疑,使用编译器优化速度,多线程等进行积极优化只是绑定,因为真正的问题是复杂性。

基本上,我正在寻找预先过滤潜在匹配的方法,并且现在对此进行了三天的研究。 我已经找到了关于R-Trees,R * -Trees,KD-Trees,Eucledian向量,minhashing等的一些有价值的信息。 但是,关于所有这些的大多数信息都是相当高度的学术性。我找到的最有价值的资源是“挖掘海量数据集”,第3章。

现在回答我真正的问题:

我已经阅读了所有这些信息,但我不确定如何将它们放在一起。

我正在考虑在树或图形数据结构中进行某种索引,在那里我可以放入一个字符串并说“找到所有匹配概率> 0.20”。 这个算法应该非常快。然后,当我得到一个潜在的(> 0.20)匹配列表时,我可以用我的“昂贵”但选择性的算法来比较这几个项目。 这应该将运行时间减少到一个非常合理的值。我相信。

我一直试图找到某种参考代码来做我上面想做的事情,但我似乎没有提出除学术文章以外的任何东西。 我确实找到了“simstring”,它实际编译了,但似乎没有很好地匹配7个测试记录。 有人能指出我正确的方向吗?当然有人必须在此之前碰到这个并找到解决方案......

非常感谢你!

P.S。我在C ++中这样做,但C#/ C / Java / PHP中的任何样本都没问题。

2 个答案:

答案 0 :(得分:1)

作为第一个切入点,我只需选择那些足够接近它们可以匹配的长度的字符串。这不是很有选择性,但是(除非你指定相当宽松的公差)可能会很快消除相当大比例的不可能匹配非常。 (例如,使用像Levenshtein这样的编辑指标将插入计为1次操作,如果从长度为5的字符串开始并且需要在5次操作中匹配,则可以在不进一步检查的情况下消除长于10的所有字符串)。 / p>

这是否有足够的选择性直接进行昂贵的比较是值得商榷的问题 - 显然这取决于你所匹配的字符串长度的可变性。

答案 1 :(得分:1)

我终于通过执行以下操作成功实现了预选: 1.使用客户记录的某些字段构建2Grams 2.使用6个minhash函数的家族将2Grams Minhash为192位签名 3.使用boost :: geometry libraries的rtree实现在签名上创建6维空间索引 4.为我正在比较的记录选择最近的k(即我的情况30)记录,并在那些候选人上运行原始的“昂贵”比较 5.这将E(i,i = n,i = 1)的复杂度降低到大约30n + m,其中m是构建指数所需的时间(几乎可以忽略不计,令人惊讶)。

我现在可以在60秒内以高精度运行15,000次比较,这是在单线程测试中。多线程到4或8核,这将运行得更快。