显示 scipy 树状图的聚类标签

新手上路,请多包涵

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

我的问题是, 根据文档“labels[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()

随机生成的点的树状图

现在假设我想截断到只有 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
          )

这就是问题所在,没有标签:

在此处输入图像描述

我想这里可能会用到参数“leaf_label_func”,但我不确定如何使用它。

原文由 EmmetOT 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 612
2 个回答

您对使用 leaf_label_func 参数是正确的。

除了创建绘图之外,树状图函数还返回一个包含多个列表的字典(他们在文档中将其称为 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()

原文由 coradek 发布,翻译遵循 CC BY-SA 3.0 许可协议

你可以简单地写:

 hierarchy.dendrogram(Z, labels=label_list)

这是一个很好的例子,使用 pandas Data Frame :

 import numpy as np
import pandas as pd
from scipy.cluster import hierarchy
import matplotlib.pyplot as plt

data = [[24, 16], [13, 4], [24, 11], [34, 18], [41,
6], [35, 13]]
frame = pd.DataFrame(np.array(data), columns=["Rape",
"Murder"], index=["Atlanta", "Boston", "Chicago",
"Dallas", "Denver", "Detroit"])

Z = hierarchy.linkage(frame, 'single')
plt.figure()
dn = hierarchy.dendrogram(Z, labels=frame.index)

原文由 Mohammad Forouhesh 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题