【问题标题】:Convex hulls of hierarchical clustering in PythonPython中层次聚类的凸壳
【发布时间】:2012-10-10 06:35:18
【问题描述】:

我正在使用层次聚类来尝试可视化已扁平化为二维的大量数据。我想要做的是创建一个可视化,允许我通过将集群渲染为其组成点的凸包来查看层次结构中不同高度的数据。这个问题最难的部分是我需要一种算法,当我向上移动时,它可以有效地合并对集群的凸包。我已经看到了很多用于在 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 组合,依此类推,直到算法以最顶层的集群结束,该集群将以所有点的凸包作为其凸包)。

【问题讨论】:

  • 您能否更详细地解释一下您打算利用什么以及当前的数据结构究竟是怎样的?
  • 你能添加一张简单的图片来展示它应该是什么样子吗? (特别是你说“这个问题最困难的部分是我需要一种算法,当我向上移动时,我需要一种算法可以有效地合并对集群的凸包”)

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


【解决方案1】:

有多种方法可让您在添加新点时“更新”凸包。此外,一些凸包和 Delaunay 三角剖分的方法已经很好地由内而外地工作,这应该很好地发挥作用。看看 s-hull 算法。

但是,由于您在谈论层次聚类,因此在涉及复杂性时,凸包可能是您最不关心的问题。

层次聚类不能很好地扩展到大型数据集,因为这些算法本质上通常是O(n^3)(使其成为您发现仍在实践中使用的最慢的聚类算法之一)。因此,考虑到您的聚类成本更高,另外计算多个凸包应该不会产生太大影响。您可能只需要快速、增量地实现 O(n log n) 凸包算法。

【讨论】:

  • 我会研究 s-hull... 我的理解是,层次聚类在某些情况下效率更高——单链接的 O(n^2) 和 O(n^2 log n) 对于其他一些情况。但是,如果您有其他建议,请开火;我基本上希望能够在地图上渲染集群,智能地选择适当的层次结构级别。到目前为止,我已经运行了整整一周的集群 :) 不过,K-means 在计算上看起来并没有好多少。但是任何事情都可以,我只需要一个合理的数据可视化表示,集群的保真度并不重要。
  • 只有O(n^2) 如果你有一个 good 实现。如果是通常的基于矩阵的实现,则为O(n^3)。在您的情况下,索引可能要聪明得多。甚至也研究四叉树。它们非常简单,这使得它们非常快(尤其是在内存中时;R-tree 更适合磁盘操作)。
  • 我一直在使用具有 O(n^2) 实现的 Python Fastcluster (math.stanford.edu/~muellner/fastcluster.html),尽管它仍然非常慢。我不确定单独的树结构是否合适。我现在正在研究 DBSCAN 和 OPTICS 等基于密度的算法,这些算法可能适合我的需求,并且具有可接受的性能。
  • 请注意,根据我的经验,DBSCAN 和 OPTICS 的 Weka、R 和 Python 版本的速度非常慢,但它是一种实现方式。 ELKI 实现——据说是相同的算法——在我的数据集上快了 2+ 个数量级。
  • 不管我怎么看,我真的只是被灌醉了,嗯?但是,是的,我已经看到您在其他一些问题上使用 ELKI 的建议,所以我一直在努力为我的数据集启动并运行它。 OPTICS 上的 ELKI 文档看起来很稀少,但我会试一试。
【解决方案2】:

我知道至少有两种凸包合并算法——Toussaint 的rotating calipers(论文的第 5 部分)和 Preparata 和 Hong 的 bridging algorithm(见论文的第 3 部分)。这两种算法都在 h = h1 + h2 中采用线性时间,其中 h1h2 分别是第一个和第二个凸包中的包顶点数。

【讨论】:

    猜你喜欢
    • 2011-02-25
    • 2016-10-31
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 2014-06-28
    • 2021-07-21
    • 2015-04-24
    相关资源
    最近更新 更多