【问题标题】:Clustering algorithms with custom distance function in PythonPython中具有自定义距离函数的聚类算法
【发布时间】:2017-04-18 18:03:41
【问题描述】:

我有一个聚类问题,我认为它需要直观的距离函数。每个实例都有一个 x、y 坐标,但也有一组描述它的属性(每个实例的数量不同)。理想情况下,可以将 pythonobjects(类的实例)传递给它,并根据它们的内容任意比较它们。

我想将距离表示为 x、y 值之间的欧几里得距离的加权和,以及类似 jaccard 索引的东西,以测量其他属性的集合重叠。比如:

dist = (euclidean(x1, y1, x2, y2) * 0.6) + (1-jaccard(attrs1, attrs2) * 0.4)

我发现的大多数聚类算法和实现都将实例特征转换为数字。例如,使用 sklearn 中的 dbscan,要执行我的距离函数,我需要以某种方式将数字转换回原始表示。

如果可以使用可以以任意方式比较实例的距离函数进行聚类,那就太好了。例如,想象一个欧几里得距离函数,如果对象在另一个非空间特征上匹配,它将评估为更接近。

def dist(ins1, ins2):
     euc = euclidean(ins1.x, ins1.y, ins2.x, ins2.y)
     if ins1.feature1 == ins2.feature1:
          euc = euc * 0.9
     return euc         

有没有适合这种情况的方法?如果不必预先设置集群的数量也很好(但这对我来说并不重要)。

【问题讨论】:

    标签: python cluster-analysis


    【解决方案1】:

    实际上,几乎所有的聚类算法(除了对于k-means,显然需要数字来计算mean)都可以与任意距离函数一起使用。

    在 sklearn 中,大多数算法接受 metric="precomputed"距离矩阵,而不是原始输入数据。请更仔细地检查文档。例如DBSCAN:

    如果度量是“预先计算的”,则假定 X 是一个距离矩阵并且必须是方阵。

    您失去的是通过索引来加速某些算法的能力。计算距离矩阵是 O(n^2),所以你的算法不可能比这更快。在 sklearn 中,您需要修改 sklearn Cython 代码以添加新的距离函数(不幸的是,使用 pyfunc 会产生非常糟糕的性能)。诸如ELKI can be extended with little overhead 之类的Java 工具,因为Java 的即时编译器对此进行了很好的优化。如果您的距离是 metric,那么许多索引可用于加速,例如DBSCAN。

    【讨论】:

    • 谢谢!我完全忘记了“预计算”模式。幸运的是,在我的情况下 O(n^2) 复杂度很好。
    猜你喜欢
    • 2012-07-09
    • 2021-01-24
    • 2014-01-25
    • 2016-12-20
    • 1970-01-01
    • 2013-09-25
    • 2021-08-01
    • 1970-01-01
    • 2014-03-15
    相关资源
    最近更新 更多