scipy.cluster.hierarchy 教程 [关闭]

Posted

技术标签:

【中文标题】scipy.cluster.hierarchy 教程 [关闭]【英文标题】:Tutorial for scipy.cluster.hierarchy [closed] 【发布时间】:2014-03-05 11:27:51 【问题描述】:

我试图了解如何操作层次结构集群,但文档太……技术性?……我不明白它是如何工作的。

有什么教程可以帮助我开始,逐步解释一些简单的任务吗?

假设我有以下数据集:

a = np.array([[0,   0  ],
              [1,   0  ],
              [0,   1  ],
              [1,   1  ], 
              [0.5, 0  ],
              [0,   0.5],
              [0.5, 0.5],
              [2,   2  ],
              [2,   3  ],
              [3,   2  ],
              [3,   3  ]])

我可以轻松地进行层次聚类并绘制树状图:

z = linkage(a)
d = dendrogram(z)
现在,如何恢复特定集群?假设在树状图中包含元素 [0,1,2,4,5,6] 的那个? 如何取回这些元素的值?

【问题讨论】:

【参考方案1】:

层次凝聚聚类 (HAC) 分为三个步骤:

    量化数据(metric 参数) 集群数据(method 参数) 选择集群数量

在做

z = linkage(a)

将完成前两个步骤。由于您没有指定任何参数,因此它使用标准值

    metric = 'euclidean' method = 'single'

所以z = linkage(a) 将为您提供a 的单个链接层次凝聚聚类。这种聚类是一种解决方案的层次结构。从这个层次结构中,您可以获得有关数据结构的一些信息。你现在可以做的是:

检查哪个metric 是合适的,例如。 G。 cityblockchebychev 将以不同方式量化您的数据(cityblockeuclideanchebychev 对应于 L1L2L_inf norm) 检查methdos 的不同属性/行为(例如singlecompleteaverage) 检查如何确定集群的数量,例如。 G。由reading the wiki about it 计算找到的解决方案(聚类)的索引,例如silhouette coefficient(使用此系数,您可以获得关于点/观察与聚类分配给它的聚类的匹配程度的质量反馈)。不同的索引使用不同的标准来限定聚类。

这里是开始

import numpy as np
import scipy.cluster.hierarchy as hac
import matplotlib.pyplot as plt


a = np.array([[0.1,   2.5],
              [1.5,   .4 ],
              [0.3,   1  ],
              [1  ,   .8 ],
              [0.5,   0  ],
              [0  ,   0.5],
              [0.5,   0.5],
              [2.7,   2  ],
              [2.2,   3.1],
              [3  ,   2  ],
              [3.2,   1.3]])

fig, axes23 = plt.subplots(2, 3)

for method, axes in zip(['single', 'complete'], axes23):
    z = hac.linkage(a, method=method)

    # Plotting
    axes[0].plot(range(1, len(z)+1), z[::-1, 2])
    knee = np.diff(z[::-1, 2], 2)
    axes[0].plot(range(2, len(z)), knee)

    num_clust1 = knee.argmax() + 2
    knee[knee.argmax()] = 0
    num_clust2 = knee.argmax() + 2

    axes[0].text(num_clust1, z[::-1, 2][num_clust1-1], 'possible\n<- knee point')

    part1 = hac.fcluster(z, num_clust1, 'maxclust')
    part2 = hac.fcluster(z, num_clust2, 'maxclust')

    clr = ['#2200CC' ,'#D9007E' ,'#FF6600' ,'#FFCC00' ,'#ACE600' ,'#0099CC' ,
    '#8900CC' ,'#FF0000' ,'#FF9900' ,'#FFFF00' ,'#00CC01' ,'#0055CC']

    for part, ax in zip([part1, part2], axes[1:]):
        for cluster in set(part):
            ax.scatter(a[part == cluster, 0], a[part == cluster, 1], 
                       color=clr[cluster])

    m = '\n(method: )'.format(method)
    plt.setp(axes[0], title='Screeplot'.format(m), xlabel='partition',
             ylabel='\ncluster distance'.format(m))
    plt.setp(axes[1], title=' Clusters'.format(num_clust1))
    plt.setp(axes[2], title=' Clusters'.format(num_clust2))

plt.tight_layout()
plt.show()

给予

【讨论】:

您能解释一下如何使用 np.diff 来查找拐点吗?二度为什么用它,这点的数学解释是什么? @user1603472 横坐标上的每个数字都是一种可能的解决方案,它由相应数量的分区组成。现在显然,您允许的分区越多,集群内的同质性就越高。所以你真正想要的是:具有高同质性的分区数量少(在大多数情况下)。这就是您寻找“膝盖”点的原因,即。 e. before 点距离值“跳跃”到相对于之前增加的更高的值。 @user1603472 在处理离散值的导数时,我没有注意到一级和二级之间的差异。不知何故,它刚刚成功。实际上我发现可以使用曲率公式来找出“最强”的膝点,但我的意思是:通常你无论如何都必须通过查看来评估情节。它可能只是作为一个额外的方向。这是根据我要说的维基中的elbow method。 感谢伟大的起点!像knee = np.diff(z[::-1, 2], 2) 维数之类的行中的幻数“2”从何而来?您绘制的蓝线到底是什么 - 在集群方差或某物之间/在集群方差之内,或其他什么?提前致谢 @nrob z[::-1, 2] 是链接矩阵的第三列。这些值取决于metric method。该度量决定了如何量化对象之间的距离(数据矩阵a 中的行),并且该方法决定了在融合集群时如何重新计算或“添加”这些距离。而这些值(链接的第三列)实际上也是蓝线。 np.diff(.., 2) 是二阶导数(绿色曲线),指出蓝色曲线中的一个拐点。有很多方法可以猜测什么是“好”的分区数......

以上是关于scipy.cluster.hierarchy 教程 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

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

使用scipy进行层次聚类和k-means聚类

在 Scipy/Matplotlib 中注释树状图节点

层次聚类python,scipy(dendrogram, linkage,fcluster函数)总算有博文说清楚层次聚类Z矩阵的意义了

如何使用树状图处理大量数据

如何以最少的内存使用对大量数据进行聚类