使用相似性函数进行scikit-learn聚类

4 投票
1 回答
2684 浏览
提问于 2025-04-19 15:25

我用一个函数来计算一对文档之间的相似度,然后想用这个相似度来进行聚类分析。
到目前为止的代码:

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自动优化。

撰写回答