熊猫数据框将特征划分为高相关性组

问题描述

我有一个具有280多个功能的数据框。 我运行了关联图以检测高度相关的特征组:

enter image description here

现在,我想将特征划分为组,这样每个组将成为一个“红色区域”,这意味着每个组将具有彼此之间的相关性均> 0.5的特征。

怎么办?

谢谢

解决方法

免责声明

  1. 此解决方案未解决可视化问题。仅找到组。
  2. 该解决方案已知是NP难解决的,因此会影响效率。

理论

问题本质上是图论中的clique problem,这意味着在给定图中(节点> 2)找到所有完整的子图。

想象一个图,其中所有要素都是节点,而满足corr > 0.5的要素对是边。然后,找到请求的所有“组”的任务可以简单地转换为“在图中找到所有完整的子图”。

代码

代码将networkx.algorithms.find_cliques用于搜索任务,根据文档实现了Bron–Kerbosch algorithm

代码包含两个部分。第一部分使用np.triu(从this post修改)提取边缘,第二部分将边缘列表输入networkx

关联矩阵

特征[A,B,C]和[C,D,E]密切相关,但在[A,B]和[D,E]之间不相关。

np.random.seed(111)  # reproducibility
x = np.random.normal(0,1,100)
y = np.random.normal(0,100)
a = x
b = x + np.random.normal(0,.5,100)
c = x + y
d = y + np.random.normal(0,100)
e = y + np.random.normal(0,100)

df = pd.DataFrame({"A":a,"B":b,"C":c,"D":d,"E":e})
corr = df.corr()

corr
Out[24]: 
          A         B         C         D         E
A  1.000000  0.893366  0.677333 -0.078369 -0.090510
B  0.893366  1.000000  0.577459 -0.072025 -0.079855
C  0.677333  0.577459  1.000000  0.587695  0.579891
D -0.078369 -0.072025  0.587695  1.000000  0.777803
E -0.090510 -0.079855  0.579891  0.777803  1.000000

第1部分

# keep only upper triangle elements (excluding diagonal elements)
mask_keep = np.triu(np.ones(corr.shape),k=1).astype('bool').reshape(corr.size)
# melt (unpivot) the dataframe and apply mask
sr = corr.stack()[mask_keep]
# filter and get names
edges = sr[sr > 0.5].reset_index().values[:,:2]

edges
Out[25]: 
array([['A','B'],['A','C'],['B',['C','D'],'E'],['D','E']],dtype=object)

第2部分

import networkx as nx
g = nx.from_edgelist(edges)
ls_cliques = []
for clique in nx.algorithms.find_cliques(g):
    ls_cliques.append(clique)

# result
ls_cliques
Out[26]: [['C','A','D','E']]