关于python:用于计算两个字符串之间距离的算法

Algorithms for computing the distance between two strings

有没有不考虑单词顺序的字符串距离算法?

以下算法无法给出所需结果(在该示例中,所需结果应为1):

1
2
3
4
5
6
7
8
9
10
11
import jaro
jaro.jaro_winkler_metric(u'Michael Jordan',u'Jordan Michael')
>>>0.47

import Levenshtein
Levenshtein.ratio('Michael Jordan', 'Jordan Michael')
>>>0.5

from difflib import SequenceMatcher
SequenceMatcher(None, 'Michael Jordan', 'Jordan Michael').ratio()
>>>0.5

一种方法是将字符串按字母顺序排列,然后使用上述算法:

1
2
3
4
5
''.join(sorted('Michael Jordan'))
>>>' JMaacdehilnor'

''.join(sorted('Jordan Michael'))
>>>' JMaacdehilnor'

但在这里,名字和姓氏的信息会丢失,不会有"稳定"的结果。

我使用itertools中的permutations创建了一个函数,它获取所有可能的单词编译,比较字符串并输出最大值。结果令人满意,但当我不得不比较数百万个名字时,整个过程真的很慢。

可以做的其他事情是对单词进行排序,例如:

1
2
3
4
' '.join(sorted('Michael Jordan'.split()))
>>>'Jordan Michael'
' '.join(sorted('Jordan Michael'.split()))
>>>'Jordan Michael'

似乎很好的方法和简单的方法来减少计算,但我们松了一些敏感的情况。例子:

1
2
3
4
5
6
7
name1 = ' '.join(sorted('Bizen Dim'.split()))
>>>'Bizen Dim'
name2 = ' '.join(sorted('Dim Mpizen'.split()))
>>>'Dim Mpizen'

SequenceMatcher(None, name1, name2).ratio()
>>>  0.55

这两个名字是相同的,在有些情况下,人们"翻译"他们的名字从"B"到"MP"(我是其中之一)。这样我们就失去了这场比赛。

是否有任何字符串距离算法比较单词而不考虑单词的顺序?或者,是否有一个如何有效地实现所需功能的建议?


尝试模糊模糊

安装:

1
2
pip install fuzzywuzzy
pip install python-Levenshtein

与订单一起使用,而不是磨砂:

1
2
fuzz.token_sort_ratio(u'Michael Jordan',u'Jordan Michael')
>>100

您可以标记这两个字符串(例如,使用NLTK标记器),计算每个词对之间的距离,并返回所有距离的总和。


尝试将其转换为小写,然后进行排序。使用原始字符串排序的问题是,Python认为大写字母的顺序更高。(如果你要去勒文施泰因距离,空间不应该是一个问题)

1
2
>>> ''.join(sorted('Michael Jordan'.lower()))
' aacdehijlmnor'

然后使用.index()方法得到子串位置。(您也可以使用此答案,该答案使用re模块,使其更加可变)