【问题标题】:Preselection of probability for approximate string matching近似字符串匹配的概率预选
【发布时间】:2013-02-04 20:47:47
【问题描述】:

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

先介绍一点背景:

我对算法进行了一些广泛的研究,并决定每个领域都应该权衡一定的数量 使用不同的算法,因为并非所有算法在所有情况下都表现得一样好。 例如,姓氏的权重因子为 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 个测试记录.. 谁能指出我正确的方向?肯定有人以前遇到过这个问题并找到了解决方案......

非常感谢您!

附:我在 C++ 中执行此操作,但 C#/C/Java/PHP 中的任何示例都可以。

【问题讨论】:

    标签: c++ string matching metric approximate


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      作为第一个切入点,我只需选择那些足够接近相同长度的字符串,它们可以在给定的概率内匹配。这不会非常有选择性,但(除非您指定非常宽松的容差)可能会很快消除相当大比例的不可能匹配非常。 (例如,使用像 Levenshtein 这样的编辑指标将插入计为 1 次操作,如果您从长度为 5 的字符串开始并且需要在 5 次操作中匹配,那么您可以消除所有长度超过 10 的字符串而无需进一步检查)。

      这是否具有足够的选择性以直接进行昂贵的比较是有待商榷的——显然这将取决于您匹配的字符串长度的可变性。

      【讨论】:

      • 谢谢,这绝对有帮助。这也是他们在数据挖掘书的第 3 章中谈到的内容。我在想字符串长度可能是可行的,但 Levenshtein 不可行(有时记录会颠倒字段,例如“John Smith”和“Smith, John”,Levenshtein 会错误地将它们排除为匹配项)。我将试一试字符串长度并比较运行时间。您是否也对提到的其他选项(R/KD 树等)的可行性有任何意见?至少为什么他们不能接受(除了复杂性)?
      猜你喜欢
      • 2011-05-11
      • 2013-07-10
      • 1970-01-01
      • 2013-06-26
      • 2010-09-08
      • 2016-03-28
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多