如何将含280+特征的Pandas DataFrame按高相关性分组为「红区」(组内相关>0.5)
实现特征红区组划分(两两相关性>0.5)
这是个典型的图论中的团(Clique)检测问题——你要找的是所有两两之间都满足相关性>0.5的特征子集,也就是完全连通的子图。下面我给你一套可落地的Python实现方案,用Pandas+NetworkX来搞定:
步骤1:准备工作
首先确保你安装了必要的库:
pip install pandas numpy networkx
步骤2:核心代码实现
假设你的DataFrame名为df,直接运行下面的代码:
import pandas as pd import numpy as np import networkx as nx # 1. 计算特征间的皮尔逊相关矩阵 corr_matrix = df.corr(method='pearson') # 2. 构建图结构:节点=特征名,边=两两相关性>0.5 G = nx.Graph() G.add_nodes_from(corr_matrix.columns) # 遍历所有特征对,添加符合条件的边 for i, feat1 in enumerate(corr_matrix.columns): for feat2 in corr_matrix.columns[i+1:]: if corr_matrix.loc[feat1, feat2] > 0.5: G.add_edge(feat1, feat2) # 3. 找出所有最大团(无法再加入其他特征的满足条件的组) max_cliques = list(nx.find_cliques(G)) # 4. 处理重叠特征,生成最终红区组(贪心策略:先到先得) assigned_features = set() red_zones = [] for clique in max_cliques: # 提取当前团中未被分配的特征 unassigned = [feat for feat in clique if feat not in assigned_features] if unassigned: red_zones.append(unassigned) assigned_features.update(unassigned) # 5. 处理孤立特征(和所有其他特征相关性≤0.5的特征) remaining_features = [feat for feat in corr_matrix.columns if feat not in assigned_features] if remaining_features: # 孤立特征单独成组 red_zones.extend([[feat] for feat in remaining_features]) # 输出结果 for zone_idx, zone in enumerate(red_zones, 1): print(f"红区组 {zone_idx}: {zone}")
关键细节说明
- 团的定义:
nx.find_cliques(G)返回的每个团,内部所有特征两两之间的相关性都>0.5,完全符合你的要求。 - 重叠特征处理:一个特征可能属于多个团,这里用的是「先到先得」的贪心策略,你也可以改成「分配到包含它的最大团」,只需要在遍历前把团按长度降序排序:
max_cliques.sort(key=len, reverse=True) - 相关性调整:如果你的需求是「相关性绝对值>0.5」(包含强负相关),只需要把判断条件改成
abs(corr_matrix.loc[feat1, feat2]) > 0.5即可。 - 结果验证:可以随机选一个红区组,验证内部相关性是否全部达标:
sample_zone = red_zones[0] zone_corr = df[sample_zone].corr() # 检查非对角线元素是否全部>0.5 print((zone_corr > 0.5).all().all()) # 正常应该返回True
性能优化提示
如果280个特征的计算速度较慢,可以先过滤掉孤立特征(和其他所有特征相关性≤0.5的特征),减少后续图计算的节点数:
# 找出至少和一个特征相关性>0.5的特征 non_isolated = [feat for feat in corr_matrix.columns if (corr_matrix.loc[feat] > 0.5).any()] # 只对非孤立特征构建图 G.add_nodes_from(non_isolated) # 后续步骤同上...
内容的提问来源于stack exchange,提问作者Cranjis
相关产品推荐
相关产品推荐

