关于如何改进当前模糊搜索实现的建议

时间:2010-10-21 16:35:20

标签: java algorithm performance fuzzy-search levenshtein-distance

2 个答案:

答案 0 :(得分:3)

哇......很难。

那你为什么不实施lucene呢?对于像你这样的问题,这是最好和最新的技术状态。

但是我想分享一些想法...

Fuziness不是像稻草一样的东西,而是一些单词的错误输入。每个缺失/错误的角色都会增加1距离。

它通常非常非常难以同时具有部分匹配(通配符)和模糊性!

标记通常是一个好主意。

一切也很大程度上取决于你得到的数据。源文件或仅搜索查询中是否存在拼写错误?

我已经看到了一些使用多维范围树的非常好的实现。

但我真的认为如果你想完成上述所有工作,你需要一个非常巧妙的图形集和一个很好的索引算法组合。

例如,您可以使用芝麻这样的语义数据库,并在导入文档时将每个标记和文档导入为节点。然后根据文档中的位置等,您可以添加加权关系。

然后你需要一些结构中的标记,你可以在其中进行有效的模糊匹配,例如bk-trees。 我认为您可以在mysql数据库中索引令牌并执行逐位比较函数以获得差异。这是一个返回所有匹配位的函数,如果你将字符串转换为ascii并将这些位分组,你可以很快地实现某些目标。

但是,如果您将标记与字符串匹配,您可以构建一个假设的完美匹配antity并查询您的语义数据库中的最近邻居。

在进行标记化以实现部分匹配时,您必须将这些单词拆分为部分单词。

但是你也可以做通配符匹配(前缀,后缀或两者),但是没有模糊性。

您还可以索引整个单词或不同的标记连接。

然而,可能有特殊的bk-tree实现支持这个但我从未见过它。

答案 1 :(得分:2)

我在很久以前就进行了多次拼写修正器的迭代,这里是基本方法的recent description。基本上,正确单词的字典在trie中,搜索是一个简单的分支绑定。我使用反复深度优先行走,由lev限制。距离是因为,因为每增加一个距离会导致更多的行走,所以对于小距离而言,成本基本上是指数距离,因此进行组合深度/广度搜索并不会节省太多但是更复杂。

(旁白:你会惊讶于医生可以尝试拼写“乙酰水杨酸”的方式。)

我对你的特里的大小感到惊讶。可接受单词的基本词典可能是几千。然后有共同的前缀和后缀。由于结构是trie,您可以将子尝试连接在一起并节省大量空间。像基本前缀的trie可以连接到主词典,然后主词典的终端节点可以连接到常见后缀的trie(实际上可以包含循环)。换句话说,trie可以推广到有限状态机中。这为您提供了很大的灵活性。

无论如何,您遇到了性能问题。性能问题的好处是,它们越糟糕,它们就越容易找到。我一直是StackOverflow的真正害虫,指出了这一点。 This link解释了如何做到这一点,链接到一个详细的例子,并试图消除一些流行的神话。简而言之,花在做一些你可以优化的事情上的时间越多,你就越有可能抓住它,如果你只是暂停它并看一看。我怀疑很多时候是在夸大数据结构的操作上,而不仅仅是得到答案。这是一种常见情况,但在样本直接指出问题之前不要修复任何问题。