Python中的层次聚类凸壳

时间:2012-10-19 15:40:12

标签: python cluster-analysis computational-geometry convex-hull hierarchical-clustering

我正在使用层次聚类来尝试可视化已被展平为二维的大量数据。我想要做的是创建一个可视化,允许我通过将簇作为其组成点的凸包来查看层次结构中不同高度的数据。这个问题中最棘手的部分是我需要一种能够在向上移动层次结构时有效地合并对簇的凸包的算法。我已经看到很多用于计算O(n log n)时间点的凸包的算法,但在这种情况下似乎更有效地利用问题的子结构,但我是不确定如何。

修改

有关更多信息,数据结构是一个以群集原始点开头的数组,然后说明哪些点/群组合在一起形成下一个群集。所以它有点像树/指针结构,但包含在一个大数组中。重要的是,有效地看到两个组成簇是什么超级簇,但获得属于一个簇的所有点的集合效率不高。所以任何合理的算法都必须自下而上。

所以我们假设我们处于层次结构的中间位置,而预先计算的层次结构表明集群A和B合并以产生集群C.我们从下往上,所以我们已经计算了凸面群集A和B中的点的船体,因此我们只需要将它们组合起来以生成群集C的凸包。群集A的凸包实际上可以是单个点,一对或完整多边形。对于集群B来说也是如此。因此,有几种情况应该如何合并以形成集群C的凸包,但我敢打赌,这是一个聪明的解决方案,可能会对待单体并以与多边形相同的方式配对。

最明显的解决方案是使用来自群A和B的凸包的组合点计算凸包。但是我需要在100k点的层次结构上进行此操作,所以我想知道是否存在一种更有效的方法来组合A和B的凸包。

编辑2:

         /----5
    1---/    / \
   / \      / B 8
  2 A 3  C 6   /
   \ /      \ /
    4--------7

好的,所以我试图用ASCII表示我的意思。 A组凸壳为1-2-3-4,B的凸壳为5-6-7-8,C的凸壳为1-2-4-7-8-5。据推测,集群A和B在其船体内部包含额外的点,但这些明显不可能成为C船体的一部分,因此问题是一种算法确定在哪里“拼接”集群A和B的船体以形成C的船体,基于点的坐标。这是整个过程的归纳步骤。 (最终C将与群集D组合,依此类推,直到算法以最顶层的群集结束,这将使其凸包为所有点的凸包。)

2 个答案:

答案 0 :(得分:3)

我至少知道两种凸包合并算法--Turssaint的rotating calipers(论文的第5部分)和Preparata和Hong的bridging algorithm(见第3节)论文)。这两种算法在 h = h 1 + h 2 中需要时间线性,其中 h 1 h 2 分别是第一和第二凸包中的船体顶点数。

答案 1 :(得分:2)

有多种方法可以让您在添加新点时“更新”凸包。另外一些凸壳和Delaunay三角测量的方法已经很好地从内到外工作,这应该很好地适应这一点。看看s-hull算法。

然而,既然你在谈论层次聚类,那么凸面船体在复杂性方面可能是你最不关心的问题。

分层聚类不能很好地扩展到大型数据集,因为算法本质上通常是O(n^3)(使它们成为您在实践中仍然使用的最慢的聚类算法之一)。所以另外计算一些凸包应该会产生很大的不同,因为你的聚类更贵。您可能只需要快速,渐进地实现O(n log n)凸包算法。