12

Tôi đang sử dụng seaborn clustermap để tạo cụm và trực quan hoạt động tốt (điều này example tạo ra kết quả rất giống nhau).Trích xuất cụm từ cụm từ seaborn

Tuy nhiên, tôi đang gặp sự cố khi tìm hiểu cách trích xuất các cụm theo cách lập trình. Ví dụ, trong ví dụ liên kết, làm thế nào tôi có thể tìm ra rằng 1-1 rh, 1-1 lh, 5-1 rh, 5-1 lh làm cho một cụm tốt? Trực quan thật dễ dàng. Tôi cố gắng để sử dụng phương pháp tìm kiếm thông qua các dữ liệu, và dendrograms nhưng tôi đang gặp chút thành công

EDIT Mã từ ví dụ:

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) 

Làm thế nào tôi có thể kéo những gì mô hình trong đó cụm ra của result?

EDIT2 Các result không mang theo với nó một linkage với các dendrogram_col mà tôi nghĩ sẽ làm việc với fcluster. Nhưng giá trị ngưỡng để chọn điều đó gây nhầm lẫn cho tôi. Tôi cho rằng các giá trị trong bản đồ nhiệt cao hơn ngưỡng sẽ được nhóm lại với nhau?

Trả lời

10

Trong khi sử dụng result.linkage.dendrogram_col hoặc result.linkage.dendrogram_row hiện sẽ hoạt động, có vẻ như đó là chi tiết triển khai. Tuyến đường an toàn nhất là đầu tiên tính toán các liên kết một cách rõ ràng và chuyển chúng đến hàm clustermap, có các thông số row_linkagecol_linkage chỉ cho điều đó.

Thay thế dòng cuối cùng trong ví dụ của bạn (result = ...) với mã dưới đây cho kết quả tương tự như trước, nhưng bạn cũng sẽ có row_linkagecol_linkage biến mà bạn có thể sử dụng với fcluster, vv

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) 

Trong ví dụ cụ thể này, mã có thể được đơn giản hóa hơn vì mảng tương quan là đối xứng và do đó row_linkagecol_linkage sẽ giống nhau.

Lưu ý: Câu trả lời trước bao gồm gọi tới distance.squareshape theo mã của seaborn, nhưng is a bug.

+0

Hey @Marcel M, bạn sẽ không muốn sử dụng "ma trận không giống nhau" thay vì ma trận tương quan? Giống như '1 - np.abs (tương quan)' hay gì đó? –

+1

@ O.rka Việc truyền các tương quan tới 'sns.clustermap()' xuất phát từ ví dụ bẩm sinh được trích dẫn trong câu hỏi mà tôi vừa sao chép. Cả hai phiên bản tính toán khoảng cách giữa các tương quan, vì vậy trong khoảng cách cuối cùng được sử dụng, nhưng tôi thừa nhận tôi không biết nó có ý nghĩa như thế nào (tôi không biết tại sao ví dụ seaborn làm như vậy). Trong dự án của riêng tôi, tôi sử dụng khoảng cách trực tiếp. –

3

Có thể bạn muốn một cột mới trong khung dữ liệu của mình với thành viên cụm. Tôi đã quản lý để thực hiện điều này từ các đoạn mã được lấy cắp từ tất cả các trang web trên mạng:

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 

Vì vậy, cột này cung cấp cho bạn cột 'g' hoặc 'r' cho cụm màu xanh lá cây hoặc màu đỏ. Tôi xác định color_threshold của tôi bằng cách vẽ biểu đồ dendrogram và đánh dấu các giá trị trục y.

+0

Điều này sẽ không hoạt động trên dữ liệu lớn hơn, nơi có nhiều nhóm hơn màu sắc vì (ví dụ) màu xanh lá cây sẽ lặp lại chính nó sẽ nhóm màu. – PvdL

Các vấn đề liên quan