python - 在 Python 中使用自定义距离函数对任意对象进行聚类

标签 python scikit-learn cluster-analysis

我有一个 Python 对象列表,我想将这些对象聚集到未知数量的组中。这些对象不能简单地通过 scikit-learn 提出的任何距离函数进行比较,而是通过自定义定义的距离函数进行比较。我正在使用 scikit-learn 库中的 DBSCAN,当在我的数据上运行时会引发 TypeError。
这是错误代码的样子。我想要聚类的对象是通过扫描 3d 网格获得的“补丁”对象:

from sklearn.cluster import DBSCAN

def getPatchesSimilarity(patch1, patch2):
    ... #Logic to calculate distance between patches
    return dist 

#Reading the data (a mesh object) and extracting its patches
mesh = readMeshFromFile("foo.obj")
patchesList = extractPatchesFromMesh(mesh)

clustering = DBSCAN(metric = getPatchesSimilarity).fit(np.array([[patch] for patch in meshPatches]))
运行时,此代码产生以下错误:
TypeError: float() argument must be a string or a number, not 'Patch'
这似乎意味着 scikit-learn 提出的 DBSCAN 算法不适用于非向量或字符串的值?
我也尝试过只使用补丁的索引,以便传递的数据是数字的,但它也不起作用。现在可行的最后一个解决方案是使用距离矩阵,但是对象的数量非常大,我的计算机无法存储这样的矩阵。

最佳答案

简短回答:对这两个部分都不是。

  • Adding an API for user-defined distance functions in clustering ” 自 2012 年以来一直是一个悬而未决的问题。( 编辑 :我错过了一个部分: DBSCAN 确实支持传递 metric 可调用,但这仍然必须针对向量表示)。
  • 任何调用 .fit必须成功通过 check_array .

  • 一种解决方案是实现一种将对象转换为列表/向量的方法:
    import numpy as np
    data = np.array([[-0.538,-0.478,-0.374,-0.338,-0.346,0.230,0.246,0.366,0.362,0.342],[0.471,0.559,0.411,0.507,0.631,0.579,0.467,0.475,0.543,0.659]]).T
    
    class Point:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def to_list(self):
            return [self.x, self.y]
    
        def __repr__(self):
            return str(self.__class__.__name__) + "(" + str(self.x) + "," + str(self.y) + ")"
    
    points = [Point(*xy) for xy in data]
    # [Point(-0.538,0.471), Point(-0.478,0.559), ... , Point(0.342,0.659)]
    
    然后你可以对向量表示进行聚类:
    from sklearn.cluster import KMeans
    
    points_vector = np.array([point.to_list() for point in points])
    # [[-0.538  0.471]
    #  [-0.478  0.559]
    #  ...
    #  [ 0.342  0.659]]
    
    cluster = KMeans(n_clusters=2)
    cluster.fit(points_vector)
    

    为任意 Python 对象列表实现聚类算法可能是可能的(我发现了一个可能接近的 cluster 库)。如果有人尝试过,我会很感兴趣。

    关于python - 在 Python 中使用自定义距离函数对任意对象进行聚类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67489107/

    相关文章:

    python - python命名空间中的名称分配和重用

    python - 在标签不在训练集中的测试数据上使用 MultilabelBinarizer

    python - 如何在 numpy 数组中查找值簇

    r - 如何从 flexclust 生成集群的性能统计信息?

    python - 如何用不同的数字替换字符串中所有出现的地方

    python - 在 Vim 嵌入的 python 脚本中打开一个新窗口

    python - 神经网络识别手写数字: Dealing with multiple outputs

    python-2.7 - 在决策树期间导出 graphviz 给出错误

    algorithm - 在 RTS 中确定一组单位的方法

    条件中的 Python 正则表达式匹配