我在这里讨论了许多讨论基于编辑距离的模糊搜索的线程,像Elasticsearch / Lucene这样的工具开箱即用,但我的问题有点不同。假设我有一个单词词典,{'cat','cot','catalyst'}和一个字符相似关系f(x,y)
f(x, y) = 1, if characters x and y are similar
= 0, otherwise
(这些“相似之处”可以由程序员指定)
这样,比方说,
f('t', 'l') = 1
f('a', 'o') = 1
f('f', 't') = 1
但是,
f('a', 'z') = 0
etc.
现在,如果我们有一个'cofatyst'查询,算法应报告以下匹配项:
('cot', 0)
('cat', 0)
('catalyst', 0)
其中数字是找到的匹配项的从0开始的索引。我尝试了Aho-Corasick algorithm,虽然它对于精确匹配非常有用,但是当一个字符的“相似”字符数量相对较少时,它的性能会随着我们增加一个字符的相似字符数而呈指数下降。有人能指出我这样做的更好方法吗?模糊性是绝对必要的,它必须考虑到字符的相似性(即,不要盲目地依赖于编辑距离)。
有一点需要注意的是,在野外,字典会非常大。
答案 0 :(得分:1)
我可能尝试使用每个字符的位置作为特征来使用余弦相似性,并使用基于您的角色关系的匹配函数在特征之间映射产品。
我知道,这不是一个非常具体的建议,但我希望它可以帮助你。
编辑:扩大答案。
使用余弦相似度,您将计算两个向量的相似程度。在您的情况下,规范化可能没有意义。那么,我要做的是非常简单的事情(我可能会过分简化问题):首先,将CxC矩阵看作依赖矩阵,其中两个字符相关的概率(例如,P('t'|'l') )= 1)。这也允许您具有部分依赖关系来区分完美匹配和部分匹配。在此之后,我将为每个位置计算每个单词的字母不相同的概率(使用P(t_i,t_j)的补码),然后您可以使用总和来汇总结果。
它将计算特定单词对的不同术语数,并允许您定义部分依赖项。此外,实施非常简单,应该可以很好地扩展。这就是为什么我不确定我是否误解了你的问题。
答案 1 :(得分:0)
我正在使用Fuse JavaScript Library作为我的一个项目。它是一个适用于JSON数据集的javascript文件。它很快。看看吧。
它已经实现了完整的Bitap算法,利用了Diff,Match& amp;的改进版本。谷歌的补丁工具(来自他的网站)。
代码很容易理解算法的实现。