理解python {k}中的kmeans聚类输出

时间:2017-04-05 10:20:30

标签: python matrix k-means

我有两个距离矩阵,每个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均值算法。希望是我可以识别正数的簇,这些正对应于矩阵1中非常接近但在矩阵2中相距很远的对,而对于负数簇则相反。

首先,我已经阅读了很多关于如何在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 

2

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的输出时,我就会得到如何在图形上绘制聚类的解释,这不是我想要做的。请有人向我解释一下我在输出中看到的内容,以及如何从中获取每个群集中项目的坐标?

2 个答案:

答案 0 :(得分:1)

你有两个问题,k-means的建议可能不是很好......

  1. K-means需要一个坐标数据矩阵,而不是距离矩阵

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

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

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

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

答案 1 :(得分:0)

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

对于直言不讳,我也讨厌" RTFM"类型的答案,但您使用的功能在以下文档中有详细记录:

简而言之,

  • 模型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在您的情况下