我正在寻找一个模糊搜索JavaScript库来过滤数组。我尝试使用Fuzzyset.js和fuse.js,但是结果很糟糕(可以在链接的页面上尝试一些演示)。
在对Levenshtein距离进行了一些阅读之后,我对用户输入时所寻找的内容的近似性感到不满意。对于那些不知道的人,系统会计算要使两个字符串匹配,需要多少个插入,删除和替换。
在Levenshtein-Demerau模型中修复的一个明显缺陷是,blub和boob都被认为与bulb相似(都需要两次替换)。很明显,但是,灯泡更类似于咕噜比布布是的,我刚才提到的模型识别到,允许换位。
我想在文本补全的背景下使用它,因此,如果我有一个数组['international', 'splint', 'tinder']
,并且我的查询是int,我认为International应该比splint排名更高,即使前者的得分(高=差)为10与后者的3。
因此,我正在寻找(并且如果不存在的话将创建)一个执行以下操作的库:
- 权衡不同的文本操作
- 根据每个单词在单词中出现的位置,对每个操作进行加权加权(较早的操作比较晚的操作成本更高)
- 返回按相关性排序的结果列表
有没有人遇到过这样的事情?我意识到,StackOverflow并不是要求软件推荐的地方,但是上面的隐式(不再是!)是:我是否正在以正确的方式考虑?
编辑
我找到了一篇很好的论文(pdf)。一些注释和摘录:
仿射编辑距离功能为插入或删除序列分配了相对较低的开销
Monger-Elkan距离函数(Monge&Elkan 1996),它是Smith-Waterman距离函数(Durban et al。1998)的仿射变体,具有特定的成本参数
对于史密斯-沃特曼距离(Wikipedia),“史密斯-沃特曼算法无需查看总序列,而是比较所有可能长度的片段并优化相似性度量。” 这是n-gram方法。
大致上类似的度量标准(不是基于编辑距离模型)是Jaro度量标准(Jaro 1995; 1989; Winkler 1999)。在记录链接文献中,使用此方法的变体已获得了良好的结果,该变体基于两个字符串之间的公共字符的数量和顺序。
由于Winkler(1999)的不同,它也使用最长公共前缀的长度P
(似乎主要用于短字符串)
为了完成文本,Monger-Elkan和Jaro-Winkler方法似乎最有意义。Winkler对Jaro度量标准的添加有效地对单词的开头进行了更重的加权。而且,Monger-Elkan的仿射方面意味着完成一个单词的必要性(这只是一系列加法)不会太不利于它。
结论:
TFIDF排名在几个基于令牌的距离度量中表现最好,而Monge和Elkan提出的经过调整的仿射间隔编辑距离度量在几个字符串编辑距离度量中表现最好。令人惊讶的良好距离度量是Jaro提出并随后由Winkler扩展的快速启发式方案。这几乎和Monge-Elkan方案一样有效,但是速度要快一个数量级。结合TFIDF方法和Jaro-Winkler的一种简单方法是用基于Jaro-Winkler方案的近似令牌匹配替换TFIDF中使用的精确令牌匹配。平均而言,此组合的性能比Jaro-Winkler或TFIDF都要好,偶尔也要好得多。在性能上也接近本文所考虑的几种最佳指标的学习组合。
krole
不返回Final Fantasy V: Krile
,尽管我希望返回。它要求查询中的所有字符在结果中以相同的顺序出现,这是很短视的。进行良好模糊搜索的唯一方法似乎是拥有一个常见错别字数据库。