
1. 从皮尔逊到斯皮尔曼为什么我们需要另一种相关系数在数学建模和数据分析的实战里判断两个变量之间有没有关系、关系有多强是绕不开的基础操作。一提到相关性分析很多人第一个想到的就是皮尔逊相关系数。确实皮尔逊相关系数Pearson correlation coefficient太经典了它衡量的是两个连续变量之间的线性相关程度计算直接意义明确。但正是这种“线性”和“连续”的假设在实际数据面前常常会碰壁。我遇到过不少这样的案例比如分析一个地区的人均收入与幸福感评分的关系。收入数据是具体的数值但幸福感评分往往是1到10的等级数据。又比如在研究广告投放时长与用户点击意愿的关系时点击意愿我们用“强烈反对、反对、中立、赞同、强烈赞同”这样的有序等级来衡量。这些数据有一个共同特点它们不是严格意义上的连续数值而是有序的等级Rank。更棘手的情况是当收入与幸福感的关系图呈现出一条明显的上升曲线但并非直线时皮尔逊系数可能会因为个别极端的高收入高幸福感数据点而产生偏差给出一个看似不高但实际上趋势非常明确的相关性估计。这时斯皮尔曼等级相关系数Spearmans rank correlation coefficient的价值就凸显出来了。它不关心变量的具体数值是多少只关心它们的“排位”。计算斯皮尔曼相关系数时我们会先将两列原始数据分别转换成等级序号排名然后计算这两个排名序列之间的皮尔逊相关系数。正因为这个特性斯皮尔曼相关系数也被称为“等级相关系数”。它的核心优势在于对数据的要求非常宽松不要求变量是连续的正态分布数据只要求至少是有序的。无论是连续数据、离散数据还是等级数据只要能排出顺序它就能用。同时它对异常值Outliers也不像皮尔逊系数那么敏感因为异常值在转换为排名后其影响力被大大削弱了比如一个极大值排第一和第二对整体排名序列的影响是有限的。所以简单来说当你面对的数据不符合正态分布、存在异常值、或者本身就是等级/次序数据时斯皮尔曼相关系数就是你工具箱里更合适的那个工具。它探寻的是两个变量之间单调关系的强弱即一个变量增加时另一个变量倾向于增加或减少但不一定是按固定斜率的直线增加。在数学建模竞赛中对于社会经济、心理调查、满意度评价这类常见的数据类型斯皮尔曼相关系数的出场率往往比皮尔逊还要高。2. 斯皮尔曼相关系数的计算原理与公式拆解理解了为什么需要斯皮尔曼系数我们再来深入看看它是怎么算出来的。知其然更要知其所以然这能帮助我们在使用软件如MATLAB直接得出结果时也能理解背后的含义甚至在需要时进行手动验算。斯皮尔曼相关系数记为 ρ读作“rho”或 rs。其定义是两个变量的等级序列之间的皮尔逊相关系数。假设我们有 n 对观测数据 (X_i, Y_i)i1,2,...,n。计算步骤如下2.1 第一步数据转换赋予等级这是最关键的一步。分别对 X 和 Y 这两列数据单独进行排序并赋予它们等级Rank。排序规则通常是从小到大排列。最小的值等级为1次小的等级为2以此类推。处理并列值Ties如果出现相同的数值则取它们所占位置的平均等级。例如如果第二和第三名的数值相同则它们的等级都是 (23)/2 2.5。假设我们有一组简单的数据学生数学成绩 (X)物理成绩 (Y)A8590B9288C7875D9295E8582对数学成绩X排序78(1), 85(2), 85(3), 92(4), 92(5)。因为有并列85有两个等级取(23)/22.592有两个等级取(45)/24.5。所以X的等级序列 R_X 为[2.5, 4.5, 1, 4.5, 2.5]。 对物理成绩Y排序75(1), 82(2), 88(3), 90(4), 95(5)。没有并列所以Y的等级序列 R_Y 为[4, 3, 1, 5, 2]。2.2 第二步计算等级差计算每一对观测值等级之差 d_i R_Xi - R_Yi。 根据上面的例子 d [2.5-4, 4.5-3, 1-1, 4.5-5, 2.5-2] [-1.5, 1.5, 0, -0.5, 0.5]2.3 第三步套用斯皮尔曼公式最常用的计算公式是基于等级差平方和的 rs 1 - [ 6 * Σ(d_i^2) ] / [ n * (n^2 - 1) ]其中Σ(d_i^2) 是所有等级差 d_i 的平方和。在我们的例子中 Σ(d_i^2) (-1.5)^2 (1.5)^2 (0)^2 (-0.5)^2 (0.5)^2 2.25 2.25 0 0.25 0.25 5 n 5 代入公式rs 1 - [6 * 5] / [5 * (25 - 1)] 1 - 30 / (5*24) 1 - 30/120 1 - 0.25 0.75这个公式是当没有并列等级时的一个简化特例。如果存在并列等级就像我们例子中的X变量使用这个简化公式会引入误差。更通用、更准确的方法是直接计算两个等级序列 R_X 和 R_Y 的皮尔逊相关系数。MATLAB等软件内部正是采用这种通用方法。2.4 第四步理解计算结果斯皮尔曼相关系数 rs 的取值范围也是 [-1, 1]。rs 1表示两个变量的等级完全一致存在完美的单调递增关系。即X的排名越高Y的排名也越高。rs -1表示两个变量的等级完全相反存在完美的单调递减关系。即X的排名越高Y的排名越低。rs 0表示两个变量的等级之间没有单调关系。但这不代表完全没有关系可能存在复杂的非单调关系。rs 0.75如我们的例子表示数学和物理成绩的排名之间存在较强的正相关趋势。成绩排名靠前的学生在两门课上排名都倾向于靠前。注意斯皮尔曼相关系数衡量的是单调关系而非线性关系。即使两者关系是一条曲线如指数、对数只要方向一致同增或同减斯皮尔曼系数就能捕捉到并给出较高的值。这是它与皮尔逊系数的根本区别之一。3. 在MATLAB中实现斯皮尔曼相关分析与假设检验理论清楚了我们来看如何在数学建模最常用的工具之一——MATLAB中实操。MATLAB提供了非常方便的函数一键就能完成计算和显著性检验。3.1 核心函数corr函数在MATLAB中计算各种相关系数的主力函数是corr。其基本语法是R corr(X, Y, ‘type’, ‘Spearman’)X和Y是输入向量或矩阵。如果是矩阵则会计算所有列之间的相关系数矩阵。‘type’, ‘Spearman’这个参数对指定了计算斯皮尔曼等级相关系数。如果不指定默认是‘Pearson’。让我们用上一节的例子来演示% 定义数据 math_scores [85, 92, 78, 92, 85]; % 数学成绩转置为列向量 physics_scores [90, 88, 75, 95, 82]; % 物理成绩 % 计算斯皮尔曼相关系数 r_s corr(math_scores, physics_scores, ‘type‘, ‘Spearman‘)运行后r_s的值应该就是 0.75。这与我们手动计算的结果一致。3.2 获取显著性检验的P值在数学建模中仅仅算出相关系数是不够的。我们必须要问这个相关性是真实存在的还是仅仅由于随机抽样误差导致的这就需要用到假设检验。 MATLAB的corr函数可以同时返回P值[R, P] corr(X, Y, ‘type’, ‘Spearman’)R是相关系数矩阵。P是对应的P值矩阵。P值表示在原假设H0两个变量不相关即总体斯皮尔曼相关系数为0成立的情况下观察到当前样本相关系数或更极端情况的概率。通常我们设定一个显著性水平 α常见为0.05或0.01如果P α则拒绝原假设认为相关系数是显著的即两个变量在统计上存在显著的相关关系。如果P α则没有足够证据拒绝原假设不能认为相关性显著。接上例[r_s, p_value] corr(math_scores, physics_scores, ‘type‘, ‘Spearman‘); fprintf(‘斯皮尔曼相关系数 rs %.4f\n‘, r_s); fprintf(‘显著性P值 %.4f\n‘, p_value); if p_value 0.05 fprintf(‘在0.05水平上相关性显著。\n‘); else fprintf(‘在0.05水平上相关性不显著。\n‘); end对于只有5个样本的小数据P值很可能大于0.05这说明尽管我们算出了0.75的相关系数但由于样本量太小这个结果在统计上并不可靠。这提醒我们在解读相关系数时必须结合P值和样本量一起看。一个绝对值很大的相关系数如果来自一个很小的样本其统计意义可能并不大。3.3 处理多变量与可视化相关系数矩阵与热图实际建模中我们常常要分析多个变量两两之间的斯皮尔曼相关性。这时将数据组织成矩阵形式corr函数会直接返回相关系数矩阵R和 P值矩阵P。% 假设我们有4个变量数学、物理、化学、生物成绩每个变量有20个样本 data randn(20, 4); % 这里用随机数生成示例数据实际替换为自己的数据矩阵 [R, P] corr(data, ‘type‘, ‘Spearman‘); % 显示相关系数矩阵 disp(‘斯皮尔曼相关系数矩阵 R:‘); disp(R); disp(‘显著性P值矩阵 P:‘); disp(P);为了更直观地展示我们可以绘制相关系数矩阵的热图Heatmapfigure; imagesc(R); % 绘制图像 colorbar; % 显示颜色条 title(‘斯皮尔曼相关系数矩阵热图‘); % 添加坐标轴标签假设变量名称为{‘Math‘, ‘Physics‘, ‘Chemistry‘, ‘Biology‘} xticks(1:4); xticklabels({‘Math‘, ‘Physics‘, ‘Chemistry‘, ‘Biology‘}); yticks(1:4); yticklabels({‘Math‘, ‘Physics‘, ‘Chemistry‘, ‘Biology‘}); % 在图上添加相关系数数值 textStrings num2str(R(:), ‘%.2f‘); % 将矩阵数值转换为字符串保留两位小数 textStrings strtrim(cellstr(textStrings)); % 去除空格并转为元胞数组 [x, y] meshgrid(1:4, 1:4); % 创建坐标网格 hStrings text(x(:), y(:), textStrings(:), … % 在网格位置添加文本 ‘HorizontalAlignment‘, ‘center‘, ‘FontWeight‘, ‘bold‘); % 根据数值大小设置文本颜色深色背景用白色字浅色背景用黑色字 textColors repmat(R(:) 0.5, 1, 3); % 假设以0.5为阈值 set(hStrings, {‘Color‘}, num2cell(textColors, 2)); % 设置颜色这样的热图能让评委或读者一眼就看出哪些变量之间正相关强深色哪些负相关强浅色哪些关系弱。实操心得在计算大量变量的相关系数矩阵时corr函数可能会因为内存或计算量而变慢。对于超大型数据集可以考虑先抽样或使用更高效的算法包。另外绘制热图时使用clim([-1 1])可以固定颜色轴的范围使得不同图表之间的颜色对比具有一致性。4. 数学建模实战从数据预处理到结果解读的全流程在数学建模竞赛中应用斯皮尔曼相关系数绝不是简单地调用一个函数。它嵌入在一个完整的数据分析流程中。下面我们以一个模拟的赛题场景为例走通整个流程。4.1 场景设定与数据探索假设我们遇到这样一个问题“探究城市各类环境指标如PM2.5浓度、绿化率、噪音水平与居民健康自评分数之间的关系”。我们收集了50个城市的数据。因变量Y居民健康自评分数1-10分有序等级。自变量XPM2.5年均浓度连续数值可能存在极端值、城市绿化覆盖率连续百分比、平均噪音分贝连续数值。首先进行数据导入和初步观察% 假设数据已保存在CSV文件‘city_health_data.csv‘中列顺序为City, PM25, GreenRate, Noise, HealthScore data readtable(‘city_health_data.csv‘); % 查看数据摘要检查缺失值和分布 summary(data); % 绘制数据分布直方图 figure; subplot(2,2,1); histogram(data.PM25); title(‘PM2.5分布‘); subplot(2,2,2); histogram(data.GreenRate); title(‘绿化率分布‘); subplot(2,2,3); histogram(data.Noise); title(‘噪音分布‘); subplot(2,2,4); histogram(data.HealthScore); title(‘健康评分分布‘);通过直方图我们可能发现PM2.5数据有右偏少数城市污染很重健康评分是离散的等级数据。这初步提示皮尔逊相关系数可能不是最佳选择。4.2 选择斯皮尔曼相关系数的理由论证在模型建立或分析部分我们需要书面化地陈述选择斯皮尔曼而非皮尔逊的理由。这体现了建模的严谨性。可以这样写 “本研究中的因变量‘居民健康自评分数’为1-10的有序等级数据不符合连续变量及正态分布的前提假设。部分自变量如PM2.5浓度的分布存在右偏可能含有极端值。皮尔逊相关系数对数据的正态性和线性关系要求严格且在存在异常值时稳定性较差。因此为更稳健地衡量各环境指标与健康评分之间的单调关联趋势本研究采用基于变量排名的斯皮尔曼等级相关系数进行分析。”4.3 执行相关分析并呈现结果计算所有变量两两之间的斯皮尔曼相关系数及显著性% 提取数值变量列 X [data.PM25, data.GreenRate, data.Noise]; Y data.HealthScore; % 计算与健康评分(Y)的相关性 [r_xy, p_xy] corr(X, Y, ‘type‘, ‘Spearman‘); fprintf(‘与健康评分的斯皮尔曼相关性分析\n‘); varNames {‘PM2.5‘, ‘绿化率‘, ‘噪音‘}; for i 1:3 fprintf(‘%s: rs %.3f, p %.4f‘, varNames{i}, r_xy(i), p_xy(i)); if p_xy(i) 0.01 fprintf(‘ **‘); % 用**表示在0.01水平显著 elseif p_xy(i) 0.05 fprintf(‘ *‘); % 用*表示在0.05水平显著 end fprintf(‘\n‘); end % 计算所有自变量之间的相关系数矩阵用于检查多重共线性 [R_xx, P_xx] corr(X, ‘type‘, ‘Spearman‘); figure; heatmap(varNames, varNames, R_xx, ‘Colormap‘, parula, ‘ColorLimits‘, [-1 1]); title(‘环境指标间斯皮尔曼相关系数‘);4.4 结果解读与建模启示假设我们得到如下结果PM2.5与健康评分rs -0.62, p 0.01绿化率与健康评分rs 0.48, p 0.01噪音与健康评分rs -0.35, p 0.05如何解读方向与强度PM2.5与健康评分呈显著的负相关rs-0.62。系数为负意味着PM2.5排名越高的城市污染越重其居民健康评分排名倾向于越低健康自评越差。绝对值0.62表明这是一种中等偏强的单调关系。绿化率与健康评分呈显著的正相关rs0.48即绿化率越高健康评分倾向于越高。噪音也是显著的负相关但关系相对较弱rs-0.35。统计显著性三个p值均小于0.05说明这些相关性不太可能是偶然产生的具有统计学意义。对后续建模的指导这些分析为后续的回归建模提供了重要依据。例如我们可以尝试建立健康评分Y关于PM2.5、绿化率、噪音X的有序逻辑回归Ordinal Logistic Regression模型因为Y是有序分类变量。斯皮尔曼相关分析的结果帮助我们确认了这些自变量与Y之间存在显著的单调关系值得放入模型。同时通过检查自变量间的相关系数矩阵R_xx如果发现某两个自变量之间高度相关例如|rs|0.8则需要警惕多重共线性问题考虑剔除其中一个或使用主成分分析等方法处理。避坑指南一个常见的错误是看到显著的斯皮尔曼相关系数就直接断言“A导致B”。相关性不等于因果性。城市绿化率高可能意味着该城市经济更发达、医疗条件更好这些才是影响健康评分的真正原因。在建模论文中解读时应使用“关联”、“相关”等词汇谨慎推断因果关系。若要论证因果需要更复杂的模型设计如格兰杰因果检验、工具变量法等或严谨的实证研究设计。5. 进阶讨论与皮尔逊系数的对比、检验效力与软件实现细节掌握了基本应用后我们还需要深入一些细节这能让你在建模论文中展现出更深厚的功底。5.1 斯皮尔曼 vs. 皮尔逊何时用哪个这是一个永恒的问题。我们可以通过一个简单的模拟来直观感受两者的区别。% 生成非线性但单调的数据y x^2 噪声 x 1:0.5:10; y x.^2 randn(size(x))*10; % 加入随机噪声 % 计算两种相关系数 r_pearson corr(x‘, y‘, ‘type‘, ‘Pearson‘); r_spearman corr(x‘, y‘, ‘type‘, ‘Spearman‘); figure; scatter(x, y, ‘filled‘); title(sprintf(‘非线性单调关系\\n皮尔逊: %.3f, 斯皮尔曼: %.3f‘, r_pearson, r_spearman)); xlabel(‘X‘); ylabel(‘Y‘);你会发现对于这种二次函数关系斯皮尔曼相关系数仍然接近1完美的单调关系而皮尔逊系数可能会低很多因为它试图用一条直线去拟合曲线效果自然不好。决策流程可以总结如下如果数据是连续的且通过散点图观察大致呈线性关系残差近似正态分布那么皮尔逊系数是首选因为它能提供关于线性关系强度和方向的无偏估计。如果数据是有序分类等级、分布明显非正态偏态、存在极端异常值、或者怀疑存在单调但非线性的关系如指数、对数关系那么斯皮尔曼系数是更稳健、更合适的选择。在数学建模中如果不确定一种稳妥的做法是两者都计算并对比。如果两者结果相差不大说明数据关系接近线性使用哪个都可以如果斯皮尔曼系数绝对值明显大于皮尔逊系数则提示存在较强的非线性单调关系报告中应以斯皮尔曼系数为准。5.2 假设检验的底层原理与样本量考量斯皮尔曼相关系数的显著性检验其原假设 H0 是两个变量的总体等级之间不存在单调关联即总体斯皮尔曼相关系数为0。当样本量 n 较大时通常 n30检验统计量近似服从 t 分布 t rs * sqrt( (n-2) / (1 - rs^2) ) 自由度为 df n-2。然后根据 t 值和自由度计算 P 值。这就是MATLAB中corr函数计算P值的基础原理之一。样本量 n 对结果的影响巨大小样本如 n10即使真实的总体相关性很强也可能因为随机波动而无法检测到显著性P值很大。反之也可能由于偶然得到一个较大的 rs 和显著的 P 值假阳性。因此对小样本结果要格外谨慎下结论要保守。大样本如 n500即使非常微弱的、实际意义不大的相关性如 rs0.05也可能因为样本量巨大而呈现出极高的统计显著性P值极小。这时不能只看P值必须结合相关系数 rs 的大小来判断关联的实际强度。一个 rs0.05 的相关性即使P值小于0.001在实际应用中也几乎可以忽略不计。在建模论文中报告结果时务必同时给出相关系数 rs 和 P 值并注明样本量 n。5.3 MATLAB实现中的细节与替代函数除了corr函数MATLAB统计工具箱中还有corrcoef函数但它主要计算皮尔逊相关系数对斯皮尔曼的支持不如corr直接。对于没有并列等级的数据你也可以手动实现简化公式来验证function r_s my_spearman(x, y) % 手动计算斯皮尔曼相关系数简化版未处理并列值 n length(x); [~, rank_x] sort(x); [~, rank_y] sort(y); d rank_x - rank_y; r_s 1 - 6 * sum(d.^2) / (n * (n^2 - 1)); end但强烈建议使用corr函数因为它内置了处理并列值的通用算法并且经过了充分优化和测试。另一个有用的函数是partialcorr用于计算偏斯皮尔曼相关系数。它衡量的是在控制了一个或多个其他变量影响后两个变量之间的等级相关。这在多变量分析中非常有用可以排除混淆因素的影响。例如我们想探究绿化率与健康评分的关系但怀疑这种关系可能是由城市经济水平GDP驱动的因为经济好的城市绿化好、医疗也好。我们就可以计算控制GDP后的偏斯皮尔曼相关系数% 假设 data 中包含 GreenRate, HealthScore, GDP 三列 partial_rs partialcorr(data{:, {‘GreenRate‘, ‘HealthScore‘}}, data.GDP, ‘type‘, ‘Spearman‘);如果控制GDP后偏相关系数partial_rs变得很小且不显著那么说明绿化率与健康评分的简单相关可能主要是由GDP这个共同原因造成的虚假相关。6. 在综合建模中的应用结合回归、聚类与路径分析斯皮尔曼相关系数很少孤立使用。在复杂的数学建模中它常常是探索性数据分析EDA的第一步为后续更高级的模型提供线索和依据。6.1 作为回归模型的前哨站在建立多元回归模型特别是线性回归之前进行变量间的斯皮尔曼相关分析是标准操作。其主要目的有两个筛选自变量与因变量斯皮尔曼相关系数过低且不显著的变量可以考虑剔除以简化模型。诊断多重共线性如果两个自变量之间的斯皮尔曼相关系数绝对值过高例如 0.8它们很可能在回归模型中引发严重的多重共线性问题导致系数估计不稳定、标准误膨胀。此时需要采取措施如剔除其中一个、合并变量或使用岭回归等正则化方法。6.2 辅助聚类分析的特征选择在进行聚类分析如K-means时我们通常希望用于计算距离的特征之间相关性较低。高度相关的特征会给它们代表的“维度”赋予过高的权重扭曲聚类结果。因此在聚类前可以计算特征间的斯皮尔曼相关系数矩阵。对于相关系数极高的一对特征可以考虑只保留其中一个或者使用主成分分析PCA将相关特征转换为一组不相关的主成分后再进行聚类。6.3 路径分析Path Analysis与结构方程模型SEM的初步检验在探索变量间复杂因果关系的路径分析或SEM中斯皮尔曼相关系数矩阵可以作为输入的基础关联矩阵当数据不满足多元正态分布时使用斯皮尔曼相关矩阵比皮尔逊相关矩阵更稳健。模型估计出的路径系数需要能够在一定程度上“复现”或“解释”这个观测到的相关矩阵。如果模型拟合后发现根据模型推导出的变量间相关系数与实际计算的斯皮尔曼相关系数相差甚远则说明模型设定可能有问题。6.4 实例一个整合的工作流假设我们在“城市可持续发展评估”模型中有十几个潜在指标。一个完整的工作流可能是数据清洗与描述处理缺失值观察各指标分布。斯皮尔曼相关分析计算所有指标两两之间的相关系数绘制热图。降维与分组根据相关热图将高度相关的指标归类如“经济类”、“环境类”、“社会类”。从每一类中选出一个代表性指标或对每一类进行主成分分析提取主成分。建立综合模型使用筛选或转换后的不相关/弱相关指标构建综合评价模型如熵权法、TOPSIS或预测模型。模型验证将模型结果如综合得分与某个关键外部变量如专家评分做斯皮尔曼相关分析验证模型的有效性。在整个过程中斯皮尔曼相关系数像一把瑞士军刀从最初的探索到中间的诊断再到最后的验证都发挥着简洁而重要的作用。它不追求复杂的数学形式而是直指数据间最本质的单调关联为更复杂的建模任务铺平道路。真正掌握它意味着你能在纷繁的数据中快速抓住主要矛盾为整个数学建模项目建立一个坚实可靠的起点。