从Python中的“enchant suggest()”中获取最相关的单词(拼写检查)

从Python中的“enchant suggest()”中获取最相关的单词(拼写检查),python,spell-checking,Python,Spell Checking,我想从enchant suggest获得最相关的单词。有没有更好的办法。我觉得我的功能在检查100k或更大范围内的大量单词时效率不高 enchant的问题建议: 我的功能是从一组建议的单词中获取适当的单词: import enchant, difflib word="prfomnc" dict,max = {},0 a = set(d.suggest(word)) for b in a: tmp = difflib.SequenceMatcher(None, word, b).rati

我想从enchant suggest获得最相关的单词。有没有更好的办法。我觉得我的功能在检查100k或更大范围内的大量单词时效率不高

enchant的问题建议:

我的功能是从一组建议的单词中获取适当的单词:

import enchant, difflib word="prfomnc" dict,max = {},0 a = set(d.suggest(word)) for b in a: tmp = difflib.SequenceMatcher(None, word, b).ratio(); dict[tmp] = b if tmp > max: max = tmp print dict[max] Result: performance 更新:


如果我得到多个键,意味着相同的difflib比率值,我就使用多键字典。正如这里所解释的:

如果你只对最好的匹配感兴趣,你实际上不需要保留口述

>>> word="prfomnc"
>>> best_words = []
>>> best_ratio = 0
>>> a = set(d.suggest(word))
>>> for b in a:
...   tmp = difflib.SequenceMatcher(None, word, b).ratio()
...   if tmp > best_ratio:
...     best_words = [b]
...     best_ratio = tmp
...   elif tmp == best_ratio:
...     best_words.append(b)
... 
>>> best_words
['performance']
恐怕没有魔弹。。。但也有一些建议

我猜逻辑中的大部分时间都花在difflib的SequenceMatcher.ratio调用上。这并不奇怪,因为这种方法使用的是一个相对昂贵的变量,CPU方面的,但它产生的度量是在标记上定位接近的匹配,这可能就是你喜欢它的原因

当然,您应该分析这个逻辑,并确认SequenceMatcher确实是热点。也许Enchant.suggest也有点慢,但是我们可以做的很少,从代码角度来看,要改进这个配置,可能有一些选项,例如,取消个人词典以保存双重查找和合并等

假设SequenceMatcher确实是罪魁祸首,并且假设您希望坚持使用Ratcliff Obershelp相似性度量作为选择最佳匹配的方法,您可以执行以下[部分]操作:

仅计算Enchant中前5项的SequenceMatcher比率值。毕竟,Enchant.suggest会以一种有序的方式返回其建议,首先返回其最佳猜测;因此,尽管基于不同的启发式,附魔顺序也是有价值的,但找到高排名匹配的机会可能会随着列表的下移而减少。此外,即使我们最终可能会忽略一些高排名的匹配,通过只测试排名前几位的Enchant建议,我们以某种方式将Enchant的启发中发现的智慧与Ratcliff Obershelp度量中的智慧结合起来。 达到某个阈值后,停止计算SequenceMatcher比率 这个想法与前面的想法类似:一旦发现更好的可能性越来越小,并且一旦我们手头有了一个不错的(如果不是最好的)选择,就不要调用SequenceMatcher 用你自己的逻辑过滤掉一些单词。 我们的想法是进行一个相对快速/廉价的测试,该测试可能会告诉我们,给定的单词不太可能在SequenceMatcher比率上取得好成绩。例如,排除不具有至少(比如)用户字符串长度减去两个公共字符的单词。 顺便说一句,您可能可以使用SequenceMatcher对象的一些[FASTER]函数来获取一些用于过滤启发的数据。 改用SequenceMatcher*quick_ratio*函数 至少在某些情况下。 只保留字符串中的最佳匹配项,而不是使用字典 显然,只有最重要的选择才重要,因此,除了测试目的,您可能不需要字典的[相对较小的]开销。 你可以考虑写自己的RAT悬崖OBESELP或类似的方法,在其中介绍各种早期出口,当满足当前最大比率的可能性很小。注意,很可能很难产生一个像difflib的C语言方法那样高效的方法,您对此感兴趣的是早期退出。。。
嗯,祝你好运-

假设100k个单词中的某些单词是相同的,您可以记忆函数结果。不要使用dict或max作为变量名,它们会隐藏内置项,我也认为使用list而不是dict。但是list似乎比dict慢得多。这些是我的timeit值:list=0.20800385952&dict=0.111775200367。我的timeit代码打印t.timeit100/100
>>> word="prfomnc"
>>> best_words = []
>>> best_ratio = 0
>>> a = set(d.suggest(word))
>>> for b in a:
...   tmp = difflib.SequenceMatcher(None, word, b).ratio()
...   if tmp > best_ratio:
...     best_words = [b]
...     best_ratio = tmp
...   elif tmp == best_ratio:
...     best_words.append(b)
... 
>>> best_words
['performance']