Python 计算树状图叶片的顺序

Python 计算树状图叶片的顺序,python,data-mining,cluster-analysis,dendrogram,Python,Data Mining,Cluster Analysis,Dendrogram,我有五个点,我需要从中创建树状图。“树状图”功能可用于确定这些点的顺序,如下所示。但是,我不想使用树状图,因为它速度慢,并且会导致大量点的错误(我在这里问了这个问题)。有人能告诉我如何将“链接”输出(Z)转换为“树状图(Z)['ivl']”值 为什么慢?当然,计算链接聚类的简单方法是O(n^3),但是对于n=5,这是最便宜的方法了 有关scipy链接矩阵的格式,请参见以下问题: 请注意,您可能仍然需要对数据进行最佳排序。上面的链接矩阵编码给出了 元素1和簇3在高度0.1144处连接(形成一个

我有五个点,我需要从中创建树状图。“树状图”功能可用于确定这些点的顺序,如下所示。但是,我不想使用树状图,因为它速度慢,并且会导致大量点的错误(我在这里问了这个问题)。有人能告诉我如何将“链接”输出(Z)转换为“树状图(Z)['ivl']”值


为什么慢?当然,计算链接聚类的简单方法是
O(n^3)
,但是对于
n=5
,这是最便宜的方法了

有关scipy链接矩阵的格式,请参见以下问题:

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

  • 元素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排序(因为不是每个使用链接聚类的人都希望在之后运行树状图)。但是无论如何,如果您确实需要排序,那么计算树状图的顺序应该是
O(n logn)
,与实际的聚类相比相当便宜

沿着这些思路应该可以做到这一点:

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)]
n=len(Z)+1
cache=dict()
对于范围内的k(len(Z)):
c1,c2=int(Z[k][0]),int(Z[k][1])
c1=[c1]如果c1
这可能看起来是线性的,但是数组的预期大小是
logn
,因此根据列表类型,它可能仍然是
O(nlogn)
,而对于链表,它确实应该在
O(n)
中可以实现


但最终,您可能希望避免层次聚类。这是一个流行的聚类分析入门示例,因为它在概念上很容易理解。有一些相当棘手的算法(SLINK)可以将其归结为
O(n^2)
复杂性。但是有更现代、更强大的聚类算法,它们的复杂性更低。实际上,计算的内容非常类似(当您设置minPts=2时),当您有一个好的索引结构时,它将在
O(n log n)
中运行。此外,还可以增加minPts以获得更有意义的集群。(但不要在Weka中使用光学元件,也不要在四处游荡的python版本中使用光学元件——因为它们都不完整或有缺陷!)

在scipy中有一个专用函数用于计算线性化叶序。给你

我还想知道,在没有scipy树状图函数的情况下,如何创建排序。无论是在这里还是在这两个相关的问题上,都没有给出答案。有一篇论文引起了我的兴趣。甚至可以用光学方法创建一个树状图,不是吗?是的,有一些论文讨论了光学图与规则树状图的关系。我的意思是特别的。然而,原理是什么,在树状图中叶子是按顺序排列的?它是通过某种方式遍历共生矩阵完成的吗?树状图和光学簇顺序本质上都是序列化的最小生成树(具有不同于点到点距离的度量)。虽然此链接可以回答这个问题,最好在这里包括答案的基本部分,并提供链接供参考。如果链接页面发生更改,则“仅链接”答案可能无效。@Dijkgraaf这里没有必要描述整个聚类/排序算法。这根本不是问题。这是软件包的一个重要部分,它是专门为此目的而实现的,因此不太可能发生重大更改。您可以添加一个示例,说明如何使用该函数、需要哪些参数或类似的内容。就目前情况而言,您的答案只是一个边界链接,因此在您不编辑它以添加更多细节的情况下有被删除的风险。
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)]