OPTICS(聚类)算法的 Python 实现

Posted

技术标签:

【中文标题】OPTICS(聚类)算法的 Python 实现【英文标题】:Python Implementation of OPTICS (Clustering) Algorithm 【发布时间】:2011-07-27 19:19:10 【问题描述】:

我正在寻找 Python 中 OPTICS 算法的体面实现。我将使用它来形成基于密度的点簇((x,y) 对)。

我正在寻找可以接收 (x,y) 对并输出集群列表的东西,其中列表中的每个集群都包含属于该集群的 (x,y) 对列表。

【问题讨论】:

你看过 SciPy:docs.scipy.org/doc/scipy/reference/cluster.html OPTICS 是一种如此陌生/未知的算法,以至于我的问题没有引起注意吗? =( @pyrony - 我正在寻找一种基于密度的聚类方法。此外,在 K-Means 中指定“k”值并不适合我正在处理的任务。 链接的***文章中有一些伪代码,你试过翻译吗?如果有,您遇到了什么问题? 对我来说,这将是第一个选择 - 这是了解更多关于您最终最终使用的实现的最佳方式... 【参考方案1】:

请参阅“基于密度的聚类方法” http://www.chemometria.us.edu.pl/index.php?goto=downloads

【讨论】:

感谢 vartec 的回答,但对我来说实施似乎不完整。我正在寻找可以接收 (x,y) 对并输出集群列表的东西,其中列表中的每个集群都包含属于该集群的 (x,y) 对列表。【参考方案2】:

您想查看空间填充曲线或空间索引。 sfc 将 2d 复杂度降低到 1d 复杂度。你想看看尼克的希尔伯特曲线四叉树空间索引博客。您想在 phpclasses.org (hilbert-curve) 下载我的 sfc 实现。

【讨论】:

感谢墓志铭,但这究竟是如何回答我的问题的?你能再澄清一下你的答案吗? sfc 是一种使用分形的聚类算法。希尔伯特曲线的分形维数为 2。如果您有 2d 数据,您可以轻松地将这些数据细分为更小的图块。基本上这是一个重新排序。这就像将它们存储在四叉树中。您还可以使用自适应 sfc,其中跳过空区域或具有较低粒度的 sfc。 Sfc 常用于地图,如谷歌地图。 听起来不错,值得一试。谢谢你。但我仍在寻找 Python 中的 OPTICS 实现。 没问题,我不知道OPTICS,我也不懂。在我看来它正在使用空间索引,但我不明白为什么。 有了空间索引,OPTICS 可以运行在O(n log n) 而不是O(n^2)。因此,对于大型、可索引的数据集,这会产生很大的不同。不过,R*-Tree 可能是比 sfc 更好的选择。【参考方案3】:

编辑:已知以下内容不是是 OPTICS 的完整实现。

我进行了快速搜索,发现以下内容 (Optics)。我不能保证它的质量,但是算法看起来很简单,所以你应该能够快速验证/适应它。

下面是一个快速示例,说明如何在光学算法的输出上构建集群:

def cluster(order, distance, points, threshold):
    ''' Given the output of the options algorithm,
    compute the clusters:

    @param order The order of the points
    @param distance The relative distances of the points
    @param points The actual points
    @param threshold The threshold value to cluster on
    @returns A list of cluster groups
    '''
    clusters = [[]]
    points   = sorted(zip(order, distance, points))
    splits   = ((v > threshold, p) for i,v,p in points)
    for iscluster, point in splits: 
        if iscluster: clusters[-1].append(point)
        elif len(clusters[-1]) > 0: clusters.append([])
    return clusters

    rd, cd, order = optics(points, 4)
    print cluster(order, rd, points, 38.0)

【讨论】:

感谢 Bashwork,但这似乎与 vartec 建议的代码完全相同。问题是,我无法弄清楚如何从该算法的输出中提取聚类结构(哪些元素属于哪个聚类)。请查看我的问题最底部的“注释”。 因此代码为您提供了提取集群所需的输出(顺序和可达距离)。如果您查看 wikipedia 部分以提取集群,您只需在距离上设置一个阈值(较低的阈值意味着更多的集群)来遍历有序结果。 (en.wikipedia.org/wiki/OPTICS_algorithm)。如果这没有意义,我可以给出一些示例代码。 我刚刚运行了您发布的代码,我得到的阈值为 38 的结果是 [[31.0, 87.0], [73.0, 9.0]] [[5.0, 8.0]] [[97.0 , 9.0]] (3 个集群)。我将阈值降低到 10,并且只有 1 个集群。我使用的测试数据与您提供的链接(testX)中使用的数据相同。如果您能更正代码,我将不胜感激,我会奖励您的赏金。 根据我对算法的理解,这些结果是正确的,因为每次有序集合下降到给定阈值以下时都会创建一个集群。在 38 的情况下,有三个谷,而在 10 的情况下,只有一个(零结果)。阈值基本上控制了应该被视为山谷的地方。 我对这一切持保留态度。它大大偏离了我对这个算法的理解。您可能希望获得官方实现(不是在 python 中)并比较结果。【参考方案4】:

我不知道 OPTICS 的 完整 和精确的 Python 实现。此处发布的链接似乎只是 OPTICS 想法的粗略近似。它们也不使用索引进行加速,因此它们将在O(n^2) 甚至更可能在O(n^3) 中运行。

除了显而易见的想法之外,OPTICS 还有许多棘手的事情。特别是,建议使用相对阈值(“xi”)而不是此处发布的绝对阈值来完成阈值处理(此时结果将近似于 DBSCAN!)。

原始 OPTICS 论文包含将算法输出转换为实际集群的建议方法:

http://www.dbs.informatik.uni-muenchen.de/Publikationen/Papers/OPTICS.pdf

Weka 中的 OPTICS 实现基本上是未维护并且同样不完整。它实际上并不产生集群,它只计算集群顺序。为此,它复制了数据库 - 它不是真正的 Weka 代码。

最初发布 OPTICS 的小组在 Java 中的 ELKI 中似乎有一个相当广泛的实现。您可能想针对这个“官方”版本测试任何其他实现。

【讨论】:

确实,周围有很多不完整的 OPTICS 实现和 Weka 版本的克隆。您应该以 ELKI 版本为参考。 在我看来,相对阈值是一个相对清晰的展示和方法过渡到更模糊的东西的点,带有额外的启发式和隐藏参数。可能没有办法解决这个问题,但我绝对认为中间有序可达性值构成了一个独立的好结果。之后发生的事情对不同的方法持开放态度,本文中选择的方法并非不言而喻,以至于成为唯一值得考虑的方法。 对于如何从图中精确聚类,至少还有两种方法被提出。然而,没有这样的聚类提取方法,它真的是聚类算法吗?在某些时候,您确实希望从中获得集群,而不仅仅是一个情节。 请注意,绝对阈值意味着您正在执行 DBSCAN,而不是 OPTICS。只是更复杂,因此更慢。【参考方案5】:

虽然从技术上讲不是 OPTICS,但在 https://github.com/lmcinnes/hdbscan 上提供了适用于 python 的 HDBSCAN* 实现。这相当于具有无限最大 epsilon 的 OPTICS,以及不同的集群提取方法。由于该实现提供了对生成的集群层次结构的访问,因此如果您愿意,您也可以通过更传统的 OPTICS 方法从中提取集群。

请注意,尽管不限制 epsilon 参数,但此实现仍然使用基于 kd-tree 和 ball-tree 的最小生成树算法 and can handle quite large datasets 实现 O(n log(n)) 性能。

【讨论】:

【参考方案6】:

现在存在库 pyclustering,其中包含 Python 和 OPTICS 的 C++ 实现等。

【讨论】:

【参考方案7】:

现在在 sklearn(python 的聚类和机器学习模块)的开发版本(scikit-learn v0.21.dev0)中实现

这里是链接: https://scikit-learn.org/dev/modules/generated/sklearn.cluster.OPTICS.html

【讨论】:

以上是关于OPTICS(聚类)算法的 Python 实现的主要内容,如果未能解决你的问题,请参考以下文章

optics聚类算法

密度聚类密度聚类过程OPTICS算法

OPTICS聚类算法详解

精品聚类算法 optics

密度聚类OPTICS算法

SIGAI机器学习第二十五集 聚类算法2