如何使用 sklearn k-means 聚类根据彼此的相关性对 * 特征 * 进行聚类

Posted

技术标签:

【中文标题】如何使用 sklearn k-means 聚类根据彼此的相关性对 * 特征 * 进行聚类【英文标题】:How to cluster *features* based on their correlations to each other with sklearn k-means clustering 【发布时间】:2019-03-07 20:18:17 【问题描述】:

我有一个 pandas 数据框,其中行作为记录(患者)和 105 列作为特征。(每个患者的属性)

我想对患者进行聚类,而不是按照惯例对行进行聚类,而是对列进行聚类,以便我可以查看哪些特征与哪些其他特征相似或相关。我已经可以使用df.corr() 计算每个特征与其他所有特征的相关性。但是如何使用sklearn.cluster.KMeans 将它们聚类到 k=2,3,4... 组中?

我尝试了KMeans(n_clusters=2).fit(df.T),它确实对特征进行了聚类(因为我采用了矩阵的转置),但仅使用欧几里得距离函数,而不是根据它们的相关性。我更喜欢根据相关性对特征进行聚类。

这应该很容易,但非常感谢您的帮助。

【问题讨论】:

如果某个特征 A 与 B 相关并且 B 与 C 相关但 A 与 C 不相关,会发生什么?这种情况很容易出现。如果你有两个聚类(粗略地说,相关特征组和不相关特征组),那么 A 和 C 属于同一组(不相关特征)但 A 和 B 属于另一组(相关特征) .你会怎么处理?您的组之间不能有交集。 这可能有点愚蠢,但是 PCA 呢?如果多个特征是相关的,它们各自的由协方差矩阵分解提供的特征向量应该是“接近”的,对吗?您可以使用余弦相似度进行聚类吗? 【参考方案1】:

通过获取所有特征 df.corr() 的相关性创建一个新矩阵,现在使用这个新矩阵作为 k-means 算法的数据集。 这将为您提供具有相似相关性的特征集群。

【讨论】:

【参考方案2】:

KMeans 在这种情况下不是很有用,但您可以使用任何可以处理距离矩阵的聚类方法。例如 - 凝聚聚类。

我将使用 scipy,sklearn 版本更简单,但没有那么强大(例如,在 sklearn 中,您不能将 WARD 方法与距离矩阵一起使用)。

from scipy.cluster import hierarchy
import scipy.spatial.distance as ssd

df = ...  # your dataframe with many features
corr = df.corr()  # we can consider this as affinity matrix
distances = 1 - corr.abs().values  # pairwise distnces

distArray = ssd.squareform(distances)  # scipy converts matrix to 1d array
hier = hierarchy.linkage(distArray, method="ward")  # you can use other methods

阅读文档以了解 hier 结构。

你可以用

打印树状图
dend = hierarchy.dendrogram(hier, truncate_mode="level", p=30, color_threshold=1.5)

最后,为您的特征获取集群标签

threshold = 1.5  # choose threshold using dendrogram or any other method (e.g. quantile or desired number of features)

cluster_labels = hierarchy.fcluster(hier, threshold, criterion="distance")

【讨论】:

以上是关于如何使用 sklearn k-means 聚类根据彼此的相关性对 * 特征 * 进行聚类的主要内容,如果未能解决你的问题,请参考以下文章

Sklearn参数详解—聚类算法

使用 sklearn_pandas 查找 k-means 聚类最重要的词

机器学习之SKlearn(scikit-learn)的K-means聚类算法

如何在sklearn中检查k-means中给定向量的集群细节

Sklearn k-means聚类(加权),确定每个特征的最佳样本权重?

如何从 K-Means 聚类中解释轮廓系数?