资讯动态

连续型变量相关性分析:三种相关系数原理与Python实现

发布时间:2026/10/18 4:59:17 来源:尧图企业网站定制
相关性分析这件事说穿了就是在回答两个问题两个连续型变量之间到底有没有关系关系有多强、有多稳定。我做了好几年数据分析每次拿到新数据集几乎都会把这个动作放在最前面。标题里的“连续型变量”是重点——现实里大量核心指标都是连续的销售额、温度、响应时长、转化率这类建模之前先搞清它们之间的相关结构能少走很多弯路。这篇文章我会把三种最常用的相关系数讲透包括原理、适用场景、Python实操以及那些最容易被忽视的坑。内容不绑定具体行业电商、金融、物联网里的场景基本都能套用。适合刚接触数据分析的人做入门也适合已经在跑模型、但想把统计底子补扎实的同行顺手翻一翻。这个系列既然叫“统计学与统计机器学习”前面这几篇我会优先把最常用、最容易误用的统计工具梳理清楚相关性分析就是第一块基石。1. 为什么第一件事永远是相关性分析1.1 建模前的“体检报告”很多人拿到数据就急着训练模型我见过太多这种急性子结果模型跑出来一团糟回头排查才发现特征之间高度共线或者某个被当成强特征的变量其实和目标变量半毛钱关系都没有。相关性分析就是建模前的那份体检报告花十分钟做一遍后面能省下几小时的调参时间。具体来说相关性分析能提前暴露三类问题。第一类是特征冗余两个特征相关系数超过0.8把它们同时塞进线性模型系数会变得很不稳定标准误被放大解释性直接崩掉。第二类是数据质量问题如果一个特征本来应该和目标有强相关算出来却接近零大概率是采集、清洗或对齐环节出了岔子这时候去查数据往往能发现一堆脏值。第三类是业务洞察相关性结构本身就能告诉你哪些指标在同步变化这在做报表和归因时很有价值。说它是“体检报告”还有个原因相关性分析是探索性的。它不会直接告诉你“该用哪个模型”但它会告诉你“接下来该往哪个方向看”。比如发现两个特征高度相关你可以考虑做特征融合发现目标变量和某个特征完全不相关可以考虑直接丢弃。这些判断越早做成本越低。1.2 连续型变量为什么值得单独拿出来讲分类变量之间看相关性用的是卡方检验、Cramérs V这类工具底层逻辑和连续变量完全不同。连续型变量自带数值的大小、排序和距离信息所以我们能谈“随一个变量增大另一个变量如何变化”这种关系强度可以用一个标量压缩表达。这就是相关系数存在的意义。但连续型变量的麻烦也在这里越是信息丰富越容易被错误解读。比如两个变量关系是曲线线性相关系数可能接近零再比如数据里混进一个异常值相关系数就可能从一个极端跳到另一个极端。后面的章节我会专门展开这些坑现在先记住一个原则任何相关系数都是一堆假设之下的“快照”不是放之四海而皆准的真理。从统计机器学习角度看连续型变量相关分析还是很多后续步骤的入口。特征选择要筛相关PCA要看协方差结构回归要诊断多重共线性聚类要看变量是否适合同时进入距离计算。可以说连续型变量的相关性分析是一个承上启下的基础模块题目里把它放在系列第一篇是有道理的。2. 三种主流相关系数的原理和选型逻辑2.1 皮尔逊相关系数衡量线性关系的“标尺”皮尔逊相关系数通常记为r是最常用、也最容易被滥用的一个。它的定义是协方差除以两个变量的标准差r Σ((xi - x̄)(yi - ȳ)) / sqrt(Σ(xi - x̄)² · Σ(yi - ȳ)²)这个公式用口语翻译一下先把每个变量减去自己的均值得到偏离中心的部分然后看两个变量偏离的方向是否一致——同时偏大或同时偏小乘积为正说明正相关一个偏大另一个偏小乘积为负说明负相关。把所有乘积加起来再归一化到-1到1之间就是r。为什么说皮尔逊相关系数是“线性”关系的标尺因为它本质上是在用一个最佳拟合直线去描述两个变量的关系。如果数据点不在一条直线附近而是呈明显的曲线分布这个标尺就会失灵——哪怕两者的函数关系非常强算出来的r也可能很接近0。我在实际项目里见过不止一次某两个指标明明有很强的单调关系但因为中间有一段平台期线性相关系数只有0.2左右。皮尔逊相关系数还有几个隐含前提变量大致呈正态分布没有严重异常值最好还是连续的数值型变量。它是最灵敏的相关系数用对场景时效率极高但前提条件不满足时它的结果可信度就要打个问号。这里可以给个生活化类比皮尔逊相关系数就像一把刻度精准的直尺量直线很靠谱量弯曲的路面就不能硬来了。2.2 斯皮尔曼秩相关系数把关系变成排名来比斯皮尔曼秩相关系数Spearmans rank correlation的思路很巧妙不看原始数值先把两组数据各自排序得到每一条记录在变量内部的“名次”也就是秩然后对这些秩算皮尔逊相关系数。它衡量的是两个变量的单调关系——随着一个变量增大另一个是否稳定地增大或减小至于这种增大是匀速还是变速它不关心。这个特性让斯皮尔曼在两类场景下非常实用。第一类是数据严重偏离正态分布或存在异常值时极端值只会影响它在排序中的位置不会像在皮尔逊计算里那样通过平方项被放大所以结果更稳。第二类是关系是单调但非线性的情况比如“收入增长和消费升级速度”这种先快后慢的关系用皮尔逊可能低估用斯皮尔曼则能如实反映。用秩替代原始值代价是会丢失一部分信息。如果数据本身确实接近线性、分布也正常斯皮尔曼的精确度通常略低于皮尔逊因为它把具体的距离信息压成了顺序信息。所以它和皮尔逊不是“谁替代谁”的关系而是不同场景下的不同工具。2.3 肯德尔tau小样本和大量并列值时的稳定选择肯德尔tau系数在业内不如前两者常用但在特定场景里非常能打。它基于一个完全不同的计数思想任意取两条记录组成一对看它们在两个变量上的相对次序是否一致。如果第一条记录在变量X和变量Y上都比第二条大这就是一个“一致对”如果一个更大另一个更小就是“不一致对”。肯德尔tau的计算围绕这两种对数展开最后归一化到-1到1。这种计数方式让肯德尔tau对样本量和并列值比较稳健。样本量小的时候皮尔逊和斯皮尔曼的抽样波动可能很大肯德尔tau反而稳定一些。数据里如果有大量并列的数值离散化产生的数据、评分数据一致对和不一致对的计数能更合理地处理平局影响。当然肯德尔tau的缺点是计算复杂度比前两者高——数据量大了之后两两配对的数量会暴涨。在几千行的“小数据”上跑完全没问题但面对上百万行数据时计算代价就要考虑了。另外它的数值一般会比皮尔逊略小一些解读时不要直接套用“0.8以上算强相关”的直觉阈值。2.4 到底怎么选先画图再定方法每次有人问我“用哪个相关系数”我的答案永远是先画散点图看一眼再说。统计检验和指标都应该服务于对数据的直观理解而不是反过来用指标代替眼睛。具体选择逻辑可以归纳成四步。第一步画散点图观察整体形态。如果数据点明显在一条直线附近用皮尔逊如果是一条明显上升或下降的曲线用斯皮尔曼如果图形既乱又没有单调趋势那说明关系很弱直接用哪个方法区别都不大。第二步做正态性检查。严重偏态的数据优先考虑斯皮尔曼或肯德尔。第三步检查异常值。箱线图或Z-score一拉发现极端值较多就别坚持皮尔逊了斯皮尔曼更稳。第四步看业务场景。业务上更关心的是“排序是否一致”还是“线性变化幅度”会直接影响指标选择——比如做用户分层时往往关心排名一致性斯皮尔曼就更贴切。三种方法对比可以参考这张表指标衡量关系类型输入数据要求对异常值的敏感度适用样本量皮尔逊r线性关系连续、近似正态、无极端异常值高中到大样本斯皮尔曼ρ单调关系连续或有序对分布不敏感低中到大样本肯德尔τ单调关系基于配对计数连续或有序适合并列值多低小样本更稳3. Python实操从相关系数矩阵到显著性检验3.1 数据准备阶段容易忽略的三个细节很多人以为相关性分析就是把数据丢进df.corr()就完了实际操作中我踩过的坑比想象中多而且绝大多数都在数据准备环节。第一个细节是缺失值。以pandas的DataFrame.corr()为例它默认按“成对删除缺失值”的方式计算——哪两个变量参与计算就用两者同时非空的记录算。这会导致一个隐藏陷阱变量A和B用1000条记录算相关系数变量B和C可能只用800条记录算整个相关矩阵里不同格子对应的样本量不一致。如果缺失机制不是随机的这种不一致会直接扭曲相关矩阵。建议在正式计算前先做一个df.isna().sum()确认缺失规模再决定用均值插补、中位数插补还是更稳的单变量插补。第二个细节是数据类型。我遇到过把数值存成字符串的情况df[sales].dtype看过去是object直接corr()会报错或者被跳过。用pd.to_numeric()统一转一遍同时处理可能出现的无法转换的值这一步做了能省不少排查时间。第三个细节是标准化。皮尔逊相关系数本身不受量纲影响因为公式里已经除以标准差做不做标准化都不影响数值得分。但如果你后续要做聚类、距离计算或主成分分析标准化就会影响结果。所以在这个环节就要想清楚这次分析是只报告相关性还是相关矩阵会被下游模块使用。想清楚了这一步就不会白做。3.2 一行代码算出相关系数矩阵数据准备好之后用pandas算相关系数矩阵非常简单import pandas as pd # 假设df是已经清洗好的数据框只保留数值列 numeric_cols df.select_dtypes(include[float64, int64]).columns df_numeric df[numeric_cols] # 皮尔逊相关矩阵默认method就是pearson pearson_corr df_numeric.corr(methodpearson) # 斯皮尔曼相关矩阵 spearman_corr df_numeric.corr(methodspearman)method参数可以换成pearson、spearman、kendall用起来非常顺手。不过要提醒一句这个函数只输出相关系数矩阵不会输出p值。如果你需要判断显著性得去scipy里拿更完整的统计量。当数据量特别大或者只关心两个变量时用numpy会更高效import numpy as np x df[sales].to_numpy() y df[temp].to_numpy() corr_matrix np.corrcoef(x, y) print(corr_matrix[0, 1])np.corrcoef直接返回2x2的矩阵多个变量会返回n x n对角线是1。它的速度比pandas快不少但要注意它是用来算皮尔逊相关不支持方法切换。3.3 显著性检验不是可选项相关系数只是点估计它到底可不可信还要看p值。零假设是“总体相关系数为0”p值表示如果两个变量真的不相关看到当前这么强的样本相关系数或更强的概率有多大。p值越小越有理由相信这个相关不是抽样误差造成的。scipy提供了现成的函数from scipy import stats r_pearson, p_pearson stats.pearsonr(df[sales], df[temp]) r_spearman, p_spearman stats.spearmanr(df[sales], df[temp]) r_kendall, p_kendall stats.kendalltau(df[sales], df[temp])这里有个非常现实的坑大样本下即使相关系数只有0.05p值也可能小于0.001。因为样本量越大标准误越小微小的相关也能被检测出来。所以报告结果时一定要同时给r和p不要只丢一个p值。如果你想知道相关系数的置信区间可以对皮尔逊r做Fisher z变换。核心是先把r变换成近似正态分布的zz 0.5 × ln((1 r) / (1 - r))然后按正态分布公式算z的置信区间再反变换回r的区间。这个计算过程不复杂可以手工实现。我通常习惯在报告中给95%置信区间因为单看点估计很容易忽视样本量带来的不确定性。样本量小的时候误差是肉眼可见的。比如n15r0.50它的置信区间可能从-0.02一直跨越到0.82。这时如果你只看“r有0.5”就断言强相关就会做出非常冒险的业务判断。经验法则是小于30个样本的相关系数必须看置信区间别当回事。3.4 把结果画出来热力图和散点图矩阵数字看多了容易麻木可视化永远是相关性分析的好搭档。最常用的三个图散点图矩阵、热力图、单个变量对的散点图加拟合线。散点图矩阵用seaborn的pairplot就能画适合变量数量不多比如5到8个时一屏概览所有两两关系import seaborn as sns sns.pairplot(df_numeric, kindreg, diag_kindkde)kindreg会在每个面板上加上回归拟合线帮你看清线性趋势。diag_kindkde让对角线展示密度分布顺带看一眼变量分布形态。热力图适合快速呈现整体相关矩阵import matplotlib.pyplot as plt corr df_numeric.corr(methodspearman) plt.figure(figsize(10, 8)) sns.heatmap(corr, annotTrue, fmt.2f, cmapRdBu_r, vmin-1, vmax1, masknp.triu(np.ones_like(corr, dtypebool))) plt.show()masknp.triu(...)把矩阵上三角遮掉只留下半张避免重复信息看起来更清爽。vmin-1, vmax1固定颜色映射范围这点很重要——不固定的话颜色深浅可能被数据范围带偏导致两张图看起来色调一致但实际数值差很大。如果某个变量对特别关键单独画一张散点图加上拟合线和置信带sns.regplot(xdf[temp], ydf[sales], ci95, scatter_kws{alpha: 0.4})这一步对判断是否存在曲线关系很有帮助。我见过太多人只盯着热力图上的数字忽略了这个散点图结果漏了非线性关系。先看图再读数字是相关分析的第一铁律。4. 边界、误用与反直觉案例4.1 相关性永远不等于因果性相关性不等于因果性这句话已经被讲到快磨出茧子但在实际项目里还是不断有人栽跟头。核心原因是两个变量高度相关可能是直接因果也可能是共同原因导致还可能是纯属巧合的伪相关。我在内部培训时常用的教学场景是“气温与销量”。某地7月份冰淇淋销售量和溺水人数高度相关相关系数可能到0.9以上但没有人会因此认为“卖冰淇淋导致溺水”。背后的共同原因显然是夏季高温让大家都往水边跑也顺手买冰淇淋。这个场景很直观但换到业务环境里就容易被忽略渠道投放费用和销售额同涨同跌难道就能说明投放驱动了销售也可能是产品本身进入旺季投放费用是被动追加的预算。相关性分析只能告诉你“它们一起动了”至于谁在拉动谁需要实验设计、时序分析或领域知识去进一步验证。谨慎的汇报姿势是在报告里把相关性和因果判断分开写。相关性给数据证据因果判断给逻辑链条和验证方案。一旦把两者混在一起决策者很容易被带偏。4.2 分组效应方向反转的辛普森现象比“相关不等于因果”更隐蔽的坑是分组后方向反转。我用一个完全虚构的教学数据说明某团队收集了两个月的销售数据按整体看广告曝光量和周销售额呈正相关但把数据按两个不同渠道分开看每个渠道内部的相关系数却都是负的。整体和局部方向完全相反这就是辛普森悖论的典型表现。这种悖论在相关分析中的教训是拿到数据别急着算总相关先按业务分组画图。常见的分组维度包括渠道、地区、时间窗口、用户层级。分组后相关方向变化说明可能存在一个未观察到的混杂变量整体相关是被这个变量“撑起来的”直接用整体结论做决策非常危险。具体操作上我会在算相关矩阵前先用hue参数快速看分组散点图sns.scatterplot(datadf, xad_spend, ysales, huechannel_name)一眼就能看出各个组内的趋势是否一致。如果各组趋势和整体趋势明显背离说明整体相关系数是“表面数字”分组分析才有业务意义。4.3 异常值如何轻松“操纵”相关系数皮尔逊相关系数对异常值的敏感程度远超很多人的想象。一个极端点可以把相关系数从0.1拉到0.8也可以从0.9压到几乎为0。原因在于公式里有平方项极端值和均值的偏离被平方放大权重远远超过正常点。我见过一个真实案例两个变量本来相关系数稳定在0.3左右某个月因为一个促销活动产生了一个极端高值相关系数直接跳到0.75。如果只看结果会误以为两者关系突然增强了其实是那一个点贡献了一大半“相关”。应对思路有两种。一种是用对异常值更稳健的方法斯皮尔曼或肯德尔。它们在计算时把数值转成排名极端值只占一个名次影响有限。另一种是保留皮尔逊但先做异常值处理用箱线图找出超出1.5倍四分位距的点或者用Z-score绝对值大于3的点先查明这些点是不是录错、口径变更或特殊事件导致的再决定是否剔除或单独分析。4.4 相关系数接近0不代表没有关系这条可能是相关性分析里最深的一个坑线性相关系数为0只能说明“没有线性关系”完全不能说明“两个变量没关系”。典型例子是倒U形关系比如学习时间与绩效时间太少绩效低时间适中绩效最高时间过长反而疲劳导致绩效下降。整个图形的形状是明显的曲线但如果你硬算皮尔逊相关系数结果大概率接近0。还有一种常见形态是分段关系前一段正相关明显后一段变得平缓或反向整体看线性相关性也被稀释了。面对这种情况光看相关系数就会得出“没关系”的错误结论。正确的检查方式是每次算完相关系数至少对每一对关键变量画一次散点图。如果看到明显的曲线形态可以考虑对变量做变换后再计算线性相关比如取对数、平方、加交互项或者直接改用斯皮尔曼秩相关描述单调性。机器学习模型虽然能自动捕捉非线性但在做特征分析和解释时你仍然需要知道自己手里这些变量之间的关系到底是什么形状。5. 常见问题排查与避坑实录5.1 高频异常现象速查表这张表是我在实际项目中反复遇到、也反复帮人排查过的问题整理成一个速查表方便直接对照使用现象可能原因优先排查动作Pearson≈0但散点图有明显曲线非线性关系改用Spearman或对变量做变换后再算相关矩阵多个格子出现NaN该变量对缺失值过多检查缺失率决定插补还是删除r很小但p值小于0.01样本量过大导致微小相关被“检验出”报告效应量r和置信区间不单看p值Pearson与Spearman结果差异悬殊存在异常值或非线性趋势画散点图定位异常点相关矩阵上三角和下三角不一致部分变量对样本量不一致确认缺失值处理策略统一样本口径相关系数高但业务上完全说不通伪相关或共同驱动因素做偏相关分析控制第三变量5.2 偏相关排除“第三者”干扰速查表里提到偏相关这里展开说说。偏相关的思想是在看变量X和Y的关系时把另一个变量Z的影响先“剥离”掉计算剩余部分的相关。实现方式是先用回归把X和Y分别对Z做回归取残差再算两个残差的相关系数。在Python里可以用pingouin库非常方便地算偏相关import pingouin as pg partial_corr pg.partial_corr(datadf, xsales, ytemp, covarseason_index)这个库还自带置信区间和p值比手写残差法省事。我在做归因分析时经常用偏相关来辅助判断两个指标表面高度相关加上第三个变量做偏相关后如果数值骤降说明现有相关性很可能是通过第三者“搭桥”产生的。当然偏相关也只是统计控制不能替代实验设计但它可以帮助筛选值得深入验证的候选关系。5.3 关于多重比较的一个实际提醒当你有10个连续变量时相关系数矩阵里会有45对关系。每对都做显著性检验按0.05的显著性水平纯属随机也可能有2到3个假阳性。所以当分析变量较多时要么用Bonferroni校正把显著性水平除以比较次数要么干脆把相关矩阵定位为探索性工具用显著性筛选出候选关系之后再做验证性分析。我自己的习惯是第一遍跑相关矩阵时不做校正把它当作“发现线索”第二遍挑出业务关注的核心假设单独做严谨检验并控制错误发现率。这样做在实际项目中既保证了探索广度又不至于被一堆假阳性淹没。5.4 实战经验小抄最后按老规矩把零散经验浓缩成几条。第一永远先画散点图再算相关系数这条怎么强调都不为过。第二多算几种相关系数互相印证比选一个“最正确”的方法更可靠。第三报告结果时至少包含相关系数、p值、样本量、置信区间如果有条件四件套齐全才不会被质疑。第四当相关系数矩阵要喂给下游算法时比如放进聚类距离或者做主成分分析记得先评估变量之间的共线性必要时做去相关处理或换用能处理共线性的算法。第五期间不要迷信“0.8就是强相关”这种一刀切阈值强不强取决于业务背景和数据量两个变量在1000个样本上r0.3可能已经是很重要的业务发现。我在这块操作中体会最深的一点是相关性分析不是“算完交差”的机械动作而是理解数据结构的第一扇窗口。很多项目到后期才发现变量关系没摸清回头补课时成本远比一开始多画几张图高得多。如果你现在也在做数据分析或特征工程建议从这一篇开始把连续型变量的相关性这个基本功彻底打牢。后面这个系列我会继续写回归诊断、假设检验和常见机器学习算法背后的统计逻辑每一步都尽量像今天这样把坑和原理一并讲透。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑