尧图精选

12种相关系数全解析:从皮尔逊到距离相关,彻底告别只会cor()

🕒 发布时间:2026/10/1 19:02:34 📁 来源:尧图网络
相关系数这东西很多人的认知基本就停在皮尔逊。论文里跑个cor(x, y)得出个0.8就觉得自己发现了新大陆。但真到了实际项目里皮尔逊往往是最不够用的那一个——数据稍微偏态一点、带几个离群值、或者根本不是线性关系它给出的结果就非常不靠谱。这篇就把12种实际工作中用得上的相关系数一次性讲清楚。不堆公式重点说清楚每种系数解决什么问题、适合什么数据、在R和Python里怎么算、以及最容易踩的坑。建议收藏下次碰到“相关性分析”别再只会皮尔逊了。1. 理解相关系数的底层逻辑在逐个上手12种相关系数之前先把底层逻辑理顺。因为如果不懂每种系数在衡量什么你只是在机械地套函数换个数据依旧不知道怎么选。1.1 相关系数究竟在度量什么说白了相关系数回答的问题只有一个一个变量的变化在多大程度上伴随另一个变量的变化。但这个“伴随”有太多模式——是同步上升下降是相反方向是缓慢的等级趋势还是先升后降的曲线关系从数学本质上看几乎所有的相关系数都是把原始数据映射到某个空间然后计算某种“距离”。皮尔逊是把数据映射到线性空间度量的是“到一条直线的距离”斯皮尔曼是把数据转换成排名然后看排名是否同步距离相关则是比较两个变量各自的距离矩阵之间的相似度。明确这一点你就明白为什么不同系数的结果可能差异巨大同一份数据用皮尔逊算出0.3用斯皮尔曼算出0.7用距离相关算出0.9这种现象一点都不奇怪因为它们回答的是关于数据不同侧面的问题。皮尔逊在问“是否在一条直线上”斯皮尔曼在问“排名是否一致”距离相关在问“临近的点是否依然临近”。1.2 理解两类“非相关”陷阱在实际分析中有两个陷阱几乎人人都会踩。第一个是线性相关为0但关系存在。经典的例子是X从-1到1YX²。用皮尔逊算结果趋近于0但X和Y的依赖关系是数学上确定的。这就是为什么做完相关系数分析后一定要画散点图看一眼。第二个是离群值绑架结果。有时候仅仅1-2个异常点就能把一个真实的负相关篡改成虚假的正相关。200个正常人加上2个极端数值皮尔逊相关系数可以瞬间从-0.3变成0.5。应对方式就是使用基于秩的相关系数比如斯皮尔曼。明白了这些底层的坑后面每种系数N你会自然理解为什么它存在、什么时候该用它。2. 12种相关系数逐一拆解——从经典到进阶这12种系数我按适用场景分成三个梯队。第一梯队经典四大家第二梯队二值数据与类别数据专用第三梯队非线性与分布无关的现代派。2.1 经典四大家皮尔逊、斯皮尔曼、肯德尔、四分相关皮尔逊相关系数Pearsons r适用前提两个变量都是连续变量近似正态分布且关系是线性的。它是“协方差归一化”的结果公式是r Cov(X,Y) / (σx · σy)本质上是把两个变量的线性共变程度除以各自离散程度的乘积。实际使用中最要命的坑是它完全不能抵抗离群值的影响。列一个典型的极端案例10个点拟合一条完美的直线r接近0.99此时如果把其中一个点的Y值改成比均值高30个标准差r可以瞬间跌到0.3甚至负值。我的建议是在计算皮尔逊之前永远先做两个动作。第一画散点图第二计算标准化残差把|Z|3的样本标记出来看看是不是录入错误。这一步在医学数据、经济数据里尤其重要因为这些领域的数据录入错误率远比你想象的高。斯皮尔曼秩相关系数Spearmans ρ它不关心数据的具体数值只关心数据的排名。X和Y各自排序后对排名计算皮尔逊相关系数。核心思想是如果说皮尔逊在寻找“线性伴侣”斯皮尔曼则在寻找“步调一致的舞伴”。这意味着三点好处不要求正态分布对离群值不敏感能捕捉单调非线性关系指数、对数等关系都能体现为正相关的秩关系。代价是它完全忽略数值间的实际距离。最常见的误用是把连续数据强行转成秩丢失了大量真实差异信息。肯德尔秩相关系数Kendalls τ和斯皮尔曼一样属于秩相关但计算逻辑是“一致对”与“不一致对”的比较。对于所有点对如果X升且Y升这对就叫concordant反之是discordant。τ (一致对数 - 不一致对数) / 总对数。因为它只比较相对顺序所以在数据中有大量并列结/tie时Kendall的结果比Spearman更稳健。在样本量小、离散程度高的问卷数据中Kendall的推荐优先级高于Spearman。四分相关Tetrachoric Correlation这是专门用来估计“隐藏的连续相关性”的系数。比如“患病/不患病”这个二分变量背后其实有一个连续潜伏变量“健康状况”。四分相关通过观测到的2×2列联表反推背后连续变量的相关系数。使用它的前提是二分变量背后确实存在正态分布的连续变量且切点是随机的。转录组学里gene表达量高低分组、医学里疾病有无都常用它。R中的tetrachoric()函数Python可以用tetrachoric这个库。2.2 二值数据与类别数据专用点双列、Phi系数、Cramers V、Goodman-Kruskal Gamma点双列相关Point-Biserial当一个变量是真正的二分变量如性别男/女、另一个是连续变量如身高时用点双列相关。它在数学上等价于皮尔逊只是针对一个二分变量做了数值编码0/1。有个细节很多人搞错点双列相关适用于“天然二分”的变量而二列相关Biserial适用于“人为二分”的背后有连续分布的变量。前者性别、是否吸烟用point-biserial后者成绩及格/不及格用biserial。Phi相关系数Φ当两个变量都是真正的二分变量时用Phi系数。它的本质是把2×2列联表的数据压缩成一个相关性指标。公式是Φ (AD - BC) / √[(AB)(CD)(AC)(BD)]。使用里比较容易忽略的点Phi系数的取值范围虽然理论上在-1到1之间但只有两个变量的边缘分布都是50/50时才能达到±1。如果一组是90/10的分布另一组是50/50Phi上限可能只有0.5左右。因此跨表比较Phi系数的大小需要谨慎。Cramers V这是Phi系数的泛化版本适用于两个多分类变量比如学历和购买偏好。它把Phi除以一个校正因子√(min(rows, cols) - 1)使得结果范围回到0到1之间。它的应用场景非常广市场研究的品牌偏好和年龄段、问卷里两道多选题之间的关联、人口特征与行为类别的关联。但注意Cramers V只能度量“关联程度”不能区分方向——因为类别变量本身没有方向语义。Goodman-Kruskal Gamma这个系数专注的是有序类别变量ordered categories之间的关联强度比如“满意度等级”低/中/高和“复购意愿等级”低/中/高这两个有序变量。它的计算逻辑和Kendall类似也基于一致对与不一致对但它忽略并列对因此在数据有大量结比如5级量表数据经常成堆得3分的时候Gamma对真实关联的估计更“乐观”但也更聚焦。2.3 非线性与分布无关的现代派距离相关、MIC、SOMD、Theils U距离相关Distance Correlation这是近年来在高维数据分析中越来越受重视的系数终于把“非线性关系”纳入了正规军。核心思路把变量X的样本点之间的距离矩阵和Y样本点之间的距离矩阵拿出来计算这两个距离矩阵之间的相关性。和皮尔逊最大的区别是距离相关等于0意味着两个变量是真·独立而皮尔逊等于0只能说明“没有线性关系”。在基因调控网络、金融时间序列、高维特征筛选里距离相关几乎是首选。R里用energy包的dcor()函数Python中用dcor库都非常方便。最大信息系数MIC, Maximal Information Coefficient它的理念是把两个变量的散点图用网格切分尝试不同数量的网格划分方案看哪种划分能最大程度地捕捉变量间的关系信息。MIC取值在0到1之间能捕捉非常复杂的函数关系包括正弦、周期性函数等。MIC在生物信息学里被广泛用于识别非线性的基因共表达模式在特征筛选里也很有用。在使用时要注意样本量不要太小最好n500否则MIC对噪声非常敏感。R中使用minerva包Python中用minepy。SOMDSummarization of Mutual Dependence这个相对小众但相当的实用。SOMD通过估计联合分布与边缘分布乘积之间的差异来度量依赖性本质上是一种基于信息论的依赖性度量。它的优势在于对有噪声的高维数据和复杂非单调关系依然稳健。我个人的使用体验是当数据量特别大百万级、特征维度特别多时SOMD的计算效率比MIC高一个量级。在做特征筛选的粗筛环节非常顺手先快速筛掉独立的特征再用更精细的方法做深入分析。Theils U不确定系数这是又一个信息论视角的相关系数度量的核心是已知X能多大程度降低Y的不确定性。如果X完全决定了Y数据在已知X后不再有不确定性U1如果X和Y无关U接近0。它和传统相关最本质的差别在于不对称性Theils UY|X和Theils UX|Y的值往往不一样。这点在因果推断的前置探索性分析中很好用——虽然U不对称不等于因果但它能帮你判断哪个方向的预测力更强。3. R和Python代码汇总——一行代码算出你要的系数工具代码这块我统一整理两个环境下的核心函数实操时直接套用即可。3.1 R语言环境下的代码速查基础包里的cor()和cor.test()就能覆盖最常用的几种。cor.test比cor多输出假设检验的P值实际报告里更推荐用这个。# 皮尔逊 cor.test(x, y, method pearson) # 斯皮尔曼 cor.test(x, y, method spearman) # 肯德尔 cor.test(x, y, method kendall) # 四分相关需安装polycor包 library(polycor) tetrachoric(table(x_binary, y_binary)) # 点双列相关双变量中一个是二分变量 library(ltm) biserial.cor(y_continuous, x_binary) # Phi系数和Cramers V library(vcd) assocstats(table(x_binary, y_binary)) # Goodman-Kruskal Gamma library(DescTools) GoodmanKruskalGamma(table(x_ordered, y_ordered)) # 距离相关 library(energy) dcor(x, y) dcor.test(x, y) # MIC library(minerva) mine(x, y)$MIC # 不确定系数 library(EntropyEstimation) LinEntropy(x)3.2 Python环境下的代码速查SciPy的stats模块覆盖了最常用的经典系数专门的dcor和minepy库则提供现代派系数适合做数据科学管道的同学。import numpy as np from scipy import stats import dcor # 皮尔逊 stats.pearsonr(x, y) # 斯皮尔曼 stats.spearmanr(x, y) # 肯德尔 stats.kendalltau(x, y) # 点双列本质是皮尔逊的快速实现 stats.pointbiserialr(x_binary, y_continuous) # Phi系数用卡方统计量换算 from scipy.stats import chi2_contingency chi2, p, dof, expected chi2_contingency(pd.crosstab(x, y)) n len(x) phi np.sqrt(chi2 / n) cramer_v np.sqrt(chi2 / (n * (min(crosstab.shape) - 1))) # 距离相关 import dcor dcor.distance_correlation(x, y) # MIC from minepy import MINE mine MINE() mine.compute_score(x, y) print(mine.mic())提示在跑任何相关系数之前先做一次数据的空值检查。NA值会导致cor()直接返回NA很多人的分析结果“不对”其实只是没有处理缺失值。4. 常见误区与选择实战——真正影响结果的几个坑看完了理论公式和代码最终要落到实际问题到底应该怎么选系数这里我从实际分析经验出发整理几个最常见的误区和选择参考。4.1 选错系数导致的“假结论”案例我见过不少实际业务分析里因为盲目使用皮尔逊得出跟真实情况完全相反的决策。举个简单案例某业务方研究“用户反馈次数”和“用户流失风险”的关系。数据里有几百个正常用户反馈1-5次的流失风险从中到低两者负相关。但有少数重度用户反馈次数在20次以上流失风险极高。把所有数据放进去算皮尔逊正相关0.6于是决策方得出结论“反馈越多越容易流失”。实际上把重度用户单独拎出来看反馈次数和流失风险依然是负相关。但皮尔逊被那几个离群点主导了全局结果。改用斯皮尔曼或者Kendall秩次不会被极端值扭曲结论就反过来了反馈越多流失风险越低。这个案例说明散点图和秩相关是先于皮尔逊的必要步骤。4.2 样本量对“显著性”的欺骗性一个特别容易被忽视的事实是当样本量足够大时任何微小的相关系数都可能“统计显著”但实际效应小到可以忽略。n10000时r0.02也能算出p0.05这在业务含义上毫无意义。报告相关系数时务必同时报告效应量r本身的大小和置信区间不要只揪住p值不放。样本量越大p值越无意义r的绝对值大小才是更值得关注的指标。4.3 系数选择实战速查表为了让你在具体场景里能快速做决定我把选择逻辑整理成一个速查表数据类型推荐系数不推荐连续连续线性正态皮尔逊斯皮尔曼会丢失数值信息连续连续线性偏态/离群值斯皮尔曼皮尔逊连续连续非线性但有单调趋势斯皮尔曼/Kendall皮尔逊会严重低估连续连续非线性且非单调U型/周期距离相关/MIC皮尔逊、斯皮尔曼二分自然连续点双列皮尔逊不适用二分人为连续二列相关点双列会低估二分二分Phi皮尔逊无序多分类无序多分类Cramers VPhi数值偏小有序多分类有序多分类Goodman-Kruskal Gamma皮尔逊连续多个变量筛选用距离相关/MIC粗筛单独皮尔逊4.4 相关性不等于因果性——老生常谈但永远有人踩这一点每篇讲相关的文章都会提但在实际分析流程里依然是被忽视的最严重问题。冰激凌销量和溺水人数高度正相关皮尔逊、斯皮尔曼、距离相关都能算出显著结果但它们都是“气温”这个混杂因素的影子。做相关性分析时报告里一定需要明确说明背景和潜在混杂因素。尤其在做特征工程时两个特征高度相关往往不是因为其中一个“导致”另一个而是它们都是同一个隐藏因素的产物。这时候做特征选择不应该随意删掉其中一个而是要理解底层逻辑再决定是保留还是合并。5. 实操心得我做了这么多年分析几点过来人的建议最后说一些真正从项目里打磨出来的体会不写报告的朋友可能不太会留意到这些细节。第一散点图矩阵永远是第一步。哪怕你笃定就用皮尔逊也先画一遍图。有时候你以为的“线性关系”视觉上一看根本是分段关系或抛物线关系。图比任何系数都诚实。第二单个相关系数只是故事的一半置信区间是另一半。样本量小的时候相关系数的点估计方差极大。n20r0.5的95%置信区间大概在0.1到0.77之间这种“显著”并不说明效应的精确度很高。报告时带上CI是专业分析师和业余跑数人的分水岭。第三多变量场景下使用偏相关。当你要研究X和Y的相关性但存在明确的混杂变量Z时直接算X和Y的相关系数得到的结果会混入Z的影响。偏相关partial correlation控制了Z之后计算X和Y的净相关关系。R语言用ppcor包Python用pingouin的partial_corr方法。第四遇到离群值不要机械地剔除。先理解离群值为什么存在——是录入错误是真实的小众群体还是数据生成机制发生了改变机械剔除离群值有时会把最有趣的信息删掉。我一般会同时汇报“含离群值”和“剔除离群值”两个结果让读者自己判断。最后再分享一个小技巧在做相关系数矩阵时不建议一次性把所有变量都塞进去一股脑算出几十个系数而是分层计算——先算核心自变量和因变量的单相关再做偏相关控制混杂因素最后才做特征间的相关矩阵。这样做的原因是避免被大量的虚假相关淹没判断力聚焦在真正重要的关系上。相关系数这个工具箱远不止皮尔逊一种。真正理解每种系数背后的度量逻辑并在适当的场景用适当的工具才能在数据分析里少走弯路。希望这篇汇总能让你在下次面对“算相关性”的需求时不再只是机械地调用cor()而是能自信地说出“这里的数据结构适合用XX系数”。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →