估计两个集群之间的最小距离
Posted
技术标签:
【中文标题】估计两个集群之间的最小距离【英文标题】:Estimate the minimum Distance between two Clusters 【发布时间】:2016-04-10 21:15:15 【问题描述】:我正在为数百万个 50-1000 维点设计一个凝聚的、自下而上的聚类算法。在我的算法的两个部分中,我需要比较两个点集群并确定两个集群之间的分离。 精确距离是所有点对 P1-P2 上的最小欧几里得距离,其中 P1 取自集群 C1,P2 取自集群 C2。如果 C1 有 X 点,C2 有 Y 点,那么这需要 X*Y 距离测量。
我目前以需要 X+Y 测量的方式估算此距离:
-
找到簇 C1 的质心 Ctr1。
在簇 C2 中找到最接近 Ctr1 的点 P2。 (Y 比较。)
在 C1 中找到最接近 P2 的点 P1。 (X 次比较。)
从 P1 到 P2 的距离是集群 C1 和 C2 之间距离的近似度量。它是真实值的上限。
如果集群大致呈球形,则效果很好。我的测试数据是由椭球高斯簇组成的,所以效果很好。然而,如果集群有奇怪的、折叠的、弯曲的形状,它可能会产生很差的结果。我的问题是:
是否有一种算法使用的距离测量值甚至少于 X+Y 距离测量值,并且在平均情况下会产生良好的准确度?
或
有没有一种算法(像我的一样)使用 X+Y 距离测量但比我的精度更高?
(我正在用 C# 编程,但是用伪代码或任何其他语言描述算法都可以。请避免引用 R 或 Matlab 中的专用库函数。具有概率保证的算法,例如“95% 的机会”距离在最小值的 5% 以内”是可以接受的。)
注意:我刚刚发现了这个相关的问题,它讨论了一个类似的问题,但不一定适用于高维度。 Given two (large) sets of points, how can I efficiently find pairs that are nearest to each other?
注意:我刚刚发现这被称为双色最近对问题。
就上下文而言,这里是整个聚类算法的概述:
第一遍使用空间填充曲线(希尔伯特曲线)将最密集的区域合并为小簇。它错过了异常值,并且经常无法合并彼此非常接近的相邻集群。但是,它确实发现了一个特征最大链接距离。相隔小于该特征距离的所有点必须聚集在一起。此步骤没有预定义的集群数量作为其目标。
如果最小距离小于最大链接距离,第二次通过将集群组合在一起来执行单链接聚集。这不是层次聚类;它是基于分区的。将组合彼此之间的最小距离小于该最大链接距离的所有集群。此步骤没有预定义的集群数量作为其目标。
第三遍执行额外的单链接聚集,对所有集群间距离进行排序,并且仅组合集群,直到集群数量等于预定义的目标集群数量。它处理一些离群值,更喜欢只将离群值与大型集群合并。如果有很多异常值(通常是这样),这可能无法减少目标的聚类数量。
第四次将所有剩余的异常值与最近的大集群合并,但不会导致大集群与其他大集群合并。 (这可以防止两个相邻的簇由于它们的异常值在它们之间形成一条细链而意外合并。)
【问题讨论】:
您尝试过类似that 的方法吗? 不!知道问题的“名称”会有所帮助!谢谢!我会读这篇文章。 文章中的有趣算法。但是,递归分治算法对 D(维数)的依赖是一个问题,因为对我来说,D 通常大于 K(簇数)。我会进一步研究它。 您可以尝试降低维度,还是所有维度都大致同等重要? @kfx - 在我的真实世界数据中,我确定了冗余维度并将其从 40,000 个维度减少到 950 个维度。在后续处理中,我按人口对邮政编码进行加权,但在聚类中,所有不冗余的维度都被认为是同等重要的。 【参考方案1】:您可以使用索引。这是非常经典的解决方案。
空间索引可以帮助您在大约 O(log n) 时间内找到任何点的最近邻居。因此,如果您的集群有 n 和 m 个对象,请选择较小的集群并索引较大的集群,以在 O(n log m) 或 O(m log n) 中找到最接近的对。
一种更简单的启发式方法是多次迭代您的想法,从而缩小您的候选对象。因此,您可以从两个集群中找到一对好的对象 a、b。然后你丢弃每个集群中必须(通过三角不等式)更远(使用上限!)的所有对象。 然后您重复此操作,但不再次选择相同的 a、b。一旦你的候选集停止改进,只对剩余的对象进行成对比较。这种方法的最坏情况应该保持 O(n*m)。
【讨论】:
我的第一遍,使用希尔伯特曲线,类似于使用空间索引。这就是我在聚类中执行第一次切割的方式。然而,如果真正的解决方案有 K 个集群,我倾向于在这一步之后得到 5K 到 10K 之间的集群,因此后续的通过。对超过 20 个维度使用适当的空间索引(如 R 树)将是一个坏主意。我对为大量维度设计的空间索引感兴趣,但目前还没有技能。 在 20+ 维度 distance 不再可靠。这就是索引失败的原因。见维度灾难;这都是关于距离太相似的问题。希尔伯特曲线也会经常在 5 维左右分解。因为要拆分每个维度一次,并且有非空分区,你需要 2^d 个对象。如果你想要一个漂亮的曲线,你至少要有 2^4d 个对象。你有 2^80 个对象吗? 关于 Anony 关于“维度诅咒”的评论,您的数据在所有这些维度上真的存在差异吗? PCA 或 SVD 表示什么? 我太清楚诅咒了!然而,我发现希尔伯特曲线方法在 500 维上对我很有效,但我可能不像其他人那样使用它。 (正如您正确指出的那样,R-Trees 确实以大部分空分区结束,但我没有创建分区。)我假设我的集群是分离良好的。如果重叠集群看起来是多模式的,我计划为第五遍编写一个分裂算法来拆分重叠集群。 @nicholas - 对于我的真实世界数据,我删除了冗余维度(这将我的问题从 40,000 个维度减少到 950 个维度)。在这 950 个维度上,我确实有有意义的差异。 (我的域是使用 UPS 或 Fedex 的邮政编码到邮政编码的交货时间。)【参考方案2】:我找到了一篇论文,描述了一种用于最接近双色点问题的线性时间、随机、epsilon 近似算法:
http://www.cs.umd.edu/~samir/grant/cp.pdf
我将尝试实现它,看看它是否有效。
更新 - 经过进一步研究,很明显运行时间与 3^D 成正比,其中 D 是维数。这是无法接受的。在尝试了其他几种方法后,我想到了以下方法。
-
使用一种有效但不完整的方法将粗略聚类成 K 个聚类。这种方法会正确地聚类一些点,但会产生太多的聚类。这些小集群仍有待进一步整合以形成更大的集群。此方法将确定被视为在同一簇中的点之间的距离上限 DMAX。
按希尔伯特曲线顺序对点进行排序。
丢弃同一集群中的邻居之前和之后的所有点。通常,这些是簇的内部点,而不是表面点。
对于每个点 P1,向前搜索,但不要比同一个簇的下一个点更远。
计算从集群 C1 的点 P1 到集群 C2 的每个访问点 P2 的距离,如果该距离小于 C1 和 C2 中的点之间测量的任何先前距离,则记录该距离。
但是,如果 P1 已经与 C2 中的某个点进行了比较,则不要再这样做了。仅对 P1 和 C2 中的任意点进行一次比较。
完成所有比较后,最多会记录 K(K-1) 个距离,并且由于大于 DMAX 而丢弃了许多距离。这些是估计的最近点距离。
如果集群比 DMAX 更近,则在集群之间执行合并。
很难想象希尔伯特曲线如何在集群之间摆动,所以我估计这种寻找最接近对的方法的效率是它与 K^2 成正比。但是,我的测试表明它更接近 K。它可能在 K*log(K) 左右。需要进一步研究。
至于准确性:
将每个点与其他点进行比较是 100% 准确的。 使用我的问题中概述的质心方法时,距离太高了大约 0.1%。 使用此方法可以找到最坏情况下高出 10%,平均高出 5% 的距离。然而,真正最接近的集群几乎总是出现在第一个到第三个最接近的集群中,所以从质量上来说它是好的。使用这种方法的最终聚类结果非常好。我的最终聚类算法似乎与 DNK 或 DNK*Log(K) 成正比。【讨论】:
以上是关于估计两个集群之间的最小距离的主要内容,如果未能解决你的问题,请参考以下文章
我如何在这个数组中获取数据,如果条件使它成为python中距离最小的集群?
计算 2 个数据帧之间的最小距离并估计一个数据帧中的缺失点位置