计算树状图叶的排序

时间:2012-09-24 20:30:09

标签: python data-mining cluster-analysis dendrogram

我有五点,我需要从这些点创建树状图。函数'dendrogram'可用于查找这些点的顺序,如下所示。但是,我不想使用树形图,因为它很慢并导致大量点的错误(我在这里问了这个问题Python alternate way to find dendrogram)。有人能指出我如何将'连锁'输出(Z)转换为“树状图(Z)['ivl']”值。

>>> from hcluster import pdist, linkage, dendrogram
>>> import numpy
>>> from numpy.random import rand
>>> x = rand(5,3)
>>> Y = pdist(x)
>>> Z = linkage(Y)
>>> Z
array([[ 1.        ,  3.        ,  0.11443378,  2.        ],
       [ 0.        ,  4.        ,  0.47941843,  2.        ],
       [ 5.        ,  6.        ,  0.67596472,  4.        ],
       [ 2.        ,  7.        ,  0.79993986,  5.        ]])
>>> 



>>> dendrogram(Z)['ivl']
['2', '1', '3', '0', '4']
>>> 

2 个答案:

答案 0 :(得分:4)

有一个专用函数用于计算scipy中的线性化叶子顺序。这里是。 scipy.cluster.hierarchy.leaves_list

答案 1 :(得分:2)

为什么慢?当然,计算链接聚类的天真方式是O(n^3),但对于n=5来说,它的价格便宜......

对于scipy连接矩阵的格式,请参阅以下问题: scipy linkage format

请注意,您可能仍需要以最佳方式对数据进行排序。上面编码的链接矩阵给出了

  • 元素1和群集3在高度0.1144处连接(进入2个元素群集,#5)
  • 元素0和群集4在高度0.7999处连接(进入2个元素群集,#6)
  • 群集5和群集6在高度0.6759处连接(进入4个元素群集,#7)
  • 元素2和群集7在高度0.7999处连接(进入5个元素群集,#8)

但它可能是通过链接距离来排序的,而不是用于可视化的1d排序(因为使用链接聚类的任何人都不希望之后运行树状图viusalization)。但无论如何,如果你需要排序,那么计算树形图应该是O(n log n)的量级,与实际的聚类相比相当便宜。

这些方面的东西应该可以解决问题:

n = len(Z) + 1
cache = dict()
for k in range(len(Z)):
  c1, c2 = int(Z[k][0]), int(Z[k][1])
  c1 = [c1] if c1 < n else cache.pop(c1)
  c2 = [c2] if c2 < n else cache.pop(c2)
  cache[n+k] = c1 + c2
print cache[2*len(Z)]

这似乎是线性的,但数组的预期大小为log n,因此根据您的列表类型,它可能仍然是O(n log n),而对于链接列表,它确实可以在O(n)

但最后,您可能希望避免分层聚类。它是聚类分析的一个流行的介绍性示例,因为它在概念上很容易理解。有一些非常棘手的算法(SLINK)可以将其降低到O(n^2)复杂度。但是有更多现代和强大的聚类算法具有较低的复杂性。实际上,OPTICS (Wikipedia)计算的东西非常相似(当你设置minPts = 2时),当你有一个好的索引结构时,它将在O(n log n)中运行。另外,您可以增加minPts以获得更有意义的集群。 (但是不要在Weka中使用OPTICS,或者那些漂浮在周围的python版本 - 假设它们都是不完整或有缺陷的!)