如何为聚类指定距离函数?

Mar*_*son 18 python hierarchical-clustering scipy scikit-learn

我想将给定自定距离的点聚类,奇怪的是,似乎scipy和sklearn聚类方法都不允许指定距离函数.

例如,sklearn.cluster.AgglomerativeClustering我唯一能做的就是输入一个亲和力矩阵(这将是一个非常大的内存).为了构建这个矩阵,建议使用sklearn.neighbors.kneighbors_graph,但我不明白如何在两点之间指定距离函数.有人可以开导我吗?

ali*_*i_m 18

所有scipy层次聚类例程都将接受自定义距离函数,该函数接受指定一对点并返回标量的两个1D向量.例如,使用fclusterdata:

import numpy as np
from scipy.cluster.hierarchy import fclusterdata

# a custom function that just computes Euclidean distance
def mydist(p1, p2):
    diff = p1 - p2
    return np.vdot(diff, diff) ** 0.5

X = np.random.randn(100, 2)

fclust1 = fclusterdata(X, 1.0, metric=mydist)
fclust2 = fclusterdata(X, 1.0, metric='euclidean')

print(np.allclose(fclust1, fclust2))
# True
Run Code Online (Sandbox Code Playgroud)

metric=kwarg的有效输入与for相同scipy.spatial.distance.pdist.


小智 5

sklearn 有 DBSCAN,它允许预先计算距离矩阵(使用三角矩阵,其中 M_ij 是 i 和 j 之间的距离)。但这可能不是您正在寻找的集群类型。

此外,正如其他人提到的,scipy.cluster.hierarchy.fclusterdata 还允许预先计算距离度量。此回复中给出了一段代码,它提供了一些代码,可将 NxN 距离矩阵转换为 fclusterdata 可以轻松读取的格式:

import scipy.spatial.distance as ssd
# convert the redundant n*n square matrix form into a condensed nC2 array
    distArray = ssd.squareform(distMatrix) # distArray[{n choose 2}-{n-i choose 2} + (j-i-1)] is the distance between points i and j
Run Code Online (Sandbox Code Playgroud)