### 三角形与方形距离矩阵在Python层次聚类中的应用?[重复]

我一直在尝试使用层次聚类,在R中非常简单hclust(as.dist(X),method="average")。我在Python中也找到了一个相当简单的办法,但对于我的输入距离矩阵有些困惑。

我有一个相似性矩阵(DF_c93tom,还有一个较小的测试版本DF_sim),我将其转换为一个非相似性矩阵DF_dissm = 1 - DF_sim

我将此作为输入传递给scipy中的linkage函数,但文档中说它接受方形或三角形矩阵。我输入下三角上三角方形矩阵时得到了不同的聚类结果。这是为什么呢?文档中说它需要上三角矩阵,但下三角聚类看起来非常相似。

我的问题是,为什么所有这些聚类结果都不同?哪个是正确的?

这是linkage函数输入距离矩阵的文档

y : ndarray一个压缩或冗余的距离矩阵。压缩距离矩阵是一个包含距离矩阵上三角部分的平面数组。 

这是我的代码:

import matplotlib.pyplot as pltimport seaborn as snsimport numpy as npimport pandas as pdfrom scipy.cluster.hierarchy import dendrogram, linkage%matplotlib inline#测试数据DF_sim = DF_c93tom.iloc[:10,:10] #相似性矩阵DF_sim.columns = DF_sim.index = range(10) #print(DF_test)#           0  1         2         3  4  5  6  7  8  9# 0  1.000000  0  0.395833  0.083333  0  0  0  0  0  0# 1  0.000000  1  0.000000  0.000000  0  0  0  0  0  0# 2  0.395833  0  1.000000  0.883792  0  0  0  0  0  0# 3  0.083333  0  0.883792  1.000000  0  0  0  0  0  0# 4  0.000000  0  0.000000  0.000000  1  0  0  0  0  0# 5  0.000000  0  0.000000  0.000000  0  1  0  0  0  0# 6  0.000000  0  0.000000  0.000000  0  0  1  0  0  0# 7  0.000000  0  0.000000  0.000000  0  0  0  1  0  0# 8  0.000000  0  0.000000  0.000000  0  0  0  0  1  0# 9  0.000000  0  0.000000  0.000000  0  0  0  0  0  1#非相似性矩阵DF_dissm = 1 - DF_sim#冗余矩阵#np.tril(DF_dissm).T == np.triu(DF_dissm)#所有值为True#方形和三角矩阵的层次聚类fig_1 = plt.figure(1)plt.title("方形")Z_square = linkage((DF_dissm.values),method="average")dendrogram(Z_square)fig_2 = plt.figure(2)plt.title("上三角")Z_triu = linkage(np.triu(DF_dissm.values),method="average")dendrogram(Z_triu)fig_3 = plt.figure(3)plt.title("下三角")Z_tril = linkage(np.tril(DF_dissm.values),method="average")dendrogram(Z_tril)plt.show()

输入图片描述


回答:

当一个二维数组作为第一个参数传递给scipy.cluster.hierarchy.linkage时,它被视为一系列观测值,并且scipy.spatial.pdist被使用将其转换为一系列观测值之间的成对距离。

有一个github问题讨论这种行为,因为这意味着传递一个“距离矩阵”如DF_dissm.values(静默地)会产生一个错误的结果

所以这个问题的结论是这些

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")

都不会产生期望的结果。相反,应该使用

  • np.triu_indices

    h, w = arr.shapeZ = linkage(arr[np.triu_indices(h, 1)], method="average")
  • 或者spatial.distance.squareform

    from scipy.spatial import distance as ssdZ = linkage(ssd.squareform(arr), method="average")
  • 或者对原始点应用spatial.distance.pdist

    Z = hierarchy.linkage(ssd.pdist(points), method="average")
  • 或者传递二维数组points

    Z = hierarchy.linkage(points, method="average")

import matplotlib.pyplot as pltimport numpy as npfrom scipy.cluster import hierarchy as hierfrom scipy.spatial import distance as ssdnp.random.seed(2016)points = np.random.random((10, 2))arr = ssd.cdist(points, points)fig, ax = plt.subplots(nrows=4)ax[0].set_title("压缩上三角")Z = hier.linkage(arr[np.triu_indices(arr.shape[0], 1)], method="average")hier.dendrogram(Z, ax=ax[0])ax[1].set_title("方形")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("观测值序列")Z = hier.linkage(points, method="average")hier.dendrogram(Z, ax=ax[3])plt.show()

输入图片描述

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注