【问题标题】:Extracting clusters from seaborn clustermap从 seaborn clustermap 中提取集群
【发布时间】:2015-03-11 13:35:54
【问题描述】:

我正在使用seaborn clustermap 创建集群,并且在视觉上效果很好(这个example 产生非常相似的结果)。

但是,我无法弄清楚如何以编程方式提取集群。例如,在示例链接中,我怎样才能发现 1-1 rh、1-1 lh、5-1 rh、5-1 lh 是一个好的集群?视觉上很容易。我正在尝试使用查看数据和树状图的方法,但收效甚微

编辑示例代码:

import pandas as pd
import seaborn as sns
sns.set(font="monospace")

df = sns.load_dataset("brain_networks", header=[0, 1, 2], index_col=0)
used_networks = [1, 5, 6, 7, 8, 11, 12, 13, 16, 17]
used_columns = (df.columns.get_level_values("network")
                          .astype(int)
                          .isin(used_networks))
df = df.loc[:, used_columns]

network_pal = sns.cubehelix_palette(len(used_networks),
                                    light=.9, dark=.1, reverse=True,
                                    start=1, rot=-2)
network_lut = dict(zip(map(str, used_networks), network_pal))

networks = df.columns.get_level_values("network")
network_colors = pd.Series(networks).map(network_lut)

cmap = sns.diverging_palette(h_neg=210, h_pos=350, s=90, l=30, as_cmap=True)

result = sns.clustermap(df.corr(), row_colors=network_colors, method="average",
               col_colors=network_colors, figsize=(13, 13), cmap=cmap)

如何从result 中提取哪些模型在哪些集群中?

EDIT2 result 确实带有 linkagedendrogram_col,我认为它可以与 fcluster 一起使用。但是选择的阈值让我感到困惑。我会假设热图中高于阈值的值会聚集在一起?

【问题讨论】:

    标签: python cluster-analysis hierarchical-clustering seaborn dendrogram


    【解决方案1】:

    虽然目前可以使用result.linkage.dendrogram_colresult.linkage.dendrogram_row,但它似乎是一个实现细节。最安全的方法是首先显式计算链接并将它们传递给 clustermap 函数,该函数具有 row_linkagecol_linkage 参数。

    将示例中的最后一行 (result = ...) 替换为以下代码会得到与以前相同的结果,但您还将拥有可与 fcluster 一起使用的 row_linkagecol_linkage 变量等等

    from scipy.spatial import distance
    from scipy.cluster import hierarchy
    
    correlations = df.corr()
    correlations_array = np.asarray(df.corr())
    
    row_linkage = hierarchy.linkage(
        distance.pdist(correlations_array), method='average')
    
    col_linkage = hierarchy.linkage(
        distance.pdist(correlations_array.T), method='average')
    
    sns.clustermap(correlations, row_linkage=row_linkage, col_linkage=col_linkage, row_colors=network_colors, method="average",
                   col_colors=network_colors, figsize=(13, 13), cmap=cmap)
    

    在这个特定示例中,代码可以进一步简化,因为相关数组是对称的,因此 row_linkagecol_linkage 将是相同的。

    注意:根据 seaborn 中的代码所做的,之前的答案包括对 distance.squareshape 的调用,但 is a bug

    【讨论】:

    • 嘿@Marcel M,您不想使用“相异矩阵”而不是相关矩阵吗?比如1 - np.abs(correlations) 什么的?
    • @O.rka 将相关性传递给sns.clustermap() 来自问题中引用的 seaborn 示例,我刚刚复制了该示例。两个版本都计算相关性之间的距离,因此最终实际上使用了距离,但我承认我不知道这样做有多大意义(我不知道为什么 seaborn 示例会这样做)。在我自己的项目中,我直接使用距离。
    【解决方案2】:

    您可能希望在数据框中添加一个具有集群成员资格的新列。我已经设法通过从网络上窃取的组装好的 sn-ps 代码做到了这一点:

    import seaborn
    import scipy
    
    g = seaborn.clustermap(df,method='average')
    den = scipy.cluster.hierarchy.dendrogram(g.dendrogram_col.linkage,
                                             labels = df.index,
                                             color_threshold=0.60)  
    from collections import defaultdict
    
    def get_cluster_classes(den, label='ivl'):
        cluster_idxs = defaultdict(list)
        for c, pi in zip(den['color_list'], den['icoord']):
            for leg in pi[1:3]:
                i = (leg - 5.0) / 10.0
                if abs(i - int(i)) < 1e-5:
                    cluster_idxs[c].append(int(i))
    
        cluster_classes = {}
        for c, l in cluster_idxs.items():
            i_l = [den[label][i] for i in l]
            cluster_classes[c] = i_l
    
        return cluster_classes
    
    clusters = get_cluster_classes(den)
    
    cluster = []
    for i in df.index:
        included=False
        for j in clusters.keys():
            if i in clusters[j]:
                cluster.append(j)
                included=True
        if not included:
            cluster.append(None)
    
    df["cluster"] = cluster
    

    因此,这会为您提供一个带有“g”或“r”的列,用于表示绿色或红色标记的集群。我通过绘制树状图并观察 y 轴值来确定我的 color_threshold。

    【讨论】:

    • 这不适用于组数多于颜色的更大数据,因为(例如)绿色会重复自身,这将对颜色进行分组。
    • 有关此代码如何工作的更多详细信息,可以在此处查看“原始”帖子:http://www.nxn.se/valent/extract-cluster-elements-by-color-in-python
    • @Dataman 最好是原作者得到认可,在我发布我的 sn-p 时我肯定已经丢失了原始来源,并且不记得我是否对发布前的原件。
    猜你喜欢
    • 2019-03-25
    • 2019-10-09
    • 1970-01-01
    • 2016-04-06
    • 2019-10-24
    • 2015-12-28
    • 2020-10-17
    • 1970-01-01
    • 2023-01-10
    相关资源
    最近更新 更多