显示scipy树状图的簇标签

Emm*_*tOT 6 python matplotlib dendrogram scipy

我正在使用层次聚类来聚类单词向量,我希望用户能够显示显示聚类的树形图.但是,由于可能有数千个单词,我希望将此树形图截断为一些合理的有价值,每个叶子的标签是该群集中最重要单词的字符串.

我的问题是,根据文档,"标签[i]值是只有当它对应于原始观察而不是非单一群集时才放在第i个叶子节点下的文本." 我认为这意味着我不能标记簇,只能标记奇点?

为了说明,这是一个简短的python脚本,它生成一个简单的标记树形图:

import numpy as np
from scipy.cluster.hierarchy import dendrogram, linkage
from matplotlib import pyplot as plt

randomMatrix = np.random.uniform(-10,10,size=(20,3))
linked = linkage(randomMatrix, 'ward')

labelList = ["foo" for i in range(0, 20)]

plt.figure(figsize=(15, 12))
dendrogram(
            linked,
            orientation='right',
            labels=labelList,
            distance_sort='descending',
            show_leaf_counts=False
          )
plt.show()
Run Code Online (Sandbox Code Playgroud)

随机生成点的树形图

现在假设我要截断到只有5个叶子,并且对于每个叶子,将它标记为"foo,foo,foo ...",即构成该群集的单词.(注意:生成这些标签不是问题.)我将其截断,并提供一个匹配的标签列表:

labelList = ["foo, foo, foo..." for i in range(0, 5)]
dendrogram(
            linked,
            orientation='right',
            p=5,
            truncate_mode='lastp',
            labels=labelList,
            distance_sort='descending',
            show_leaf_counts=False
          )
Run Code Online (Sandbox Code Playgroud)

这是问题,没有标签:

在此输入图像描述

我想这里可能有一个参数'leaf_label_func',但我不知道如何使用它.

cor*_*dek 7

您使用 Leaf_label_func 参数是正确的。

除了创建绘图之外,dendrogram 函数还返回一个包含多个列表的字典(他们在文档中将其称为 R)。您创建的 Leaf_label_func 必须接受来自 R["leaves"] 的值并返回所需的标签。设置标签的最简单方法是运行树状图两次。一次no_plot=True获取用于创建标签映射的字典。然后再次创建情节。

randomMatrix = np.random.uniform(-10,10,size=(20,3))
linked = linkage(randomMatrix, 'ward')

labels = ["A", "B", "C", "D"]
p = len(labels)

plt.figure(figsize=(8,4))
plt.title('Hierarchical Clustering Dendrogram (truncated)', fontsize=20)
plt.xlabel('Look at my fancy labels!', fontsize=16)
plt.ylabel('distance', fontsize=16)

# call dendrogram to get the returned dictionary 
# (plotting parameters can be ignored at this point)
R = dendrogram(
                linked,
                truncate_mode='lastp',  # show only the last p merged clusters
                p=p,  # show only the last p merged clusters
                no_plot=True,
                )

print("values passed to leaf_label_func\nleaves : ", R["leaves"])

# create a label dictionary
temp = {R["leaves"][ii]: labels[ii] for ii in range(len(R["leaves"]))}
def llf(xx):
    return "{} - custom label!".format(temp[xx])

## This version gives you your label AND the count
# temp = {R["leaves"][ii]:(labels[ii], R["ivl"][ii]) for ii in range(len(R["leaves"]))}
# def llf(xx):
#     return "{} - {}".format(*temp[xx])


dendrogram(
            linked,
            truncate_mode='lastp',  # show only the last p merged clusters
            p=p,  # show only the last p merged clusters
            leaf_label_func=llf,
            leaf_rotation=60.,
            leaf_font_size=12.,
            show_contracted=True,  # to get a distribution impression in truncated branches
            )
plt.show()
Run Code Online (Sandbox Code Playgroud)

  • +1 为其他镀锌明矾。但是,您知道一种获取构成截断叶子的观测值的方法吗?例如,我有 130k 个样本,我截断了 100 个集群,并想知道每个集群中存在哪些观察结果。 (2认同)
  • @Grr 我使用 scipy.cluster.hierarchy.fcluster 来检索集群。Jörn Hees 在 https://joernhees.de/blog/2015/08/26/scipy-hierarchical-clustering-and-dendrogram-tutorial/ 上有一个很好的教程 (2认同)