如何获取scipy.cluster.hierarchy制作的树形图子树

tit*_*tan 18 python numpy hierarchical-clustering scipy python-2.7

我对这个模块(scipy.cluster.hierarchy)感到困惑......还有一些!

例如,我们有以下树形图:

层次聚类

我的问题是如何以一种漂亮的格式提取彩色子树(每个子树代表一个簇),比如SIF格式?现在获得上述情节的代码是:

import scipy
import scipy.cluster.hierarchy as sch
import matplotlib.pylab as plt

scipy.randn(100,2)

d = sch.distance.pdist(X)

Z= sch.linkage(d,method='complete')

P =sch.dendrogram(Z)

plt.savefig('plot_dendrogram.png')

T = sch.fcluster(Z, 0.5*d.max(), 'distance')
#array([4, 5, 3, 2, 2, 3, 5, 2, 2, 5, 2, 2, 2, 3, 2, 3, 2, 5, 4, 5, 2, 5, 2,
#       3, 3, 3, 1, 3, 4, 2, 2, 4, 2, 4, 3, 3, 2, 5, 5, 5, 3, 2, 2, 2, 5, 4,
#       2, 4, 2, 2, 5, 5, 1, 2, 3, 2, 2, 5, 4, 2, 5, 4, 3, 5, 4, 4, 2, 2, 2,
#       4, 2, 5, 2, 2, 3, 3, 2, 4, 5, 3, 4, 4, 2, 1, 5, 4, 2, 2, 5, 5, 2, 2,
#       5, 5, 5, 4, 3, 3, 2, 4], dtype=int32)

sch.leaders(Z,T)
# (array([190, 191, 182, 193, 194], dtype=int32),
#  array([2, 3, 1, 4,5],dtype=int32))
Run Code Online (Sandbox Code Playgroud)

所以现在,输出fcluster()给出了节点的聚类(通过它们的id),并且这里leaders()描述的应该返回2个数组:

  • 第一个包含由Z生成的聚类的领导节点,在这里我们可以看到我们有5个聚类,以及在图中

  • 第二个是这些集群的id

所以如果这个leaders()返回resp.L和M:L[2]=182然后M[2]=1,群集1由节点id 182引导,它在观察集X中不存在,文档说"......然后它对应于非单一群集".但我无法得到它......

此外,我将Z转换为树sch.to_tree(Z),它将返回一个易于使用的树对象,我想要可视化,但我应该使用哪个工具作为操作这些树对象作为输入的图形平台?

Sau*_*tro 21

回答关于树操作的问题的一部分......

另一个答案所述,您可以读取树枝读取的坐标icoorddcoord树对象的坐标.对于每个分支,协调从左到右给出.

如果您想手动绘制树,可以使用以下内容:

def plot_tree(P, pos=None):
    plt.clf()
    icoord = scipy.array(P['icoord'])
    dcoord = scipy.array(P['dcoord'])
    color_list = scipy.array(P['color_list'])
    xmin, xmax = icoord.min(), icoord.max()
    ymin, ymax = dcoord.min(), dcoord.max()
    if pos:
        icoord = icoord[pos]
        dcoord = dcoord[pos]
        color_list = color_list[pos]
    for xs, ys, color in zip(icoord, dcoord, color_list):
        plt.plot(xs, ys, color)
    plt.xlim(xmin-10, xmax + 0.1*abs(xmax))
    plt.ylim(ymin, ymax + 0.1*abs(ymax))
    plt.show()
Run Code Online (Sandbox Code Playgroud)

您的代码中的位置plot_tree(P)给出:

在此输入图像描述

该功能允许您只选择一些分支:

plot_tree(P, range(10))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

现在你必须知道要绘制哪些分支.也许fcluster()输出有点模糊,另一种方法是根据最小和最大距离公差找到要绘制的分支,linkage()直接使用输出(Z在OP的情况下):

dmin = 0.2
dmax = 0.3
pos = scipy.all( (Z[:,2] >= dmin, Z[:,2] <= dmax), axis=0 ).nonzero()
plot_tree( P, pos )
Run Code Online (Sandbox Code Playgroud)

推荐参考:

  • 这个答案帮助我到达了可以在给定的距离(PD)内找到的观察结果绘制树状图的子树的地方.我没有发现fcluster或fclusterdata方法对此有用.我使用sch.to_tree(linkage).pre_order(),然后通过引用pdist距离矩阵顺序测试该列表中的相邻项目是否在PD内(参见http://stackoverflow.com/a/17870926/1876324),然后重新计算我想要绘制的每个组的距离,连锁和树状图.例如,4的PD将OP数据分组为期望的3个子树. (2认同)