2016-08-01 13 views
10

Zwykle, gdy wykonuję dendrogramy i mapy termiczne, używam matrycy dystansowej i robię kilka rzeczy z SciPy. Chcę wypróbować Seaborn, ale Seaborn chce moje dane w formie prostokątnej (wiersze = próbki, cols = atrybuty, a nie macierzy odległości)?Jak nadać sns.clustermap macierz odległości?

Zasadniczo chcę użyć seaborn jako backendu, aby obliczyć mój dendrogram i przywiązać go do mojej mapy cieplnej. czy to możliwe? Jeśli nie, czy może to być funkcja w przyszłości.

Może są parametry, które mogę dostosować, aby mogły przyjąć matrycę odległości zamiast macierzy prostokątnej?

Oto Wykorzystanie:

seaborn.clustermap¶ 
seaborn.clustermap(data, pivot_kws=None, method='average', metric='euclidean', 
z_score=None, standard_scale=None, figsize=None, cbar_kws=None, row_cluster=True, 
col_cluster=True, row_linkage=None, col_linkage=None, row_colors=None, 
col_colors=None, mask=None, **kwargs) 

Mój kod poniżej:

from sklearn.datasets import load_iris 
iris = load_iris() 
X, y = iris.data, iris.target 
DF = pd.DataFrame(X, index = ["iris_%d" % (i) for i in range(X.shape[0])], columns = iris.feature_names) 

enter image description here

Nie sądzę, moja metoda jest poprawna, ponieważ poniżej daję on precomputed macierz odległości, a nie macierz danych prostokątnych zgodnie z żądaniem. Nie ma przykładów użycia matrycy korelacji/odległości z clustermap, ale istnieje dla https://stanford.edu/~mwaskom/software/seaborn/examples/network_correlations.html, ale kolejność nie jest zgrupowana w/plain sns.heatmap func.

DF_corr = DF.T.corr() 
DF_dism = 1 - DF_corr 
sns.clustermap(DF_dism) 

enter image description here

+0

Nie jestem pewien, czy rozumiem to pytanie. Czy druga matryca nie jest kwadratowa? – mwaskom

+0

Tak, druga jest zdecydowanie kwadratowa, ale to b/c podałem mu matrycę odległości (korelacja 1-), podczas gdy 'sns.cluster_map' wymaga prostokątnej matrycy danych. Tak więc, w zasadzie zajęło mi to nadmiarową macierz odległości, potraktowałem je jako nieprzetworzone wartości, a następnie powiązałem z tym. Czy to działa matematycznie? Nie wydaje się to mieć sensu, ponieważ dane wejściowe wymagają prostokątnej matrycy danych i wydaje mi się, że pewne kroki są powtarzane. –

+0

Myślę, że musisz edytować pytanie, aby było jasne, co chcesz wiedzieć. Jak napisano, pytasz, jak utworzyć kwadratową matrycę, i wyświetlasz wykres będący kwadratową matrycą. – mwaskom

Odpowiedz

8

Można zdać precomputed macierz odległości jak wiązanie do clustermap():

import pandas as pd, seaborn as sns 
import scipy.spatial as sp, scipy.cluster.hierarchy as hc 
from sklearn.datasets import load_iris 
sns.set(font="monospace") 

iris = load_iris() 
X, y = iris.data, iris.target 
DF = pd.DataFrame(X, index = ["iris_%d" % (i) for i in range(X.shape[0])], columns = iris.feature_names) 

DF_corr = DF.T.corr() 
DF_dism = 1 - DF_corr # distance matrix 
linkage = hc.linkage(sp.distance.squareform(DF_dism), method='average') 
sns.clustermap(DF_dism, row_linkage=linkage, col_linkage=linkage) 

Dla clustermap(distance_matrix) (czyli bez powiązania minęła), połączenie jest obliczany wewnętrznie na podstawie par odległościach z rzędów i kolumn w macierzy odległości (patrz uwaga poniżej dla pełnych szczegółów) zamiast bezpośrednio używać elementów macierzy odległości (poprawne rozwiązanie). W rezultacie, wyjście jest nieco inna niż w pytaniu: clustermap

Uwaga: jeśli nie row_linkage jest przekazywana do clustermap(), wiązanie rząd jest zdeterminowany wewnętrznie rozważając każdy wiersz „punkt” (obserwacja) i obliczanie odległości parami między punktami. Tak więc rząd dendrogramu odzwierciedla podobieństwo wiersza. Analogiczne do col_linkage, gdzie każda kolumna jest uważana za punkt. To wyjaśnienie powinno prawdopodobnie zostać dodane do docs. Tutaj pierwszy przykład dokumentu został zmodyfikowany w celu wyraźnego wyjaśnienia wewnętrznego powiązania:

import seaborn as sns; sns.set() 
import scipy.spatial as sp, scipy.cluster.hierarchy as hc 
flights = sns.load_dataset("flights") 
flights = flights.pivot("month", "year", "passengers") 
row_linkage, col_linkage = (hc.linkage(sp.distance.pdist(x), method='average') 
    for x in (flights.values, flights.values.T)) 
g = sns.clustermap(flights, row_linkage=row_linkage, col_linkage=col_linkage) 
    # note: this produces the same plot as "sns.clustermap(flights)", where 
    # clustermap() calculates the row and column linkages internally 
+0

Jeszcze raz dziękuję @Ulrich Stern, to ma sens! –