seaborn.heatmap需传入corr矩阵、设annot=True显数值、cmap="coolwarm"匹配[-1,1]、中文需配置plt.rcParams。df.corr()默认Pearson,异常值多时改用spearman,缺失值建议dropna=True。

用 seaborn.heatmap 画相关性热力图,但颜色不对或数值不显示?
默认情况下 seaborn.heatmap 不显示数值,且会自动归一化颜色范围,导致高相关和低相关看起来差异不大。关键不是“怎么画”,而是“怎么让图说人话”。
- 加参数
annot=True才显示相关系数数字;fmt=".2f"控制小数位(避免满屏0.9999999) - 必须传入
corr = df.corr()这种已计算好的相关矩阵,别直接往heatmap里塞原始 DataFrame - 颜色失真常因用了
method='spearman'但没指定cmap—— 改用cmap="coolwarm"或"RdBu_r",对称色阶才匹配 [-1, 1] 范围 - 如果字段太多,图挤成一条线:加
xticklabels=False, yticklabels=False先看结构,再用plt.xticks(rotation=45)微调
df.corr() 返回的矩阵为什么和 Excel / SPSS 算出来不一样?
默认用的是 Pearson 相关系数,只对线性关系敏感;而你数据里有大量离散标签、异常值或单调非线性趋势时,结果就会“看起来不合理”。
- 检查数据类型:
df.dtypes—— 如果分类列被误读为int64,corr()会强行计算,结果无意义 - 想测秩相关(对异常值鲁棒):用
df.corr(method='spearman');想测是否同向单调:用method='kendall' - 缺失值处理暗坑:
corr()默认min_periods=1,只要两个变量在某行都不空就参与计算。样本量不一致会导致矩阵不对称(极少见但真实发生),显式加dropna=True再算更稳 - 别信 Pandas 默认的
numeric_only=None—— 在新版本里它可能跳过部分列,改用numeric_only=True明确限定
怎么过滤掉冗余特征?用 abs(corr) > 0.95 就够了吗?
单纯设阈值会漏掉“三角关系”:A 和 B 高相关(0.96),B 和 C 高相关(0.96),但 A 和 C 只有 0.89 —— 这时删谁?靠单点阈值无法决策。
- 先做相关矩阵上三角掩码:
np.triu(np.ones(corr.shape), k=1).astype(bool),避免自己和自己、重复比较 - 提取所有超阈值的变量对:
mask = abs(corr) > 0.95→mask &= mask != np.eye(len(mask))(去掉对角线) - 更实用的做法:对每个高相关对,保留那个在后续模型中
feature_importance更低(或缺失更少、业务含义更弱)的变量 —— 别只看数字 - 注意:
corr是两两统计,不能替代多重共线性诊断。VIF > 5 才真正说明“这个变量被其他几个联合解释得太多”,statsmodels.stats.outliers_influence.variance_inflation_factor得补上
中文列名热力图显示方块或乱码?
不是字体问题,是 Matplotlib 默认不支持中文字体,且 seaborn.heatmap 的 xticklabels 本质是 Matplotlib 的 Text 对象。
立即学习“Python免费学习笔记(深入)”;
- 运行前加两行:
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']和plt.rcParams['axes.unicode_minus'] = False - 别在
heatmap(..., xticklabels=df.columns)里传df.columns.tolist()—— 如果列名含空格或特殊字符,Matplotlib 会静默失败,留空标签 - 最稳方案:重命名列,用下划线代替空格,如
df.columns = df.columns.str.replace(' ', '_'),再画图 - 如果用了 Jupyter,
%matplotlib inline后仍乱码,说明内核没加载字体配置,重启 kernel 并确保上述rcParams在绘图前执行


















