使用相似性函数进行scikit-learn聚类
我用一个函数来计算一对文档之间的相似度,然后想用这个相似度来进行聚类分析。
到目前为止的代码:
Sim=np.zeros((n, n)) # create a numpy arrary
i=0
j=0
for i in range(0,n):
for j in range(i,n):
if i==j:
Sim[i][j]=1
else:
Sim[i][j]=simfunction(list_doc[i],list_doc[j]) # calculate similarity between documents i and j using simfunction
Sim=Sim+ Sim.T - np.diag(Sim.diagonal()) # complete the symmetric matrix
AggClusterDistObj=AgglomerativeClustering(n_clusters=num_cluster,linkage='average',affinity="precomputed")
Res_Labels=AggClusterDistObj.fit_predict(Sim)
我担心的是,我这里用了一个相似度函数,但我觉得根据文档的情况,它应该是一个不相似度矩阵,我该怎么把它改成不相似度矩阵呢?还有,有没有更有效的方法来做到这一点?
1 个回答
5
请正确格式化你的代码,因为在Python中,缩进是很重要的。
如果可以的话,保持代码完整(你漏掉了一个
import numpy as np
)。因为
range
总是从零开始,所以你可以省略零,直接写range(n)
。在numpy中,索引的方式是用[行, 列]来表示。
所以你应该写Sim[i, j]
,而不是Sim[i][j]
,因为后者会先取整行,然后再取列,这样效率低。这里还有一种方法可以把上三角的元素复制到下三角:Sim = np.identity(n) # diagonal with ones (100 percent similarity) for i in range(n): for j in range(i+1, n): # +1 skips the diagonal Sim[i, j]= simfunction(list_doc[i], list_doc[j]) # Expand the matrix (copy triangle) tril = np.tril_indices_from(Sim, -1) # take lower & upper triangle's indices triu = np.triu_indices_from(Sim, 1) # (without diagonal) Sim[tril] = Sim[triu]
假设你的相似度在(0, 1)的范围内,要把相似度矩阵转换成距离矩阵,你可以简单地这样做:
dm = 1 - Sim
这个操作会被numpy自动优化。