Python中的字符串距离矩阵

Posted

技术标签:

【中文标题】Python中的字符串距离矩阵【英文标题】:String Distance Matrix in Python 【发布时间】:2016-09-22 13:49:30 【问题描述】:

如何在 Python 中计算字符串的 Levenshtein 距离矩阵

              str1    str2    str3    str4    ...     strn
      str1    0.8     0.4     0.6     0.1     ...     0.2
      str2    0.4     0.7     0.5     0.1     ...     0.1
      str3    0.6     0.5     0.6     0.1     ...     0.1
      str4    0.1     0.1     0.1     0.5     ...     0.6
      .       .       .       .       .       ...     .
      .       .       .       .       .       ...     .
      .       .       .       .       .       ...     .
      strn    0.2     0.1     0.1     0.6     ...     0.7

使用距离函数,我们可以计算两个单词之间的距离。但在这里我有 1 个包含 n 个字符串的列表。我想计算距离矩阵,然后我想对单词进行聚类。

【问题讨论】:

使用 NLTK metrics 和 this 帖子可能对您有所帮助 参考这个rosettacode.org/wiki/Levenshtein_distance#Python @Tanu 它给出了两个单词之间的距离。我想要 n 个单词的矩阵 @AjayJadhav 在任何时候都将计算两个单词之间的距离,因此您可以遍历矩阵并一次计算每组两个单词的距离并填充一个新矩阵 @Tanu 我为此写下了代码。谢谢@Tanu 和@Niranj Rajasekaran 【参考方案1】:

只需使用接受自定义指标的pdist 版本。

Y = pdist(X, levensthein)

对于levensthein,您可以按照 Tanu 的建议使用 Rosettacode 的实现

如果您想要一个完整的平方矩阵,只需在结果上使用squareform

Y = scipy.spatial.distance.squareform(Y)

【讨论】:

不需要编写算法,有几个 PyPI 包可以实现它,例如editdistance, pylev. @elabard Pylev 适用于 2 个单词,但我的问题是如何计算矩阵 pylev.levenshtein('kitten', 'sitting') 3 这不正是我所建议的吗? pdist 通过将levensthein 或您想要的任何指标应用于每对元素来返回一个矩阵... 在传递字符串列表时,pdist 表示“必须传递二维数组。” .reshape(-1,1)重塑你的输入【参考方案2】:

你可以这样做

from Levenshtein import distance
import numpy as np
from time import time

def get_distance_matrix(str_list):
    """ Construct a levenshtein distance matrix for a list of strings"""
    dist_matrix = np.zeros(shape=(len(str_list), len(str_list)))
    t0 = time()
    print "Starting to build distance matrix. This will iterate from 0 till ", len(str_list) 
    for i in range(0, len(str_list)):
        print i
        for j in range(i+1, len(str_list)):
                dist_matrix[i][j] = distance(str_list[i], str_list[j]) 
    for i in range(0, len(str_list)):
        for j in range(0, len(str_list)):
            if i == j:
                dist_matrix[i][j] = 0 
            elif i > j:
                dist_matrix[i][j] = dist_matrix[j][i]
    t1 = time()
    print "took", (t1-t0), "seconds"
    return dist_matrix

str_list = ["analyze", "analyse", "analysis", "analyst"]
get_distance_matrix(str_list)

Starting to build distance matrix. This will iterate from 0 till  4
0
1
2
3
took 0.000197887420654 seconds
>>> array([[ 0.,  1.,  3.,  2.],
   [ 1.,  0.,  2.,  1.],
   [ 3.,  2.,  0.,  2.],
   [ 2.,  1.,  2.,  0.]])

【讨论】:

【参考方案3】:

这是我的代码

import pandas as pd
from Levenshtein import distance
import numpy as np

Target = ['Tree','Trip','Treasure','Nothingtodo']

List1 = Target
List2 = Target

Matrix = np.zeros((len(List1),len(List2)),dtype=np.int)

for i in range(0,len(List1)):
  for j in range(0,len(List2)):
      Matrix[i,j] = distance(List1[i],List2[j])

print Matrix

[[ 0  2  4 11]
 [ 2  0  6 10]
 [ 4  6  0 11]
 [11 10 11  0]]

【讨论】:

正如我在回答中建议的那样,您不必手动进行嵌套...pdist 会以更有效的方式为您完成,因为它只计算上三角距离.. .(距离总是对称的)

以上是关于Python中的字符串距离矩阵的主要内容,如果未能解决你的问题,请参考以下文章

数据框列中的字符串列表行之间的成对距离

给定距离矩阵的 Python 中的最近邻

python - 如何使用python中的haversine库计算大距离矩阵?

如何从 Python 中的 scipy 中的链接/距离矩阵计算集群分配?

将纬度和经度放入距离矩阵,python中的google map API

最小编辑距离python