如何得到scipy.cluster.hierarchy生成的树状图的子树

tkclm6bt  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(136)

我对这个模块(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))

因此,fcluster()的输出给出了节点的聚类(通过它们的id),并且leaders()描述的here应该返回2个数组:

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

因此,如果此leaders()分别返回L和M:L[2]=182M[2]=1,那么簇1由节点id 182引导,它不存在于观察集X中,文档说“......那么它对应于非单例簇”。但我无法得到它......
此外,我通过sch.to_tree(Z)将Z转换为树,这将返回一个易于使用的树对象,我希望将其可视化,但我应该使用哪个工具作为图形平台来操作这些类型的树对象作为输入?

zf9nrax1

zf9nrax11#

回答你关于树操作的问题...
正如another answer中所解释的,你可以从树对象中读取分支的阅读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()

其中,在您的代码中,plot_tree(P)给出:

该函数允许您仅选择一些分支:

plot_tree(P, range(10))

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

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

推荐参考:

相关问题