python - 解释 SciPy 的层次聚类树状图的输出? (也许发现了一个错误...)

标签 python machine-learning scipy hierarchical-clustering dendrogram

我想弄清楚 scipy.cluster.hierarchy.dendrogram 的输出是如何工作的...我以为我知道它是如何工作的并且我能够使用输出来重建树状图但似乎我不再理解它,或者此模块的 Python 3 版本中存在错误。

这个答案,how do I get the subtrees of dendrogram made by scipy.cluster.hierarchy , 意味着 dendrogram 输出字典给出 dict_keys(['icoord', 'ivl', 'color_list', 'leaves', 'dcoord']) w/all of相同的大小,因此您可以zip 它们和plt.plot 它们来重建树状图。

看起来很简单,当我使用 Python 2.7.11 时我确实让它恢复了工作,但是一旦我升级到 Python 3.5.1 我的旧脚本就没有了我同样的结果。

我开始为一个非常简单的可重复示例重新设计我的集群,并且认为我可能在 Python 3.5.1 版本的 SciPy version 0.17.1-np110py35_1 中发现了一个错误。打算使用 Scikit-learn 数据集 b/c 大多数人都从 conda 发行版中获得该模块。

为什么这些没有排成一行,为什么我无法以这种方式重建树状图?

# Init
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()

# Load data
from sklearn.datasets import load_diabetes

# Clustering
from scipy.cluster.hierarchy import dendrogram, fcluster, leaves_list
from scipy.spatial import distance
from fastcluster import linkage # You can use SciPy one too

%matplotlib inline

# Dataset
A_data = load_diabetes().data
DF_diabetes = pd.DataFrame(A_data, columns = ["attr_%d" % j for j in range(A_data.shape[1])])

# Absolute value of correlation matrix, then subtract from 1 for disimilarity
DF_dism = 1 - np.abs(DF_diabetes.corr())

# Compute average linkage
A_dist = distance.squareform(DF_dism.as_matrix())
Z = linkage(A_dist,method="average")

# I modded the SO code from the above answer for the plot function
def plot_tree( D_dendro, ax ):
    # Set up plotting data
    leaves = D_dendro["ivl"]
    icoord = np.array( D_dendro['icoord'] )
    dcoord = np.array( D_dendro['dcoord'] )
    color_list = D_dendro["color_list"]

    # Plot colors
    for leaf, xs, ys, color in zip(leaves, icoord, dcoord, color_list):
        print(leaf, xs, ys, color, sep="\t")
        plt.plot(xs, ys,  color)

    # Set min/max of plots
    xmin, xmax = icoord.min(), icoord.max()
    ymin, ymax = dcoord.min(), dcoord.max()

    plt.xlim( xmin-10, xmax + 0.1*abs(xmax) )
    plt.ylim( ymin, ymax + 0.1*abs(ymax) )

    # Set up ticks
    ax.set_xticks( np.arange(5, len(leaves) * 10 + 5, 10))
    ax.set_xticklabels(leaves, fontsize=10, rotation=45)

    plt.show()

fig, ax = plt.subplots()
D1 = dendrogram(Z=Z, labels=DF_dism.index, color_threshold=None, no_plot=True)
plot_tree(D_dendro=D1, ax=ax)

enter image description here

attr_1  [ 15.  15.  25.  25.]   [ 0.          0.10333704  0.10333704  0.        ]   g
attr_4  [ 55.  55.  65.  65.]   [ 0.          0.26150727  0.26150727  0.        ]   r
attr_5  [ 45.  45.  60.  60.]   [ 0.          0.4917828   0.4917828   0.26150727]   r
attr_2  [ 35.   35.   52.5  52.5]   [ 0.          0.59107459  0.59107459  0.4917828 ]   b
attr_8  [ 20.    20.    43.75  43.75]   [ 0.10333704  0.65064998  0.65064998  0.59107459]   b
attr_6  [ 85.  85.  95.  95.]   [ 0.          0.60957062  0.60957062  0.        ]   b
attr_7  [ 75.  75.  90.  90.]   [ 0.          0.68142114  0.68142114  0.60957062]   b
attr_0  [ 31.875  31.875  82.5    82.5  ]   [ 0.65064998  0.72066112  0.72066112  0.68142114]   b
attr_3  [  5.       5.      57.1875  57.1875]   [ 0.          0.80554653  0.80554653  0.72066112]   b

这里没有标签,只有 x 轴的 icoordenter image description here

所以请检查颜色是否映射正确。它说 [ 15. 15. 25. 25.] 对于 icoordattr_1 一起使用,但基于它看起来像与一起的值属性_4。此外,它不会一直走到最后一片叶子 (attr_9),那是 icoorddcoord 的 b/c 长度比 ivl 标签的数量少 1。

print([len(x) for x in [leaves, icoord, dcoord, color_list]]) 
#[10, 9, 9, 9]

最佳答案

icoorddcoordcolor_list 描述了链接,而不是叶子。 icoorddcoord 给出图中每个链接的“拱形”坐标(即倒置的 U 或 J 形),以及 color_list 是那些拱门的颜色。在完整图中,icoord 等的长度将比 ivl 的长度少一个,如您所见。

不要尝试将 ivl 列表与 icoorddcoordcolor_list 列表对齐。它们与不同的事物相关联。

关于python - 解释 SciPy 的层次聚类树状图的输出? (也许发现了一个错误...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38166327/

相关文章:

python - Pandas :asfreq 与时间序列的奇怪行为

python - 我如何检查 Python for 循环的任何(至少一次)迭代中的某件事是否为真?

python - 为什么我的路线不起作用?

machine-learning - 如何计算卷积神经网络的参数总数?

machine-learning - 训练SVM的参数有哪些

scipy - 线搜索的正方向导数

python - 无法在 Spark 中导入名称 LDA MLlib

python - 为什么我的简单前馈神经网络发散(pytorch)?

python - Python中将json转换为coo稀疏矩阵

python - 如何在 Python 中使用 PCA/SVD 进行特征选择和识别?