编辑距离计算与Python实现

1 什么是编辑距离

在计算文本的相似性时,经常会用到编辑距离(Levenshtein距离),其指两个字符串之间,由一个字符串转成另一个所需的最少编辑操作次数。在字符串形式上来说,编辑距离越小,那么两个文本的相似性越大,暂时不考虑语义上的问题。其中,编辑操作包括以下三种:

  • 插入:将一个字符插入某个字符串
  • 删除:将字符串中的某个字符删除
  • 替换:将字符串中的某个字符串替换为另一个字符

为了更好地说明编辑距离的概念,我们看看一个例子,将字符串“batyu”变为“beauty”,编辑距离是多少呢?分析步骤如下:

  1. 将batyu插入字符e有:beatyu
  2. 将beatyu删除字符u有:beaty
  3. 将beaty插入字符u有:beauty

所以,字符串“batyu”与字符串“beauty”之间的编辑距离为:3.

2 数学化

先抛开具体编程语言实现,我们简单地分析一下如何计算两个字符串之间的编辑距离

  1. 当两个字符串都为空串的时候,那么编辑距离就是0
  2. 当其中一个字符串为空串时,那么编辑距离为另一个非空字符串的长度
  3. 当两个字符串A,B均为非空时(假设长度分别为i,j),那么有如下三种情况,我们取这三种情况的最小值即可:
    1). 已知字符串A中长为 i - 1(从字符串首开始,以下描述字符串长默认此种描述)和字符串B长为j的编辑距离,那么在此基础上加1即可
    2).长度分别为i,h和j-1的编辑距离已知,那么加1即可
    3).长度分别为i-1和j-1的编辑距离已知,这个时候需要考虑两种情况,若第i个字符和第j个字符不同,那么加1即可,如果相同,那么就不需要加1.

从上面的描述,很明显可以发现是动态规划的思想。
我们将上面的叙述数学化,则有:求长度为m和n的字符A、B串编辑距离,即函数:edit(i,j),它表示第一个长度为i(从字符首开始)的字符串与第二个长度为j的字符串之间的编辑距离。动态规划表达式则有如下写法,假设i,j表示字符串A,B的字串长度:

  • if i==0 且 j==0,edit(i,j)=0
  • if (i==0 且 j>0) 或者(i>0 且j ==0),edit(i,j)=i + j
  • if i>= 1 且 j >= i, edit(i, j) = min(edit(i-1,j) + 1, edit(i, j-1) + 1, edit(i-1,j-1) + d(i,j);当第一个字符串的第i个字符不等于第二个字符串第j个字符时,d(i,j)=1,否则为0

字符串“batyu”与字符串“beauty”之间的编辑距离矩阵则有如下表示:

image

最终的编辑距离即为edit(m,n)。

3 编程实现

有了上面的思路,使用Python去实现计算两个字符串的编辑距离就简单多了。

def edit_distance(str1, str2):
    """
    计算字符串str1和字符串str2的编辑距离
    :param str1:需比较的字符串1
    :param str2:需比较的字符串2
    :return:返回两个字符串的比较距离
    """
    # 构建编辑矩阵,并初始化
    edit = [[i + j for j in range(len(str2) + 1)] for i in range(len(str1) + 1)]

    for i in range(1, len(str1) + 1):
        for j in range(1, len(str2) + 1):
            if str1[i - 1] == str2[j - 1]:
                d = 0
            else:
                d = 1
            edit[i][j] = min(edit[i - 1][j] + 1, edit[i][j - 1] + 1, edit[i-1][j-1]+d)
    # 查看编辑矩阵
    for edit_unit in edit:
        print(edit_unit)

    return edit[len(str1)][len(str2)]


if __name__ == "__main__":
    a = "batyu"
    b = "beauty"
    distance = edit_distance(a, b)
    print(distance)

需要注意的是,在进行初始化编辑距离矩阵的时候,第一列和第一行的数据是需要与实际求解有关的值,不是随机的值。

4 扩展

如果你掌握了计算编辑距离的思路,我们也可以对一些粗颗粒的对象求其编辑距离。例如,我们有两个序列A,B,每个序列中的成分是天气,A=[晴,阴,下雨,大风],B=[多云,阴,阴,下雨]等。其实,这些都是在表达方面的相似,进行具体的语义相似则还需要更多的研究。

Reference

Python如何计算编辑距离?

个人订阅号
更多算法知识等着你

我的订阅号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智绘山河

你的鼓励可能解决你下一个问题

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值