Python实战:构建相关性网络图,从高维数据中挖掘特征关联与业务洞察
1. 项目概述:从数据孤岛到洞察网络
“相关性网络图”这六个字,乍一听可能有点学术,但说白了,它就是一张能让你一眼看穿数据之间“谁和谁关系好”的图谱。想象一下,你手头有一堆变量,比如一个电商平台上的用户行为数据:浏览时长、加购次数、收藏商品数、最终购买金额、用户年龄、活跃时段等等。传统的分析方法,比如看个相关系数矩阵,是一堆冰冷的数字,你得一行行、一列列地去比对,才能勉强理出个头绪。而相关性网络图,就是把每个变量变成一个“点”(节点),如果两个变量之间的相关性足够强(无论是正相关还是负相关),就用一条“线”(边)把它们连起来。最终,所有强相关的变量会自然而然地聚集在一起,形成一个或多个“小团体”(社群),那些关系微弱的变量则会被边缘化。
这张图的价值,远不止是好看。它本质上是一种 探索性数据分析 的利器,尤其适合处理高维数据。当你有几十个甚至上百个特征时,靠人脑去理解它们之间错综复杂的关系几乎是不可能的。相关性网络图能帮你快速定位核心变量群、发现潜在的数据质量问题(比如高度共线的特征)、甚至启发你构建更有效的机器学习特征。我在金融风控、用户画像、生物信息学等多个领域都深度使用过它,每次都能从图中发现一些表格里“藏”着的秘密。无论你是数据分析师、算法工程师,还是业务运营,只要你的工作离不开从数据中找规律,掌握相关性网络图的构建与解读,就相当于多了一双透视数据的“火眼金睛”。
2. 核心原理与构建逻辑拆解
构建一张有意义的网络图,绝不是简单地把所有相关系数大于某个阈值的变量连起来就完事了。背后有一整套逻辑和权衡,每一步的选择都直接影响最终图的解释力。
2.1 相关性度量的选择:不止于皮尔逊
提到相关性,大部分人第一个想到的是 皮尔逊相关系数 。它衡量的是两个连续变量之间的线性关系强度,计算简单,解释直观,确实是入门首选。但它有两个致命弱点:第一,它只对线性关系敏感,对于曲线关系(比如先增后减)会严重低估;第二,它对异常值极其敏感,一个离群点就可能让结果面目全非。
因此,在实际项目中,我通常会根据数据特性备选其他方法:
- 斯皮尔曼等级相关系数 :不关心具体数值大小,只关心排名顺序。它评估的是单调关系(一个变量增加,另一个变量也倾向于增加或减少),对异常值不敏感,适用于非正态分布或存在异常值的数据。在分析用户满意度(1-5分)与复购行为的关系时,我常用它。
- 肯德尔等级相关系数 :与斯皮尔曼类似,也是基于秩次的,但在某些统计性质上更优,尤其适合样本量较小的情况。在计算基因表达量之间的相关性时比较常见。
- 互信息 :这是一个更强大的工具,来自信息论。它可以捕捉变量之间任何形式的统计依赖关系,无论是线性、非线性,甚至是环状的。它的计算相对复杂,且对连续变量需要先进行离散化(分箱),但在探索复杂系统,如神经信号、金融市场联动时,它能揭示皮尔逊发现不了的联系。
实操心得 :不要盲目迷信某一种方法。我的习惯是,对于一份新数据,先用皮尔逊和斯皮尔曼各算一遍,对比一下差异显著的边。如果差异很大,说明数据中存在非线性或异常值,需要优先处理数据或转向斯皮尔曼/互信息。
2.2 阈值过滤:从全连接到稀疏网络
计算完所有变量两两之间的相关性后,你会得到一个完全连通的网络(每个点都和其他所有点相连),这图毫无意义,看起来就是一团乱麻。 阈值过滤 是赋予网络图结构的关键一步。我们的目标是保留“强”连接,剔除“弱”连接,形成一个稀疏的、易于解读的网络。
设置阈值主要有两种思路:
- 绝对阈值法 :设定一个具体的相关系数值,比如 |r| > 0.7。这种方法简单直接,但缺点也很明显:不同数据集的相关性分布可能不同,固定阈值可能在某些数据集上过滤得太干净(网络太稀疏),在另一些数据集上又过滤得不够(网络仍然稠密)。
- 分位数阈值法 :这是我更推荐的方法。例如,保留相关性绝对值排名在前10%的边。这种方法能自适应数据的整体相关性强度,保证网络图的稀疏程度相对稳定。在Python中,你可以轻松地通过
np.percentile来计算这个阈值。
import numpy as np
import pandas as pd
# 假设 `corr_matrix` 是相关性矩阵的上三角部分(不含对角线)
corr_values = corr_matrix.values[np.triu_indices_from(corr_matrix, k=1)]
threshold = np.percentile(np.abs(corr_values), 90) # 取绝对值后90%分位数作为阈值
print(f“将保留相关性绝对值大于 {threshold:.3f} 的边”)
2.3 布局算法:让结构“浮现”出来
即使过滤了边,如果节点随机摆放,图还是一团糟。 布局算法 的作用就是根据节点之间的连接关系,自动计算每个节点的最佳位置,让联系紧密的节点彼此靠近,联系松散的节点彼此远离。
- 力导向布局 :这是最常用、最直观的一类算法。它模拟物理世界中的引力和斥力:相连的节点之间像有弹簧(引力),不相连的节点之间相互排斥。经过多次迭代,整个网络会达到一个力平衡的状态,社群结构就会清晰地呈现出来。
Fruchterman-Reingold算法是其中的经典代表。 - 社群发现布局 :如果你已经用算法(如
Louvain,Leiden)发现了网络中的社群(社区),可以先将同一社群的节点聚拢在一起,再在社群内部和社群之间使用力导向布局进行微调。这样得到的图层次感更强。 - 环形布局 :将所有节点均匀排列在一个圆环上,只绘制边。这种布局适合展示边的密度和特定节点的枢纽地位,但不擅长展示社群结构。
注意事项 :力导向布局的结果每次运行可能略有不同,因为其初始位置是随机的。为了得到稳定、可复现的图, 务必设置随机数种子 。另外,对于节点数超过500的大型网络,力导向布局会非常慢,此时可以考虑使用多层或基于采样的方法。
3. 实战:用Python构建与美化相关性网络图
下面,我将用一个模拟的电商用户数据集,带你走一遍完整的流程。我们假设有15个特征,包括用户属性、行为数据和消费数据。
3.1 数据准备与相关性计算
首先,我们生成模拟数据并计算斯皮尔曼相关系数。
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import spearmanr
# 1. 设置随机种子,确保可复现
np.random.seed(42)
# 2. 生成模拟数据:15个特征,1000个样本
n_samples = 1000
n_features = 15
# 创建一些人为的相关性群体
# 群体A:浏览相关特征 (0-3)
data = np.random.randn(n_samples, 4)
browse_group = data @ np.random.randn(4, 4) # 线性组合,制造内部相关性
# 群体B:购买相关特征 (4-7)
data = np.random.randn(n_samples, 4)
purchase_group = data @ np.random.randn(4, 4) + browse_group[:, 0:1] * 0.5 # 与浏览群体弱相关
# 群体C:独立特征 (8-14)
independent_group = np.random.randn(n_samples, 7)
# 合并所有特征
all_data = np.hstack([browse_group, purchase_group, independent_group])
feature_names = [f‘浏览_{i}’ for i in range(4)] + [f‘购买_{i}’ for i in range(4)] + [f‘其他_{i}’ for i in range(7)]
df = pd.DataFrame(all_data, columns=feature_names)
# 3. 计算斯皮尔曼相关系数矩阵
corr_matrix = df.corr(method=‘spearman’)
3.2 构建网络与过滤边
接下来,我们将相关系数矩阵转换为网络图,并应用分位数阈值进行过滤。
# 4. 创建无向图
G = nx.Graph()
# 5. 添加节点(每个特征一个节点)
G.add_nodes_from(feature_names)
# 6. 添加边:只添加相关性较强的边
# 提取上三角部分的相关系数值(绝对值)
corr_values = corr_matrix.values[np.triu_indices_from(corr_matrix, k=1)]
abs_corr_values = np.abs(corr_values)
# 使用85%分位数作为阈值(保留最强的前15%的相关性)
threshold = np.percentile(abs_corr_values, 85)
print(f“边过滤阈值(相关性绝对值): {threshold:.3f}”)
# 遍历所有特征对,添加符合条件的边,并将相关系数作为边的权重
for i in range(len(feature_names)):
for j in range(i+1, len(feature_names)):
corr = corr_matrix.iloc[i, j]
if abs(corr) > threshold:
G.add_edge(feature_names[i], feature_names[j], weight=corr, abs_weight=abs(corr))
# 打印网络基本信息
print(f“节点数: {G.number_of_nodes()}”)
print(f“边数: {G.number_of_edges()}”)
print(f“网络密度: {nx.density(G):.4f}”) # 密度越接近0,图越稀疏
3.3 应用布局与基础绘图
使用力导向布局算法计算节点位置,并绘制第一版网络图。
# 7. 计算力导向布局位置,使用边的绝对值权重作为“引力”强度参数
# ‘weight’参数名是`spring_layout`识别的,用于影响节点间引力
pos = nx.spring_layout(G, k=1.5, iterations=100, weight=‘abs_weight’, seed=42)
# 8. 绘制基础网络图
plt.figure(figsize=(12, 10))
# 绘制边:用颜色和透明度表示正负相关和强度
edges = G.edges(data=True)
edge_colors = [‘tomato’ if data[‘weight’] > 0 else ‘steelblue’ for _, _, data in edges]
edge_alphas = [abs(data[‘weight’]) for _, _, data in edges] # 强度决定透明度
# 分别绘制正相关和负相关的边,便于控制图例
pos_edges = [(u, v) for u, v, d in edges if d[‘weight’] > 0]
neg_edges = [(u, v) for u, v, d in edges if d[‘weight’] < 0]
nx.draw_networkx_edges(G, pos, edgelist=pos_edges, edge_color=‘tomato’,
alpha=0.6, width=1.5, style=‘solid’)
nx.draw_networkx_edges(G, pos, edgelist=neg_edges, edge_color=‘steelblue’,
alpha=0.6, width=1.5, style=‘dashed’) # 用虚线表示负相关
# 绘制节点:根据节点度(连接数)大小决定节点大小
node_degrees = dict(G.degree())
node_sizes = [300 + 100 * node_degrees[node] for node in G.nodes()]
nx.draw_networkx_nodes(G, pos, node_size=node_sizes, node_color=‘lightgrey’, edgecolors=‘black’, linewidths=1)
# 绘制节点标签
nx.draw_networkx_labels(G, pos, font_size=10, font_family=‘sans-serif’)
plt.title(‘电商用户特征相关性网络图(基础版)’, fontsize=16, pad=20)
plt.axis(‘off’) # 关闭坐标轴
# 添加自定义图例(matplotlib方式)
import matplotlib.patches as mpatches
red_patch = mpatches.Patch(color=‘tomato’, label=‘正相关’)
blue_patch = mpatches.Patch(color=‘steelblue’, label=‘负相关’)
plt.legend(handles=[red_patch, blue_patch], loc=‘upper right’)
plt.tight_layout()
plt.show()
这一版图已经能看出大概:浏览特征和购买特征各自形成了聚集,其他特征则分散在外围。但信息量还不够丰富。
3.4 高级美化与信息增强
让我们加入更多维度,制作一张信息密度更高的专业图表。
# 9. 高级美化绘图
plt.figure(figsize=(14, 12))
# 计算节点颜色(例如,用特征所属的预设分组)
# 假设我们预先知道分组:0-3浏览,4-7购买,8-14其他
node_colors = []
for node in G.nodes():
if ‘浏览’ in node:
node_colors.append(‘#FF9999’) # 浅红
elif ‘购买’ in node:
node_colors.append(‘#66B2FF’) # 浅蓝
else:
node_colors.append(‘#99FF99’) # 浅绿
# 重新绘制边和节点(用更精细的控制)
pos_edges = [(u, v) for u, v, d in edges if d[‘weight’] > 0]
neg_edges = [(u, v) for u, v, d in edges if d[‘weight’] < 0]
# 绘制边,宽度和透明度与相关性绝对值成正比
for edge_list, color, style in [(pos_edges, ‘#FF6B6B’, ‘solid’), (neg_edges, ‘#4D96FF’, ‘dashed’)]:
for u, v in edge_list:
weight = G[u][v][‘weight’]
abs_weight = abs(weight)
nx.draw_networkx_edges(G, pos, edgelist=[(u, v)],
width=abs_weight * 3, # 边宽代表强度
alpha=0.7,
edge_color=color,
style=style)
# 绘制节点,大小与节点度成正比,颜色代表分组
nx.draw_networkx_nodes(G, pos,
node_size=[200 + 150 * node_degrees[n] for n in G.nodes()],
node_color=node_colors,
edgecolors=‘black’,
linewidths=1.5,
alpha=0.9)
# 绘制节点标签,可以稍微偏移避免重叠
label_pos = {k: (v[0], v[1]+0.03) for k, v in pos.items()} # 向上偏移
nx.draw_networkx_labels(G, label_pos, font_size=11, font_weight=‘bold’)
# 10. 添加中心性指标作为注解(例如,度中心性)
degree_centrality = nx.degree_centrality(G)
# 找出度中心性最高的两个节点
top_nodes = sorted(degree_centrality.items(), key=lambda x: x[1], reverse=True)[:2]
for node, centrality in top_nodes:
x, y = pos[node]
plt.text(x, y-0.08, f‘度中心性: {centrality:.2f}’, fontsize=9,
ha=‘center’, bbox=dict(boxstyle=‘round,pad=0.3’, facecolor=‘yellow’, alpha=0.5))
plt.title(‘电商用户特征相关性网络图(增强版)\n节点颜色=特征分组 | 边宽/透明度=相关强度 | 虚线=负相关’, fontsize=16, pad=20)
plt.axis(‘off’)
# 创建更详细的图例
from matplotlib.lines import Line2D
legend_elements = [
Line2D([0], [0], marker=‘o’, color=‘w’, label=‘浏览特征’, markerfacecolor=‘#FF9999’, markersize=12),
Line2D([0], [0], marker=‘o’, color=‘w’, label=‘购买特征’, markerfacecolor=‘#66B2FF’, markersize=12),
Line2D([0], [0], marker=‘o’, color=‘w’, label=‘其他特征’, markerfacecolor=‘#99FF99’, markersize=12),
Line2D([0], [0], color=‘#FF6B6B’, lw=3, label=‘正相关(实线)’),
Line2D([0], [0], color=‘#4D96FF’, lw=3, linestyle=‘--’, label=‘负相关(虚线)’),
]
plt.legend(handles=legend_elements, loc=‘center left’, bbox_to_anchor=(1, 0.5), frameon=True)
plt.tight_layout()
plt.show()
这张增强版的图包含了极其丰富的信息:
- 节点颜色 直观展示了我们预设的特征分组,验证了网络自动聚集的效果。
- 边宽和透明度 双重编码了相关性的绝对值强度,一眼就能看出哪些关系最牢固。
- 边线样式 清晰区分了正相关(实线)和负相关(虚线)。
- 节点大小 反映了节点的“连接度”,度中心性高的节点往往是网络中的枢纽。
- 文字标注 直接标出了最重要的枢纽节点及其中心性指标。
4. 网络图的深度分析与指标解读
画出图只是第一步,更重要的是从图中挖掘洞察。网络科学提供了一系列量化指标来辅助我们解读。
4.1 关键节点识别:谁是这个网络的“枢纽”?
- 度中心性 :一个节点拥有的连接数。在我们的图中,“浏览_0”和“购买_0”可能度中心性很高,说明它们与很多其他特征都有较强关联,是核心变量。
- 特征向量中心性 :不仅考虑连接数量,还考虑邻居节点的重要性。一个节点如果连接到很多本身也很重要的节点,那么它的特征向量中心性就高。这有助于找到网络中最有影响力的“关键先生”。
- 中介中心性 :衡量一个节点落在其他节点之间最短路径上的频率。高中介中心性的节点充当了“桥梁”或“瓶颈”的角色。例如,可能有一个特征同时与“浏览”和“购买”群体都有强相关,它就在信息流动中起到了关键的桥梁作用。
# 计算并打印关键中心性指标
print(“=== 节点中心性指标 Top 5 ===”)
# 度中心性
print(“度中心性:”)
for node, cent in sorted(nx.degree_centrality(G).items(), key=lambda x: x[1], reverse=True)[:5]:
print(f“ {node}: {cent:.3f}”)
# 特征向量中心性
print(“\n特征向量中心性:”)
try: # 某些小图可能无法计算
for node, cent in sorted(nx.eigenvector_centrality(G, max_iter=500).items(), key=lambda x: x[1], reverse=True)[:5]:
print(f“ {node}: {cent:.3f}”)
except:
print(“ 图太小或结构特殊,无法计算。”)
# 中介中心性
print(“\n中介中心性:”)
for node, cent in sorted(nx.betweenness_centrality(G).items(), key=lambda x: x[1], reverse=True)[:5]:
print(f“ {node}: {cent:.3f}”)
4.2 社群发现:自动识别特征“小团体”
我们肉眼能看到浏览和购买特征分别聚集,但对于更复杂的网络,我们需要算法来帮我们精确划分社群。
- Louvain算法 :一种非常高效且效果出色的社群发现算法,通过模块度优化来寻找社区结构。模块度衡量的是社区内部连接的紧密程度相对于随机连接的提升。
# 使用 python-louvain 库进行社群发现
# 需要先安装:pip install python-louvain
import community as community_louvain
# 使用边的权重进行分区
partition = community_louvain.best_partition(G, weight=‘abs_weight’)
# 将分区结果可视化:为不同社群分配不同颜色
plt.figure(figsize=(12, 10))
cmap = plt.cm.tab20 # 使用色彩映射
unique_communities = set(partition.values())
community_color_map = {com: cmap(i / len(unique_communities)) for i, com in enumerate(unique_communities)}
node_colors_com = [community_color_map[partition[node]] for node in G.nodes()]
nx.draw_networkx_nodes(G, pos, node_color=node_colors_com, node_size=500, alpha=0.9)
nx.draw_networkx_edges(G, pos, alpha=0.3, width=1)
nx.draw_networkx_labels(G, pos, font_size=10)
plt.title(f‘Louvain社群发现结果 (共{len(unique_communities)}个社群)’, fontsize=16)
plt.axis(‘off’)
plt.tight_layout()
plt.show()
# 打印每个社群的成员
print(“\n=== 社群划分结果 ===")
for com in unique_communities:
members = [node for node in G.nodes() if partition[node] == com]
print(f“社群 {com}: {members}”)
运行后,算法很可能将我们预设的“浏览”和“购买”群体准确地划分到两个不同的社群中,这验证了我们数据构造的假设,也证明了网络图分析的有效性。
4.3 网络整体属性分析
- 平均路径长度 :网络中所有节点对之间最短路径的平均值。它衡量了网络的“效率”。在我们的相关性网络中,如果平均路径长度很短,说明信息(或影响)可以通过很少的步骤从一个特征传递到另一个特征。
- 聚类系数 :衡量节点的邻居之间也互相连接的程度,即“我朋友的朋友也是我的朋友”的概率。高聚类系数是现实世界网络(如社交网络)的典型特征。在相关性网络中,一个高聚类系数的社群,意味着其中的特征形成了一个高度内聚、彼此紧密关联的模块。
- 同配性 :衡量度值相似的节点是否倾向于相互连接。在我们的场景中,如果高度节点(枢纽特征)倾向于彼此连接,网络就是同配的。
# 计算网络整体属性(注意:需确保网络是连通的,否则需要取最大连通子图)
if nx.is_connected(G):
print(f“平均路径长度: {nx.average_shortest_path_length(G):.3f}”)
print(f“全局聚类系数: {nx.average_clustering(G):.3f}”)
else:
print(“网络不连通,无法计算平均路径长度。”)
# 计算最大连通子图的属性
largest_cc = max(nx.connected_components(G), key=len)
G_sub = G.subgraph(largest_cc).copy()
print(f“最大连通子图平均路径长度: {nx.average_shortest_path_length(G_sub):.3f}”)
print(f“全局聚类系数 (全图): {nx.average_clustering(G):.3f}”)
# 计算同配性系数(度同配性)
try:
assortativity = nx.degree_assortativity_coefficient(G)
print(f“度同配性系数: {assortativity:.3f}”)
if assortativity > 0:
print(“ 网络呈同配性:枢纽节点倾向于相互连接。”)
elif assortativity < 0:
print(“ 网络呈异配性:枢纽节点倾向于连接边缘节点。”)
else:
print(“ 网络无明显的同配/异配倾向。”)
except:
print(“无法计算同配性系数。”)
5. 避坑指南与常见问题排查
在实际操作中,你肯定会遇到各种问题。下面是我踩过坑后总结出的经验。
5.1 图一团乱麻,看不清结构?
- 问题 :节点和边挤在一起,完全无法分辨。
- 排查与解决 :
- 阈值太松 :这是最常见的原因。相关性阈值设得太低,保留了太多弱边。 解决方案 :提高阈值,比如从保留前30%的边提升到保留前10%或15%。可以尝试多个阈值,观察网络结构如何变化。
- 布局算法参数不当 :
spring_layout的k参数控制节点间的理想距离,iterations控制迭代次数。 解决方案 :增大k值(如从1.0调到2.0或3.0)可以让节点间距变大;增加iterations(如从50增到200)可以让布局更充分地收敛。 - 节点过多 :超过200个节点,力导向布局就会非常混乱且缓慢。 解决方案 :进行特征筛选。可以先计算每个特征与目标变量的相关性,或者使用方差阈值、特征重要性排序等方法,只保留最重要的几十个特征来画图。
5.2 计算相关性矩阵时报错或结果异常
- 问题 :出现NaN值,或所有相关性都接近1或-1。
- 排查与解决 :
- 存在常量列 :某个特征的所有值都相同,方差为0,导致计算相关系数时分母为零。 解决方案 :在计算前检查并删除方差为零的特征
df.loc[:, df.std() > 0]。 - 存在大量缺失值 :默认的
.corr()会 pairwise 删除缺失值,但如果数据缺失严重,不同特征对使用的样本可能差异很大,导致结果不可比。 解决方案 :要么删除缺失值过多的特征/样本,要么使用能够处理缺失值的插值方法填充后再计算。 - 数据未标准化 :如果特征量纲差异巨大(如年龄和收入),虽然皮尔逊相关系数本身不受线性缩放影响,但可能影响你对“强度”的判断。 解决方案 :对于画图来说不是必须,但为了其他分析,可以考虑进行Z-score标准化。
- 存在常量列 :某个特征的所有值都相同,方差为0,导致计算相关系数时分母为零。 解决方案 :在计算前检查并删除方差为零的特征
5.3 社群发现结果不合理或每次运行都变
- 问题 :Louvain算法把明显该在一起的节点分开了,或者两次运行结果不同。
- 排查与解决 :
- 算法随机性 :Louvain算法有随机初始化步骤,可能导致局部最优解。 解决方案 :设置随机种子
np.random.seed(),并多次运行(如100次),选择模块度最高的一次结果,或者使用best_partition函数,它内部已经做了优化。 - 权重影响 :你是否使用了权重?
best_partition(G, weight=‘abs_weight’)和best_partition(G)结果可能不同。 解决方案 :明确你的分析目标。如果想强调强连接,就使用权重;如果只关心连接与否,就不使用。 - 分辨率限制 :Louvain算法可能无法识别非常小的社群。 解决方案 :可以尝试
resolution参数(在某些实现中),调高它可能会发现更多更小的社群。
- 算法随机性 :Louvain算法有随机初始化步骤,可能导致局部最优解。 解决方案 :设置随机种子
5.4 图形渲染太慢或内存不足
- 问题 :绘制包含成千上万个节点的大图时,程序卡死或崩溃。
- 排查与解决 :
- 使用更高效的绘图后端 :Matplotlib 在渲染大量图形元素时较慢。 解决方案 :对于超大规模网络,考虑使用专门的网络可视化工具如 Gephi ,或者Python的 PyVis 库(生成交互式HTML),它们能更好地处理大规模数据。
- 简化图形元素 :不要绘制所有节点标签和边。 解决方案 :只绘制度中心性高于一定阈值的节点标签;将边的透明度调高或宽度调细;或者先进行社群发现,然后以社群为节点绘制更高层级的“元网络”。
- 采样 :如果数据量实在太大,可以考虑对数据进行采样,或者先使用其他降维方法(如PCA)提取主成分,再对主成分画网络图。
5.5 如何向非技术背景的同事解释这张图?
这是数据分析师经常面临的挑战。我的经验是:
- 讲比喻 :“想象每个业务指标是一个‘人’,如果两个指标经常同时升高或降低,它们就是‘好朋友’,我们用线连起来。最后,关系好的‘小团体’就自然聚到了一起。”
- 聚焦业务结论 :不要讲算法和参数。直接指给业务方看:“你看,‘加购次数’、‘收藏数量’和‘浏览深度’这三个点紧紧抱团,说明用户的深度浏览行为直接导向了收藏加购,这是我们内容运营有效的直接证据。而‘最终购买金额’这个点,虽然也和这个团有联系,但更靠近另一边‘优惠券使用率’和‘会员等级’的团,这说明最终转化更受促销和用户身份影响。”
- 用动态图或交互图 :一次静态汇报可能讲不清楚。使用
PyVis生成一个HTML交互图,让业务同事自己用鼠标拖动、点击高亮,他们的理解和兴趣会深刻得多。
最后,我个人最深的体会是,相关性网络图不是一个“一次性”的分析工具,而是一个 探索循环的起点 。你从图中发现了一个紧密的社群,然后就要回到数据本身,问为什么?是业务逻辑使然,还是数据泄露?发现了一个关键的“桥梁”节点,就要思考它是否能作为一个优秀的特征用于预测模型?发现两个本该相关的变量却没有连接,是不是数据采集出了问题?这张图的价值,就在于它把高维的、抽象的数据关系,变成了肉眼可见、直觉可理解的形态,从而极大地激发了你的数据好奇心和探索欲。
更多推荐

所有评论(0)