sch example cluster python cluster-analysis hierarchical-clustering seaborn dendrogram

python - example - Extracción de grupos de mapas de conglomerados marinos



scipy cluster hierarchy example python (2)

Probablemente desee una nueva columna en su marco de datos con la membresía del clúster. He logrado hacer esto desde fragmentos de código ensamblados de toda la web:

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

Así que esto le da una columna con ''g'' o ''r'' para los grupos marcados en verde o rojo. Determino mi umbral de color trazando el dendrograma y observando los valores del eje y.

Estoy utilizando el seaborn clustermap para crear clústeres y visualmente funciona muy bien (este example produce resultados muy similares).

Sin embargo, estoy teniendo problemas para averiguar cómo extraer los clústeres mediante programación. Por ejemplo, en el enlace de ejemplo, ¿cómo podría descubrir que 1-1 rh, 1-1 lh, 5-1 rh, 5-1 lh es un buen grupo? Visualmente es fácil. Estoy tratando de usar métodos para examinar los datos y los dendrogramas, pero estoy teniendo poco éxito.

EDITAR código del ejemplo:

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)

¿Cómo puedo extraer qué modelos hay en qué grupos de result ?

EDIT2 El result conlleva un linkage con el dendrogram_col que creo que funcionaría con fcluster . Pero el valor de umbral para seleccionar que me confunde. ¿Supondría que los valores en el mapa de calor que son más altos que el umbral se agruparían juntos?


Si bien actualmente funciona result.linkage.dendrogram_col o result.linkage.dendrogram_row , parece ser un detalle de implementación. La ruta más segura es primero calcular los enlaces explícitamente y pasarlos a la función clustermap , que tiene parámetros de row_linkage y col_linkage solo para eso.

Reemplazar la última línea en su ejemplo ( result = ...) con el siguiente código da el mismo resultado que antes, pero también tendrá variables row_linkage y col_linkage que puede usar con fcluster etc.

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)

En este ejemplo particular, el código podría simplificarse más, ya que la matriz de correlaciones es simétrica y, por row_linkage tanto, row_linkage y col_linkage serán idénticos.

Nota: una respuesta anterior incluía una llamada a distance.squareshape según lo que hace el código en seaborn, pero eso es un error .