关于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
方形矩阵可以具有任何大小。我想获得簇(我不知道多少),以最大化群集中的元素之间的值。IE。对于上面的示例,我应该得到两个群集:
- b
- a,c,d
原因是因为C&D之间的价值最高,A&C之间也具有最高的值。
一个项目只能在一个集群中。
回忆对于这个问题并不重要,但是精度非常重要。输出三个簇是可以接受的:1)b,2)a,3)c,d。但是,输出b在带有另一个元素的群集中的任何解决方案是不可接受的。
我认为对角线(1.0)使我感到困惑。我的数据可以保证至少具有一个2个以上元素的群集,我想在不牺牲精度的情况下找到尽可能多的簇。
我将不得不在Python中实施。
您可以使用光谱群集轻松执行此操作。您可以使用现成的实现,例如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库中算法的实现可能与我的不同。我给出的例子是最简单的方法。有一些很好的教程在线可用,以深入描述光谱群集算法。
对于您希望算法本身弄清楚簇数的情况,您可以使用密度的群集算法 suke dbscan :
from sklearn.cluster import DBSCAN
DBSCAN(min_samples=1).fit_predict(mat)
array([0, 1, 2, 2])