Python实现OPTICS(聚类)算法

32 投票
7 回答
23940 浏览
提问于 2025-04-16 14:54

我在找一个不错的Python实现的OPTICS算法。我要用它来形成基于密度的点的聚类,也就是一组一组的(x,y)坐标。

我希望这个实现能够接收(x,y)坐标对,然后输出一个聚类的列表,每个聚类里面包含属于这个聚类的(x,y)坐标对的列表。

7 个回答

7

虽然严格来说这不是OPTICS,但在Python中有一个HDBSCAN*的实现,可以在这个链接找到:https://github.com/lmcinnes/hdbscan。这个实现相当于OPTICS,只不过它的最大epsilon值是无限的,而且提取聚类的方法也不同。因为这个实现可以访问生成的聚类层次结构,所以如果你愿意,也可以通过更传统的OPTICS方法从中提取聚类。

需要注意的是,尽管这个实现没有限制epsilon参数,但它仍然能以O(n log(n))的性能运行,使用的是基于kd-tree和ball-tree的最小生成树算法,并且可以处理相当大的数据集

10

我不知道有没有一个完整且准确的Python版本的OPTICS。这里分享的链接似乎只是对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的代码。

ELKI中,似乎有一个相当全面的Java实现,是最初发布OPTICS的团队提供的。你可能想把其他实现和这个“官方”版本进行对比测试。

8

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

我做了个快速搜索,找到了这个链接(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)

撰写回答