我正在尝试编写一个拼写检查模块。
它加载一个文本,从16 mb文件创建一个字典,然后检查遇到的单词是否与字典中的单词相似(类似=最多两个字符),如果是,则将其从字典中更改为表单。 / p>
现在我正在使用Levenshtein距离算法,处理50个单词需要3分钟......
我很确定必须有更快的解决方案。 Profiler告诉我,我的应用程序花费了超过80%的时间在Levenshtein距离函数中。
有没有更好的解决方案/算法?
以下是我使用的算法版本的实现:
def levenshteinDistance(s1, s2):
l_s1 = len(s1)
l_s2 = len(s2)
d = [[a for a in genM(x, l_s2 + 1)] for x in xrange(l_s1 + 1)]
for i in xrange(1, l_s1 + 1):
for j in xrange(1, l_s2 + 1):
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + decide_of_equality(s1[i - 1],s2[j - 1]))
return d[l_s1][l_s2]
答案 0 :(得分:2)
我使用了Norvig的拼写纠正器,在评论中提到它很棒。
然而,遇到问题,你已经写了一个动态编程编辑距离算法。您的算法有资格成为数据并行算法。在共享内存上,即在一台机器上,如果你有多核,你可以利用它们。你知道map-reduce吗?请不要认为分布式,现在就好,只考虑一个四核机器和一个共享内存。作为第1步,您可以对字典进行分区,并为每个线程分配一部分,该部分将在字典的一部分上运行编辑距离(类似于地图步骤)。之后所有的线程都会返回编辑距离为2的所有单词(类似于reduce步骤)。这样,您的程序将受益于多核架构。
我能想到的另一件事是你的python代码在C中编写cpu密集编辑距离算法,即写一个python扩展。
答案 1 :(得分:0)
也许问题处于更高的水平。当分析器告诉您在函数中花费了大量时间时,可能是您经常调用它。你是否可能将文本中的每个单词与字典中的每个单词进行比较?反过来试试:对于文本中的单词,直接生成距离<= 2的单词并检查它们是否在字典中。