Skip to main content
 首页 » 编程设计

python之文本中术语的二阶共现

2025年05月04日15del

基本上,I want to reimplement this video .

给定一个文档语料库,我想找到彼此最相似的术语。

我能够使用 this SO thread 生成共现矩阵并使用视频生成关联矩阵。接下来,我想生成一个二阶共现矩阵。

问题陈述:考虑一个矩阵,其中矩阵的行对应于一个术语,行中的条目对应于与该术语相似的前 k 个术语。比如说,k = 4,我们的字典中有 n 个术语,那么矩阵 M 有 n 行和 4 列。

拥有:

M = [[18,34,54,65],   # Term IDs similar to Term t_0 
     [18,12,54,65],   # Term IDs similar to Term t_1 
     ... 
     [21,43,55,78]]   # Term IDs similar to Term t_n. 

因此,对于每个术语 ID,M 包含最相似的术语 ID。现在,我想检查这些相似术语中有多少匹配。在上面的 M 示例中,术语 t_0 和术语 t_1 似乎非常相似,因为四分之三的术语匹配,其中术语 t_0 和 t_n 不相似,因为没有术语匹配。让我们将 M 写成一系列列表。

M = [list_0,   # Term IDs similar to Term t_0 
     list_1,   # Term IDs similar to Term t_1 
     ... 
     list_n]   # Term IDs similar to Term t_n. 

想要:

C = [[f(list_0, list_0), f(list_0, list_1), ..., f(list_0, list_n)], 
     [f(list_1, list_0), f(list_1, list_1), ..., f(list_1, list_n)], 
     ... 
     [f(list_n, list_0), f(list_n, list_1), ..., f(list_n, list_n)]] 

我想找到矩阵 C,它的元素是一个应用于 M 列表的函数 f。 f(a,b) 衡量两个列表a 和b 之间的相似程度。继续上面的例子,t_0和t_1的相似度应该很高,而t_0和的相似度>t_n 应该很低。

我的问题:

  1. 比较两个列表的顺序的最佳选择是什么?也就是说,函数 f 的最佳选择是什么?
  2. 是否已经有一种转换可以将像 M 这样的矩阵作为输入并生成像 C 这样的矩阵?最好是 python 包?

谢谢你,r0f1

请您参考如下方法:

事实上,在这种情况下,余弦相似度可能还不算太差。问题是,您不想使用索引向量(即 [18,34,54,65] 等等),但您想要长度为 的向量n 除了索引向量中的值外,所有地方都为零。幸运的是,您不必显式创建这些向量,但您可以只计算两个索引向量共有多少个索引:

def f(u, v): 
    return len(set(u).intersection(set(v))) 

这里,我省略了一个常数归一化因子k。人们可以做一些更精细的事情(例如 TF-IDF 内核),但我会一开始就坚持这一点。

为了使用 numpy 高效地运行它,您需要做两件事:

将 f 转换为 ufunc,即 numpy 向量化函数。您可以通过 uf = np.frompyfunc(f, 2, 1) 来做到这一点(假设您在某个时间点import numpy as np)。

将 M 存储为列表的一维数组(基本上是您在第二个代码 list 中声明的​​内容)。这有点棘手,因为 numpy 在这里试图变得聪明,但你想要别的东西。所以这里是如何做到这一点:

n = len(M) 
Marray = np.empty(n, dtype='O')  # dtype='O' allows you to have elements of type list 
for i in range(n): 
    Marray[i] = M[i] 

现在,Marray 基本上包含您在第二个代码 list 中描述的内容。然后,您可以使用新的 ufunc 的 outer 方法来获取相似度矩阵。以下是示例中的 M 所有这些如何协同工作(假设 n=3):

M = [[18, 34, 54, 65], 
     [18, 12, 54, 65], 
     [21, 43, 55, 78]] 
n = len(M)  # i.e. 3 
uf = np.frompyfunc(f, 2, 1) 
Marray = np.empty(n, dtype='O') 
for i in range(n): 
    Marray[i] = M[i] 
similarities = uf.outer(Marray, Marray).astype('d')  # convert to float instead object type 
print(similarities) 
# array([[4., 3., 0.], 
#        [3., 4., 0.], 
#        [0., 0., 4.]]) 

我希望这能回答您的问题。