是否有任何相似性函数来比较两个字符串并给它们一个分数,比如 scipy cosinesimilarity 来比较数组?

数据挖掘 Python 数据挖掘 文本挖掘 数据清理
2022-03-05 17:53:59

我想比较字符串并根据它们中内容的相似程度给它们打分,就像比较两个数组的 scipy 余弦相似度一样。

例如 :

字符串一:'一双女鞋'

字符串二:'女鞋'对'

从逻辑上讲,我想要两个字符串之间的高分。有什么办法吗?我正在将字符串数组与数据框中单列中的另一个数组进行比较。我想以这种方式找到类似的行。这可以实现吗?

2个回答

Levenshtein 距离的计算成本很高,因此对于大型数据集来说很慢。对于更快的方法,您可以使用 sci-kit learn 的 CountVectorizer 或 TfidfVectorizer 来获取每个字符串的 n-gram 频率。这将产生一个频率矩阵,然后您可以将其用作 sklearn.metrics.pairwise_distances() 的输入,这将为您提供成对距离矩阵。请注意,对于距离矩阵,接近 0 的值是更相似的对(而在余弦相似度矩阵中,接近 0 的值是不太相似的对)。

有关如何进行此操作的精彩教程,请参阅此博客文章。

你可以试试 Levenshtein 距离。来自维基百科,这是摘要

在信息论、语言学和计算机科学中,Levenshtein 距离是衡量两个序列之间差异的字符串度量。非正式地,两个单词之间的 Levenshtein 距离是将一个单词更改为另一个单词所需的最小单字符编辑(插入、删除或替换)次数。

然后你可以使用这个 Python 函数自己计算它,或者只安装一个 Python 包来为你完成它

memo = {}
def levenshtein(s, t):
    if s == "":
        return len(t)
    if t == "":
        return len(s)
    cost = 0 if s[-1] == t[-1] else 1

    i1 = (s[:-1], t)
    if not i1 in memo:
        memo[i1] = levenshtein(*i1)
    i2 = (s, t[:-1])
    if not i2 in memo:
        memo[i2] = levenshtein(*i2)
    i3 = (s[:-1], t[:-1])
    if not i3 in memo:
        memo[i3] = levenshtein(*i3)
    res = min([memo[i1]+1, memo[i2]+1, memo[i3]+cost])

    return res
print(levenshtein("Python", "Pethno"))
print(levenshtein("Pair of women's shoes","women shoes' pair"))

>> 3
>> 16

上述代码段的源代码

或者,如果您想直接在 DataFrame 上执行此操作,您可以这样做

df['LD'] = df.apply(lambda row: levenshtein(row['text1'], row['text2']), axis=1)