宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

在日常的编程开发工作中,经常需要对字符串进行匹配和比对。而对于一些比较复杂的应用场景,如文本分类、搜索引擎、语音识别等,则需要更为精确的字符串相似度计算。Python中提供了多种方法实现字符串相似度计算。

一、Levenshtein距离

Levenshtein距离是一种常用的字符串相似度度量方法,也被称为编辑距离。它是指把一个字符串转换成另一个字符串所需的最少操作次数,允许的操作包括插入、删除、替换。对于两个字符串s1和s2,Levenshtein距离可以使用下面的Python代码来实现。


import numpy as np

def levenshtein_distance(s1, s2):
    if len(s1) < len(s2):
        s1, s2 = s2, s1
    distances = range(len(s1) + 1)
    for i2, c2 in enumerate(s2):
        distances_ = [i2+1]
        for i1, c1 in enumerate(s1):
            if c1 == c2:
                distances_.append(distances[i1])
            else:
                distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1])))
        distances = distances_
    return distances[-1]
    
# example
s1 = 'kitten'
s2 = 'sitting'
distance = levenshtein_distance(s1, s2)
print(distance)  # output: 3

上述代码中,定义了一个函数levenshtein_distance,它接受两个字符串s1和s2作为参数,返回它们之间的Levenshtein距离。函数实现过程使用了动态规划的思想。我们通过一个distances列表来保存每一个字符的编辑距离,其中distances[i]表示s1的前i个字符与s2的前j个字符之间的编辑距离。然后,我们根据s1和s2的字符匹配情况计算出distances[i+1]。最后,返回distances[-1]即可得到两个字符串之间的Levenshtein距离。

二、Jaccard相似系数

Jaccard相似系数是一种用于度量样本之间相似性的方法,主要用于计算两个集合之间的相似度。对于两个集合A和B,它的Jaccard相似系数可以使用下面的Python代码来实现。


def jaccard_similarity(set1, set2):
    intersection = len(set1 & set2)
    union = len(set1 | set2)
    return intersection / union
    
# example
set1 = set(['apple', 'banana', 'orange'])
set2 = set(['banana', 'watermelon', 'orange'])
similarity = jaccard_similarity(set1, set2)
print(similarity)  # output: 0.4

上述代码中,定义了一个函数jaccard_similarity,它接受两个集合set1和set2作为参数,返回它们之间的Jaccard相似系数。函数实现过程很简单,首先计算两个集合的交集,然后计算它们的并集并将交集除以并集得到相似系数。

三、余弦相似度

余弦相似度是一种常用的文本相似度计算方法,主要用于统计分析、数据挖掘、信息检索等任务中。对于两个向量A和B,余弦相似度可以使用下面的Python代码来实现。


def cosine_similarity(vector1, vector2):
    dot_product = np.dot(vector1, vector2)
    norm1 = np.linalg.norm(vector1)
    norm2 = np.linalg.norm(vector2)
    return dot_product / (norm1 * norm2)
    
# example
vector1 = np.array([1, 2, 3])
vector2 = np.array([4, 5, 6])
similarity = cosine_similarity(vector1, vector2)
print(similarity)  # output: 0.9746318461970762

上述代码中,定义了一个函数cosine_similarity,它接受两个向量vector1和vector2作为参数,返回它们之间的余弦相似度。函数实现过程使用了NumPy库中的dot和linalg.norm函数。首先,我们计算vector1和vector2的点积,然后分别计算它们的范数,最后将点积除以范数的乘积即可得到两个向量之间的余弦相似度。

四、编辑距离

编辑距离是一种比较字符串相似度的方法,它可以通过插入、删除、替换等操作从一个字符串变为另一个字符串所需的最小步骤数。对于两个字符串s1和s2,编辑距离可以使用下面的Python代码来实现。


import numpy as np

def edit_distance(s1, s2):
    m, n = len(s1), len(s2)
    dp = np.zeros((m+1, n+1))
    for i in range(m+1):
        dp[i][0] = i
    for j in range(n+1):
        dp[0][j] = j
    for i in range(1, m+1):
        for j in range(1, n+1):
            if s1[i-1] == s2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = 1 + min(dp[i][j-1],        # Insert
                                   dp[i-1][j],        # Remove
                                   dp[i-1][j-1])      # Replace
    return dp[m][n]
    
# example
s1 = 'kitten'
s2 = 'sitting'
distance = edit_distance(s1, s2)
print(distance)  # output: 3

上述代码中,定义了一个函数edit_distance,它接受两个字符串s1和s2作为参数,返回它们之间的编辑距离。函数实现过程使用了动态规划的思想。我们首先定义一个m+1行n+1列的dp矩阵,其中dp[i][j]表示s1的前i个字符与s2的前j个字符之间的编辑距离。然后,初始化dp矩阵的第一行和第一列。接着,我们在一个双重循环中遍历s1和s2的每一个字符,如果它们相等,我们就将dp[i][j]赋值为dp[i-1][j-1];否则,我们就从dp[i][j-1]、dp[i-1][j]、dp[i-1][j-1]三个方向中选取一个最小值并加1,得到dp[i][j]。最后,返回dp[m][n]即可得到两个字符串之间的编辑距离。