我一直在尝试使用Hierarchical Clustering
,而R
就这么简单hclust(as.dist(X),method="average")
。我在Python
中找到了一个非常简单的方法,除了我对输入距离矩阵的进展感到有些困惑。
我有一个相似度矩阵(DF_c93tom
w /较小的测试版本DF_sim
),我将其转换为相异矩阵DF_dissm = 1 - DF_sim
。
我将此作为来自linkage
的{{1}}的输入,但文档说明它采用方形或三角形矩阵。我输入了一个不同的群集来输入scipy
,lower triangle
和upper triangle
。为什么是这样?它需要文档中的上三角形,但下三角形簇看起来非常相似。
我的问题是,为什么所有群集都不同?哪一个是正确的?
这是square matrix
linkage
这是我的代码:
y : ndarray
A condensed or redundant distance matrix. A condensed distance matrix is a flat array containing the upper triangular of the distance matrix.
答案 0 :(得分:5)
当一个2D数组作为第一个参数传递给scipy.cluster.hierarchy.linkage时,
它被视为一系列观察,并scipy.spatial.pdist
is used将其转换为观察之间成对距离的序列。
有关此行为的github issue,因为这意味着传递“距离矩阵”(例如DF_dissm.values
(静默)会产生错误结果。
所以the upshot of this就是没有这些
Z_square = linkage((DF_dissm.values),method="average")
Z_triu = linkage(np.triu(DF_dissm.values),method="average")
Z_tril = linkage(np.tril(DF_dissm.values),method="average")
产生所需的结果。 改为使用
h, w = arr.shape
Z = linkage(arr[np.triu_indices(h, 1)], method="average")
from scipy.spatial import distance as ssd
Z = linkage(ssd.squareform(arr), method="average")
或将spatial.distance.pdist
应用于原始点:
Z = hierarchy.linkage(ssd.pdist(points), method="average")
或传递2D数组points
:
Z = hierarchy.linkage(points, method="average")
import matplotlib.pyplot as plt
import numpy as np
from scipy.cluster import hierarchy as hier
from scipy.spatial import distance as ssd
np.random.seed(2016)
points = np.random.random((10, 2))
arr = ssd.cdist(points, points)
fig, ax = plt.subplots(nrows=4)
ax[0].set_title("condensed upper triangular")
Z = hier.linkage(arr[np.triu_indices(arr.shape[0], 1)], method="average")
hier.dendrogram(Z, ax=ax[0])
ax[1].set_title("squareform")
Z = hier.linkage(ssd.squareform(arr), method="average")
hier.dendrogram(Z, ax=ax[1])
ax[2].set_title("pdist")
Z = hier.linkage(ssd.pdist(points), method="average")
hier.dendrogram(Z, ax=ax[2])
ax[3].set_title("sequence of observations")
Z = hier.linkage(points, method="average")
hier.dendrogram(Z, ax=ax[3])
plt.show()