有PyCluster的问题

时间:2015-05-27 14:18:30

标签: python cluster-analysis

我有一个跟随python代码:

  from Pycluster import *
  from numpy import *
  import matplotlib.pyplot as plt

   names = [ "A1", "A2", "A3", "A4", "A5", "A6", "A7", 
             "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15"]

   distances = array([
   [0.000, 0.840, 0.860, 0.115, 0.150, 0.055, 0.000, 0.070, 0.065, 0.000, 0.165, 0.000, 0.000, 0.000, 0.065],
   [0.840, 0.000, 0.710, 0.060, 0.125, 0.060, 0.000, 0.070, 0.065, 0.000, 0.165, 0.000, 0.000, 0.000, 0.070],
   [0.860, 0.710, 0.000, 0.055, 0.120, 0.055, 0.000, 0.070, 0.065, 0.000, 0.000, 0.000, 0.000, 0.000, 0.065],
   [0.115, 0.060, 0.055, 0.000, 0.885, 0.455, 0.415, 0.060, 0.150, 0.050, 0.240, 0.000, 0.000, 0.065, 0.140],
   [0.150, 0.125, 0.120, 0.885, 0.000, 0.510, 0.330, 0.125, 0.165, 0.050, 0.145, 0.000, 0.000, 0.000, 0.200],
   [0.055, 0.060, 0.055, 0.455, 0.510, 0.000, 0.335, 0.060, 0.215, 0.050, 0.140, 0.000, 0.000, 0.000, 0.085],
   [0.000, 0.000, 0.000, 0.415, 0.330, 0.335, 0.000, 0.000, 0.245, 0.060, 0.255, 0.125, 0.000, 0.075, 0.225],
   [0.070, 0.070, 0.070, 0.060, 0.125, 0.060, 0.000, 0.000, 0.195, 0.000, 0.000, 0.000, 0.000, 0.000, 0.140],
   [0.065, 0.065, 0.065, 0.150, 0.165, 0.215, 0.245, 0.195, 0.000, 0.045, 0.135, 0.000, 0.000, 0.000, 0.155],
   [0.000, 0.000, 0.000, 0.050, 0.050, 0.050, 0.060, 0.000, 0.045, 0.000, 0.000, 0.120, 0.000, 0.045, 0.080],
   [0.165, 0.165, 0.000, 0.240, 0.145, 0.140, 0.255, 0.000, 0.135, 0.000, 0.000, 0.000, 0.000, 0.150, 0.150],
   [0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.125, 0.000, 0.000, 0.120, 0.000, 0.000, 0.175, 0.090, 0.105],
   [0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.175, 0.000, 0.000, 0.000],
   [0.000, 0.000, 0.000, 0.065, 0.000, 0.000, 0.075, 0.000, 0.000, 0.045, 0.150, 0.090, 0.000, 0.000, 0.000],
   [0.065, 0.070, 0.065, 0.140, 0.200, 0.085, 0.225, 0.140, 0.155, 0.080, 0.150, 0.105, 0.000, 0.000, 0.000]
   ])

   clusterids, error, nfound = kmedoids(distances, 6)
   print "Cluster ids:", clusterids
   print "error:", error
   print "nfound:", nfound

   cities_in_cluster = {}
   for name, clusterid in zip(names, clusterids):
        cities_in_cluster.setdefault(clusterid, []).append(name)

   import textwrap
   for centroid_id, city_names in cities_in_cluster.items():
        print "Cluster around", names[centroid_id]
        text = ", ".join(city_names)
        for line in textwrap.wrap(text, 70):
             print "  ", line

   colors = ['red', 'green', 'blue', 'yellow', 'white', 'black']

   medoids = {}  
   for i in clusterids:
        medoids[i]= medoids.get(i,0) + 1    

   plt.scatter(distances[:,0],distances[:,1], c=colors)
   plt.show()

此代码提出了两个问题:
- 每次执行都会产生不同的聚类结果。是不是? - 图表仅绘制了11个点,而不是15个点。

错误在哪里?

谢谢。

2 个答案:

答案 0 :(得分:1)

kmedoids使用随机初始化,并可能会收敛到本地最小值。

所以是的,如果你多次运行它会得到不同的结果。

距离矩阵是否有可能不是距离

<0>值太多

[0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.175, 0.000, 0.000, 0.000]

是一个极端的例子。通过查看矩阵,所有点基本相同,因为从任何一点您都可以找到到任何其他点的0距离链!因此,您的矩阵不是距离矩阵。这种违反基本距离属性的行为可能导致kmedoids被杀,并导致它返回基本上随机的结果?

此外,不散布距离矩阵。散点图用于输入数据,而不是距离矩阵的前两行。如果要从距离矩阵重建散点图,请使用多维缩放

答案 1 :(得分:0)

对于问题的第2部分,如果仅在距离的第二维中取前两个值,则只有11个唯一点。即。

[[ 0.     0.84 ]
 [ 0.84   0.   ]
 [ 0.86   0.71 ]
 [ 0.115  0.06 ]
 [ 0.15   0.125]
 [ 0.055  0.06 ]
 [ 0.     0.   ]
 [ 0.07   0.07 ]
 [ 0.065  0.065]
 [ 0.     0.   ] # duplicate
 [ 0.165  0.165]
 [ 0.     0.   ] # duplicate
 [ 0.     0.   ] # duplicate
 [ 0.     0.   ] # duplicate
 [ 0.065  0.07 ]]

我不确定这对你的第一个问题是否有帮助但也许它表明距离的内容与你期望的形式不同?