有效地确定列表的“排序方式”,例如。 Levenshtein距离

时间:2011-11-21 02:24:02

标签: python sorting permutation levenshtein-distance ranking-functions

我正在对排名算法进行一些研究,并且想要给出排序列表和该列表的一些排列,计算两个排列之间的一些距离。对于Levenshtein距离的情况,这对应于计算序列与该序列的分类副本之间的距离。例如,还有“反转距离”,其线性时间算法详细here,我正在努力实施。

有没有人知道反演距离的现有python实现,和/或Levenshtein距离的优化?我在大约50,000到200,000个元素的序列上进行计算,因此O(n ^ 2)太慢,但O(n log(n))或更好应该足够。

排列相似性的其他指标也将受到赞赏。


为来自未来的人编辑:

基于Raymond Hettinger's response;它不是Levenshtein或反转距离,而是“格式塔模式匹配”:P

from difflib import SequenceMatcher
import random
ratings = [random.gauss(1200, 200) for i in range(100000)]
SequenceMatcher(None, ratings, sorted(ratings)).ratio()

在可怕的桌面上运行约6秒钟。

Edit2:如果您可以将序列强制转换为[1 .. n]的排列,则曼哈顿指标的变体非常快,并且会产生一些有趣的结果。

manhattan = lambda l: sum(abs(a - i) for i, a in enumerate(l)) / (0.5 * len(l) ** 2)
rankings = list(range(100000))
random.shuffle(rankings)
manhattan(rankings) # ~ 0.6665, < 1 second

归一化因子在技术上是近似值;它对于偶数大小的列表是正确的,但对于奇数大小的列表应该是(0.5 * (len(l) ** 2 - 1))

编辑3:还有其他一些用于检查列表相似性的算法! Kendall Tau排名系数和Spearman排名系数。这些实现在SciPy库中以scipy.stats.kendalltauscipy.stats.rspearman的形式提供,并将返回排名以及相关的p值。

1 个答案:

答案 0 :(得分:4)

Levenshtein距离是一种O(n ** 2)算法,因此如果您想要更快,请使用difflib module中的替代快速算法。 ratio 方法计算两个序列之间的相似性度量。

如果你必须坚持使用Levenshtein,那么在ASPN Python Cookbook上有一个Python配方:http://code.activestate.com/recipes/576874-levenshtein-distance/

可在以下位置找到另一个Python脚本:http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Python