Python 拼写检查加速
我写了一个拼写检查器:Python 拼写检查加速,python,loops,spell-checking,Python,Loops,Spell Checking,我写了一个拼写检查器: import operator class Corrector(object): def __init__(self,possibilities): self.possibilities = possibilities def similar(self,w1,w2): w1 = w1[:len(w2)] w2 = w2[:len(w1)] return sum([1 if i==j el
import operator
class Corrector(object):
def __init__(self,possibilities):
self.possibilities = possibilities
def similar(self,w1,w2):
w1 = w1[:len(w2)]
w2 = w2[:len(w1)]
return sum([1 if i==j else 0 for i,j in zip(w1,w2)])/float(len(w1))
def correct(self,w):
corrections = {}
for c in self.possibilities:
probability = self.similar(w,c) * self.possibilities[c]/sum(self.possibilities.values())
corrections[c] = probability
return max(corrections.iteritems(),key=operator.itemgetter(1))[0]
这是一本类似以下内容的词典:
{word1:value1}
其中value是单词在语料库中出现的次数
相似函数返回单词w1和w2之间的相似概率
在correct
函数中,您可以看到软件循环遍历所有可能的结果,然后计算每个结果是w的正确拼写的概率
我可以通过移除循环来加速代码吗
现在我知道这个问题可能没有答案,如果我不能告诉我我不能 您只需缓存
更正的结果
,这样在下一次使用相同世界的通话中,您就可以在不进行任何计算的情况下知道答案。您只需缓存更正的结果
,这样,在同一个世界的下一次通话中,您将不用任何计算就能知道答案。给您
from operator import itemgetter
from difflib import SequenceMatcher
class Corrector(object):
def __init__(self, possibilities):
self.possibilities = possibilities
self.sums = sum(self.possibilities.values())
def correct(self, word):
corrections = {}
sm = SequenceMatcher(None, word, '')
for w, t in self.possibilities.iteritems():
sm.b = w
corrections[w] = sm.ratio() * t/self.sums
return max(corrections.iteritems(),key=itemgetter(1))[0]
给你
from operator import itemgetter
from difflib import SequenceMatcher
class Corrector(object):
def __init__(self, possibilities):
self.possibilities = possibilities
self.sums = sum(self.possibilities.values())
def correct(self, word):
corrections = {}
sm = SequenceMatcher(None, word, '')
for w, t in self.possibilities.iteritems():
sm.b = w
corrections[w] = sm.ratio() * t/self.sums
return max(corrections.iteritems(),key=itemgetter(1))[0]
您通常不希望将提交的令牌与语料库中的所有令牌进行检查。减少必要计算(从而减少
for
循环中的调用)的“经典”方法是维护文档集合中存在的所有(三元)图的索引。基本上,一方面维护集合中所有标记的列表,另一方面维护一个哈希表,其中哪些键是gram,哪些值是列表中标记的索引。这可以通过类似DBM的数据库持久化
然后,在检查单词拼写时,将其拆分为克数,搜索集合中包含相同克数的所有标记,按与提交标记的克数相似性对它们进行排序,然后执行距离计算
此外,代码的某些部分可以简化。例如,这:
def similar(self,w1,w2):
w1 = w1[:len(w2)]
w2 = w2[:len(w1)]
return sum([1 if i==j else 0 for i,j in zip(w1,w2)])/float(len(w1))
可简化为:
def similar(self, w1, w2, lenw1):
return sum(i == j for i, j in zip(w1,w2)) / lenw1
其中lenw1是“w1”的预计算长度。您通常不希望根据语料库中的所有标记检查提交的标记。减少必要计算(从而减少
for
循环中的调用)的“经典”方法是维护文档集合中存在的所有(三元)图的索引。基本上,一方面维护集合中所有标记的列表,另一方面维护一个哈希表,其中哪些键是gram,哪些值是列表中标记的索引。这可以通过类似DBM的数据库持久化
然后,在检查单词拼写时,将其拆分为克数,搜索集合中包含相同克数的所有标记,按与提交标记的克数相似性对它们进行排序,然后执行距离计算
此外,代码的某些部分可以简化。例如,这:
def similar(self,w1,w2):
w1 = w1[:len(w2)]
w2 = w2[:len(w1)]
return sum([1 if i==j else 0 for i,j in zip(w1,w2)])/float(len(w1))
可简化为:
def similar(self, w1, w2, lenw1):
return sum(i == j for i, j in zip(w1,w2)) / lenw1
其中lenw1是“w1”的预计算长度。注意:
similor
的实现非常简单,它不能很好地用于字符擦除(例如:I实现)。如果我是你,我会使用这里提供的答案:检查相似性@Haidro?注意2:@tenstar可能,但是Inbar提供的一个更为准确。注意:similor
的实现非常幼稚,它不适合字符擦除(例如:I实现)。如果我是你,我会使用Inbar Rose提供的答案:检查相似性@Haidro?注意2:@tenstar可能,但是英巴提供的那一个更准确为什么要投否决票?这是一个很大的性能改进,几乎没有任何编码。我也没有得到反对票,但你可以在这里做得更好:使用装饰器来记忆函数。您只需从许多在线示例中的任何一个复制memoize装饰器,然后只需将@memoize
添加到函数定义中即可。我没有提到如何实现缓存,您提到的只是一种方法。您可能希望这样做,以便它在应用程序级别工作,在启动时重新加载最后一个状态;我甚至没有想过要多次跑步。我也不知道为什么你会实施拼写检查,而不使用其中一个已经可用。不要重新发明轮子之类的东西。为什么要投否决票?这是一个很大的性能改进,几乎没有任何编码。我也没有得到反对票,但你可以在这里做得更好:使用装饰器来记忆函数。您只需从许多在线示例中的任何一个复制memoize装饰器,然后只需将@memoize
添加到函数定义中即可。我没有提到如何实现缓存,您提到的只是一种方法。您可能希望这样做,以便它在应用程序级别工作,在启动时重新加载最后一个状态;我甚至没有想过要多次跑步。我也不知道为什么你会实施拼写检查,而不使用其中一个已经可用。不要重新发明轮子之类的东西。是的,那可能会更快,但是有没有办法绕过for循环?它更快,你自己检查一下。但是不,如果不循环检查列表中的每个单词,是不可能的。循环没有什么错-但是,如果你想你可以指定中断条件,比如如果比率是100%,那么你可以立即返回这个词等等。。。。不管你做什么-在代码中的某个地方,你都必须逐字逐句,无论是实时迭代还是事先准备字典。。。你需要循环。但是如果你的单词语料库有一万亿个条目,我只需要几年(不是真的)就能找到正确的拼写!是的,这可能会更快,但是有没有办法绕过for循环?它更快,请检查