在scipy.cluster.hierarchy.linkage()中使用距离矩阵?

46

我有一个n*n的距离矩阵M,其中M_ij表示object_iobject_j之间的距离。因此,它的形式如下:

   /  0     M_01    M_02    ...    M_0n\
   | M_10    0      M_12    ...    M_1n |
   | M_20   M_21     0      ...    M2_n |
   |                ...                 |
   \ M_n0   M_n2    M_n2    ...      0 / 

现在我希望用层次聚类对这n个对象进行聚类。 Python有一个叫做scipy.cluster.hierarchy.linkage(y, method='single', metric='euclidean')的实现。 它的文档说:
y必须是一个{n \choose 2}大小的向量,其中n是距离矩阵中原始观测值成对出现的数量。 y:ndarray 压缩或冗余的距离矩阵。压缩的距离矩阵是包含距离矩阵上三角的扁平数组。这是pdist返回的格式。 或者,m个n维观测向量的集合可以作为m乘以n的数组传递。
这个关于y的描述让我感到困惑。我能直接把我的M作为输入的y吗?

更新

@hongbo-zhu-cn已在GitHub上提出了此问题。这正是我所担心的。然而,作为一个GitHub的新手,我不知道它是如何运作的,因此不知道如何处理这个问题。


你可以检出自己的Scipy源代码,并更新scipy/cluster/hierarchy.py中的linkage()函数,然后编译自己的Scipy版本;或者避免将冗余的距离矩阵作为输入提供给linkage()函数(使用squareform()将其转换为压缩形式)。 - HongboZhu
@HongboZhu 噢,是的,我差点忘了我可以这样做! - Sibbs Gambling
2个回答

49

看起来我们确实不能直接传递冗余的方阵,尽管文档声称我们可以这样做。

为了使未来面临相同问题的任何人受益,我在此额外添加我的解决方案作为答案。因此,复制粘贴的人可以继续进行聚类。

使用以下代码片段压缩矩阵并愉快地进行下一步操作。

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
请纠正我如果我错了。

4
我认为现阶段这是可行的方法。你可以比较使用压缩距离矩阵作为输入所得到的结果和使用观察数据作为输入所得到的结果。 - HongboZhu

12

现在您需要传入“压缩的距离矩阵”,即向量形式的距离矩阵的上三角:

y = M[np.triu_indices(n,1)]

@hongbo-zhu-cn的拉取请求讨论来看,解决方案似乎是向linkage函数添加一个额外的关键字参数,允许用户明确指定他们传递的是一个n x n距离矩阵而不是一个m x n观测矩阵。


3
有一个Scipy函数scipy.spatial.distance.squareform()可以进行转换:http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.squareform.html - HongboZhu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接