了解 python 中 kmeans 聚类的输出



我有两个距离矩阵,每个 232*232,其中列和行标签相同。因此,这将是两者的删节版本,其中 A、B、C 和 D 是测量距离的点的名称:

A  B  C  D ...    A  B  C  D  ...
A 0  1  5  3      A 0  5  3  9
B 4  0  4  1      B 2  0  7  8  
C 2  6  0  3      C 2  6  0  1
D 2  7  1  0      D 5  2  5  0
...               ...

因此,这两个矩阵表示两个不同网络中点对之间的距离。我想识别在一个网络中靠近而另一个网络中相距很远的对簇。为此,我尝试首先通过将每个距离除以矩阵中的最大距离来调整每个矩阵中的距离。然后,我从一个矩阵中减去另一个矩阵,并将聚类算法应用于生成的矩阵。建议我为此使用的算法是k均值算法。希望我能识别出正数簇,这些簇对应于矩阵一中非常接近的对,在矩阵二中相距很远的对,反之亦然,负数簇。

首先,我已经阅读了很多关于如何在python中实现k方法的信息,我知道可以使用多个不同的模块。我已经尝试了所有这三个:

1.

import sklearn.cluster
import numpy as np
data = np.load('difference_matrix_file.npy') #loads difference matrix from file
a = np.array([x[0:] for x in data])
clust_centers = 3
model = sklearn.cluster.k_means(a, clust_centers)
print model 

阿拉伯数字。

import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.cluster import KMeans
difference_matrix = np.load('difference_matrix_file.npy') #loads difference matrix from file
data = pd.DataFrame(difference_matrix)
model = KMeans(n_clusters=3)
print model.fit(data)

3.

import numpy as np
from scipy.cluster.vq import vq, kmeans, whiten
np.set_printoptions(threshold=np.nan)
difference_matrix = np.load('difference_matrix_file.npy') #loads difference matrix from file
whitened = whiten(difference_matrix) 
centroids = kmeans(whitened, 3) 
print centroids

我正在努力解决的是如何解释这些脚本的输出。(在这一点上,我可能会补充一点,如果读者还没有猜到的话,我既不是数学家也不是计算机科学家)。我期望算法的输出是聚类对的坐标列表,每个聚类一个,在这种情况下是三个,然后我可以追溯到我的两个原始矩阵并识别感兴趣的对的名称。

然而,我得到的是一个包含数字列表的数组(每个集群一个),但我真的不明白这些数字是什么,它们显然与我的输入矩阵中的内容不对应,除了每个列表中有 232 个项目,与输入矩阵中的行数和列数相同。数组中的列表项是另一个数字,我认为它一定是集群的质心,但每个集群没有一个,整个数组只有一个。

我一直在试图解决这个问题很长一段时间,但我正在努力到达任何地方。每当我搜索解释kmeans的输出时,我只会得到有关如何在图上绘制集群的解释,这不是我想要做的。请有人向我解释我在输出中看到的内容以及如何从中获取每个集群中项目的坐标?

您有两个问题,并且 k 均值的建议可能不是很好......

  1. K 均值需要坐标数据矩阵,而不是距离矩阵

    为了计算质心,它需要原始坐标。如果您没有这样的坐标,则可能不应该使用 k 均值。

  2. 如果计算两个距离矩阵
  3. 的差值,则较小的值对应于两个矩阵中距离相似的点。这些可能仍然相距很远!因此,如果您将此矩阵用作新的"距离"矩阵,您将获得毫无意义的结果。考虑点 A 和 B,它们在两个原始图形中具有最大距离。手术后,它们的差异为 0,因此现在将被视为相同

所以你还没有理解k-means的输入,难怪你不理解输出

我宁愿将差分矩阵视为相似性矩阵(尝试绝对值,仅正值,仅负值)。然后使用分层聚类分析。但是您将需要一个相似性的实现,距离矩阵的通常实现将不起作用。

免责声明:下面,我试图回答你关于如何解释函数返回的内容以及如何从中获取集群中的点的问题。我同意@Anony-Mousse的观点,如果你有一个距离/相似性矩阵(而不是特征矩阵),你将需要使用不同的技术,例如光谱聚类。

抱歉直言不讳,我也讨厌"RTFM"类型的答案,但您使用的功能在以下位置有很好的记录:

  • sklearn.cluster,
  • scipy.cluster.vq?

总之

  • 模型sklearn.cluster.k_means()返回一个包含三个字段的元组:
    • 带有质心的数组(应该为您3x232)
    • 每个点的标签分配(即值为 0-2 的 232 长数组)
    • 和"intertia",衡量聚类的好坏程度; 有几种措施可以做到这一点,所以你最好不要太关注这一点;
  • scipy.cluster.vq.kmeans2()返回一个包含两个字段的元组:
    • 簇质心(如上)
    • 标签分配(如上所述)
    • kmeans()返回一个"失真"值而不是标签赋值,所以我肯定会使用kmeans2().

至于如何到达每个聚类中点的坐标,您可以:

for cc in range(clust_centers):
print('Points for cluster {}:n{}'.format(cc, data[model[1] == cc]))

其中modelsklearn.cluster.k_meansscipy.cluster.vq.kmeans2返回的元组,datapoints x coordinates数组,difference_matrix在你的例子中。

最新更新