nlp

编辑距离

"编辑距离"

Posted by zwt on July 13, 2020

概念

编辑距离又称Levenshtein Distance,主要用来衡量两个序列的相似程度。具体指的是:

1
2
3
4
5
6
两个序列之间,由一个序列转换到另一个序列所需要的的次数
主要的操作包含:插入、删除、修改
例子:
abc->ab:将abc删除一个字符即可,编辑距离为1
ab->abc:在ab后加一个字符即可,编辑距离为1
abd->abc:将字符d换为字符c即可,编辑距离为1

公式以及解释

\(\operatorname{lev}_{a, b}(i, j)=\left\{\begin{array}{ll} \max (i, j) & \text { if } \min (i, j)=0 \\ \min \left\{\begin{array}{ll} \operatorname{lev}_{a, b}(i-1, j)+1 & \text { otherwise } \\ \operatorname{lev}_{a, b}(i, j-1)+1 & \\ \left(\operatorname{lev}_{a, b}(i-1, j-1)+1_{\left(a_{i} \neq b_{j}\right)}\right. \end{array}\right. \end{array}\right.\) 第一行表示的是:当第一个序列或者第二个序列为空的时候,那个整个的变换过程就是增加相应长度的字符即可。

第二行到第四行统一处理一般的情况:

1
2
3
4
第二行表示:通过一定的操作将i-1,变为j,然后再将i移除即可
第三行表示:通过一定的操作将i变为j-1,然后再加上j即可
第四行表示:通过一定的操作i-1转换为j-1,后面如果i=1,则结束,如果i不等j则再修改i为j。
2,3,4综合得到操作次数最少的结果。

实现

递归形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def edit_distence(str1, str2):
    """递归"""
    if len(str1) == 0:
        return len(str2)
    elif len(str2) == 0:
        return len(str1)
    elif str1 == str2:
        return 0

    if str1[len(str1) - 1] == str2[len(str2) - 1]:
        d = 0
    else:
        d = 1

    return min(edit_distence(str1, str2[:-1]) + 1,
               edit_distence(str1[:-1], str2) + 1,
               edit_distence(str1[:-1], str2[:-1]) + d)

动态规划:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def edit_distence(str1, str2):
    """动态规划"""
    import numpy as np
    matrix = np.zeros((len(str1) + 1, len(str2) + 1), dtype=np.int)
    matrix[0] = np.arange(len(str1) + 1)
    matrix[:, 0] = np.arange(len(str2) + 1)
    # matrix = [[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

            matrix[i][j] = min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + d)

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

Levenshtein 包的使用

1
Levenshtein.distance(str1, str2)

应用

  1. 错别字纠正
  2. 也可以作为一种相似度算法
  3. 拼音检查