引入
衡量两个序列的相似度,可以用马氏距离,欧氏距离等距离公式来度量。
但对两个字符串,比如kitten
与sitting
的相似度是多少?
如果是两个等长字符串,也可以用one-hot对每个字母编码,然后用马氏、欧式距离也可以计算。但对不等长的两个字符串,怎么计算相似度呢?
更一般的说法,如何计算两个不等长数组的相似度呢?
莱文斯坦(Levenshtein)距离
莱文斯坦距离就用是来解决这个问题的。先看它的公式:
其中a
,b
是两个数组(字符串),i/j是数组下标。莱文斯坦距离
的含义,是求将a
变成b
(或将b
变成a
),所需要做的最少次数的变换。
举个例子,字符串”kitten”与”sitting”的莱文斯坦距离
是3, 应为将一个字符串变为另一个字符串,最小需要做三次变换:
- kitten → sitten (字符k变为s)
- sitten → sittin (字符e变成i)
- sittin → sitting (在末尾插入字符g)
python实现
莱文斯坦距离
的python模块在这里https://github.com/ztane/python-Levenshtein/,它同时支持python2和python3。
(1)安装Levenshtein模块
pip install python-Levenshtein
(2)计算两个字符串的相似度
import Levenshtein
s1 = 'kitten'
s2 = 'sitting'
ratio = Levenshtein.ratio(s1, s2)
dist = Levenshtein.distance(s1, s2)
print('ratio={0}, dist={1}'.format(ratio, dist))
# ratio=0.6153846153846154, dist=3
(3)计算两个字符串list的相似度
import Levenshtein
a = ['1','2','3','4','5']
b = ['2','3','4']
Levenshtein.seqratio(a, b)# 0.75
我在github这里(https://github.com/ybdesire/machinelearning/blob/master/ml_related_alg/levenshtein_distance.ipynb)给出了完整示例代码。