有关stackoverflow的一些问题提到了这个问题,但我还没有找到具体的解决方案。
我有一个由余弦相似性(0到1之间的值)组成的方阵,例如:
| A | B | C | D
A | 1.0 | 0.1 | 0.6 | 0.4
B | 0.1 | 1.0 | 0.1 | 0.2
C | 0.6 | 0.1 | 1.0 | 0.7
D | 0.4 | 0.2 | 0.7 | 1.0
方阵可以是任何大小。我想获得最大化集群中元素之间的值的集群(我不知道有多少)。即对于上面的例子,我应该得到两个集群:
原因是因为C& D在它们之间具有最高值,并且A& C也具有最高值。
项目只能在一个群集中。
召回对于这个问题并不重要,但精确度非常重要。输出三个簇是可以接受的:1)B,2)A,3)C,D。但是输出任何其中B与另一个元素在一个簇中的解决方案是不可接受的。
我认为对角线(1.0)令我感到困惑。我的数据保证至少有一个2+元素的集群,我想在不牺牲精度的情况下找到尽可能多的集群。
我将不得不在Python中实现它。
答案 0 :(得分:13)
您可以使用谱聚类轻松完成此操作。您可以使用现成的实现,例如sklearn中的实现,也可以自己实现。这是一个简单的算法。
这是使用sklearn在python中执行的一段代码:
import numpy as np
from sklearn.cluster import SpectralClustering
mat = np.matrix([[1.,.1,.6,.4],[.1,1.,.1,.2],[.6,.1,1.,.7],[.4,.2,.7,1.]])
SpectralClustering(2).fit_predict(mat)
>>> array([0, 1, 0, 0], dtype=int32)
如您所见,它会返回您提到的群集。
该算法采用与最大特征值对应的输入矩阵的前k个特征向量,然后在新矩阵上运行k均值算法。这是一个简单的代码,可以为您的矩阵执行此操作:
from sklearn.cluster import KMeans
eigen_values, eigen_vectors = np.linalg.eigh(mat)
KMeans(n_clusters=2, init='k-means++').fit_predict(eigen_vectors[:, 2:4])
>>> array([0, 1, 0, 0], dtype=int32)
请注意,sklearn库中算法的实现可能与我的不同。我给出的例子是最简单的方法。网上有一些很好的教程可以深入描述谱聚类算法。
对于您希望算法自行计算出群集数量的情况,您可以使用基于密度的聚类算法,例如 DBSCAN :
from sklearn.cluster import DBSCAN
DBSCAN(min_samples=1).fit_predict(mat)
array([0, 1, 2, 2])