在 scipy.cluster.hierarchy.linkage() 中使用距离矩阵?
Posted
技术标签:
【中文标题】在 scipy.cluster.hierarchy.linkage() 中使用距离矩阵?【英文标题】:Use Distance Matrix in scipy.cluster.hierarchy.linkage()? 【发布时间】:2013-09-27 22:56:42 【问题描述】:我有一个距离矩阵 n*n M
,其中 M_ij
是 object_i
和 object_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')
的实现。
Its documentation 说:
y 必须是 n \choose 2 大小的向量,其中 n 是 原始观测值在距离矩阵中配对。
y : 数组
一个精简或冗余的距离矩阵。一个浓缩的 距离矩阵是一个平面数组,包含 距离矩阵。这是 pdist 返回的形式。或者,一个 在 n 维中的 m 个观察向量的集合可以传递为 一个 m × n 数组。
我对@987654329@ 的这种描述感到困惑。 我可以直接输入我的M
作为输入y
吗?
更新
@hongbo-zhu-cn has raised this issue up in GitHub.这正是我所关心的。但是,作为 GitHub 的新手,我不知道它是如何工作的,因此不知道这个问题是如何处理的。
【问题讨论】:
您可以检查您自己的 scipy 源代码副本并更新 scipy/cluster/hierarchy.py 中的 links() 函数并编译您自己的 Scipy 版本,或者简单地避免将冗余距离矩阵作为链接()的输入。 (使用 squareform() 将其转换为压缩形式)。 @HongboZhu 哦,是的,我差点忘记我可以做到这一点! 【参考方案1】:看起来我们确实不能直接传入冗余方阵,尽管文档声称我们可以这样做。
为了让以后遇到同样问题的人受益,我在这里写下我的解决方案作为附加答案。所以复制粘贴的人就可以继续进行聚类了。
使用下面的sn-p来压缩矩阵,愉快地继续。
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
如果我错了,请纠正我。
【讨论】:
我认为这是目前要走的路。您可以比较使用压缩距离矩阵作为输入获得的结果和使用观察作为输入获得的结果。【参考方案2】:现在您应该传入“压缩距离矩阵”,即仅以向量形式传递距离矩阵的上三角形:
y = M[np.triu_indices(n,1)]
从the discussion of @hongbo-zhu-cn's pull request 看来,解决方案似乎是向linkage
函数添加一个额外的关键字参数,这将允许用户明确指定他们正在通过 nxn 距离矩阵而不是 mxn 观察矩阵。
【讨论】:
有一个 scipy 函数 scipy.spatial.distance.squareform() 进行转换:docs.scipy.org/doc/scipy/reference/generated/…以上是关于在 scipy.cluster.hierarchy.linkage() 中使用距离矩阵?的主要内容,如果未能解决你的问题,请参考以下文章
我如何获得由 scipy.cluster.hierarchy 制作的树状图的子树
层次聚类python,scipy(dendrogram, linkage,fcluster函数)总算有博文说清楚层次聚类Z矩阵的意义了