如何给 sns.clustermap 一个预先计算的距离矩阵?
Posted
技术标签:
【中文标题】如何给 sns.clustermap 一个预先计算的距离矩阵?【英文标题】:How to give sns.clustermap a precomputed distance matrix? 【发布时间】:2016-12-06 22:02:19 【问题描述】:通常当我做树状图和热图时,我使用距离矩阵并做一堆SciPy
的东西。我想试试Seaborn
但Seaborn
想要我的数据是矩形的(行=样本,列=属性,而不是距离矩阵)?
我本质上想使用seaborn
作为后端来计算我的树状图并将其添加到我的热图上。这可能吗?如果没有,这是否可以成为未来的功能。
也许我可以调整一些参数,以便它可以采用距离矩阵而不是矩形矩阵?
用法如下:
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)
我的代码如下:
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)
我不认为我的方法在下面是正确的,因为我给它一个预先计算的距离矩阵,而不是它要求的矩形数据矩阵。没有关于如何将相关/距离矩阵与clustermap
一起使用的示例,但有https://stanford.edu/~mwaskom/software/seaborn/examples/network_correlations.html 的示例,但排序不与普通的sns.heatmap
函数一起使用。
DF_corr = DF.T.corr()
DF_dism = 1 - DF_corr
sns.clustermap(DF_dism)
【问题讨论】:
我不确定我是否理解这个问题。第二个矩阵不是方阵吗? 是的,第二个肯定是正方形的,但它是 b/c 我给它一个距离矩阵(1-相关),而sns.cluster_map
需要矩形数据矩阵。所以基本上它采用了我的冗余平方距离矩阵,将它们视为原始值,然后从中进行链接。这在数学上有效吗?这似乎没有意义,因为输入需要一个矩形数据矩阵,我认为某些步骤正在重复。
我认为您需要编辑问题以更清楚地了解您想知道的内容。如所写,您在询问如何制作方阵,并且您正在展示一个方阵图。
K,我现在就解决这个问题。
【参考方案1】:
您可以将预先计算的距离矩阵作为链接传递给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)
对于clustermap(distance_matrix)
(即,未传递链接),链接是在内部根据距离矩阵中的行和列的成对距离计算的(有关完整详细信息,请参见下面的注释),而不是使用距离矩阵的元素直接(正确的解决方案)。结果,输出与问题中的输出有些不同:
注意:如果没有row_linkage
传递给clustermap()
,则行链接是通过将每一行视为一个“点”(观察值)并计算点之间的成对距离在内部确定的。所以行树状图反映了行的相似性。与col_linkage
类似,其中每一列都被视为一个点。这个解释可能应该添加到docs。这里修改了文档的第一个示例以明确内部链接计算:
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
【讨论】:
再次感谢@Ulrich Stern 这很有意义!以上是关于如何给 sns.clustermap 一个预先计算的距离矩阵?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Scikit KMeans 中使用预先计算的距离矩阵?