
简介面向数学建模参赛者与数据分析初学者MATLAB相关性分析资源包聚焦皮尔逊与斯皮尔曼两种常用相关系数的计算与可视化。包内共11个文件含3个m脚本实现相关系数计算与热力图绘制3个xls和1个xlsx体测数据集包含八年级男女生体测数据用于实操演练2个mat数据文件提供中间处理结果另有docx临界值表和jpg效果图供判断显著性与对照参考。压缩包仅194KB轻量易下载目前已有2407人学习使用。通过源码、示例数据与说明文档读者可快速掌握相关性分析完整流程从数据导入、相关性计算、显著性检验到热力图呈现并理解斯皮尔曼秩相关系数在非正态分布或存在离群值时的适用优势。代码注释清晰、结构紧凑适合在数学建模备赛或课程作业中直接复用与扩展。1. MATLAB相关性分析从相关系数选型到建模落地的完整解读建模之前先做相关性分析听着像是多此一举实际上能把后面特征筛选、回归建模的坑提前排掉大半。相关系数回答的是“两个变量是否同步变化、方向如何、强度多大”但回答不了“谁导致谁”这个边界一开始就要立住。在MATLAB里做相关性分析数学建模最大优势是corr、corrcoef、partialcorr这套函数族能一站走完矩阵计算、显著性和可视化不用在多个工具之间来回倒腾。适合备战数学建模、做数据预研和特征筛选的动手型选手新手按步骤能出结果熟手可以在参数细节和稳健性验证上再做文章。2. 相关性分析的原理与选型三种相关系数在MATLAB中的使用边界2.1 皮尔逊、斯皮尔曼、肯德尔只会调用corr选错类型等于白算数学建模里最常用的是皮尔逊相关系数默认数据之间存在线性关系并且最好近似正态。它的计算本质是协方差除以两个变量的标准差乘积取值范围在[-1,1]之间。|r|越接近1线性趋势越强r为负代表方向相反。但在实际数据里“线性关系”这个前提经常不成立油气藏压力曲线、经济数据的边际递减效应、生物实验的剂量响应都容易呈现出单调但非线性的形态。这时继续用皮尔逊系数结果会严重偏小甚至接近0造成“两个变量无关”的错误结论。MATLAB里计算相关系数的主入口是corr函数两个变量的简单版本如下x [1, 2, 3, 4, 5]; y [2, 4, 5, 7, 9]; % Pearson相关系数同时输出p值 [r, p] corr(x, y, Type, Pearson); fprintf(r %.3f, p %.3f\n, r, p);这里corr返回的第一个输出r是相关系数标量第二个输出p是显著性概率。p值对应的原假设是“总体相关系数为0”p小于0.05一般就认为相关关系在统计上成立。Type参数的三个枚举值值得记牢Pearson是默认值对线性关系敏感Spearman先把数据排序成秩次再做相关Kendall用样本对之间的一致性来估计对样本量小和并列等级多的情况更稳。spearman版本的调用几乎一样只是换Type% Spearman秩相关注意这里输出的是rho [rho, pval] corr(x, y, Type, Spearman); fprintf(rho %.3f, pval %.3f\n, rho, pval);我一般会同时看散点图再做选择。画出来是直线趋势用Pearson画出来是单调曲线用Spearman数据里等级关系明显、又有大量并列值用Kendall。三者的适用场景差异可以压成一张表放在手边比记函数签名更实用相关系数数据形态要求对异常值敏感度MATLAB对应TypePearson线性、近似正态、连续变量高单个极端值可能主导结果PearsonSpearman单调关系即可不要求正态低基于秩次SpearmanKendall等级数据允许大量并列低基于样本对一致性Kendall系数本身能给你一个数值问题在于多数人只拿这个数值当结论忽略了三个隐藏信息一是相关系数的置信区间还没算小样本下r0.7可能并不可靠二是p值在样本量过万时会变得过于敏感三是变量之间的“伪相关”可能是由第三个变量同时驱动造成的。这三类问题放在第4章逐条展开先继续把数据准备工作做扎实。2.2 数据清洗不能跳缺失值和类型错乱会让corr直接翻车相关性计算的输入必须是一个数值矩阵或者两个等长的数值列向量。常见做法是拿到数据后先用readtable或readmatrix读进来接着立刻检查数据类型和缺失值。直接整个表丢给corr的写法遇到文本列会报错遇到NaN会默认按“整行删除”处理数据量大的时候删掉的行可能直接改变结论走向。下面这一段是我处理“某公司销售数据”时的固定起手式假设csv文件里混着地区名、日期这类非数值列% 读取原始表注意readtable会自动把文本列识别为cell或string T readtable(survey_data.csv); % 找出所有数值列isnumeric对double有效table里还要结合varfun numFlag varfun(isnumeric, T, OutputFormat, uniform); dataMat T{:, numFlag}; % 删除包含NaN的行得到干净矩阵 dataMat rmmissing(dataMat); fprintf(有效样本量: %d\n, size(dataMat, 1));逻辑说明varfun会把isnumeric逐个作用到每一列返回一个逻辑向量然后用逻辑索引把数值列从table里提出来这样地区名、编号这类列不会进入相关分析。rmmissing删除的是任何一列出现NaN的行保证后面corr不会因为缺失值反复报警。值得留意的是rmmissing会把行数默默改小如果删除比例超过20%应该回头看原始数据为什么缺这么多而不是直接往下跑。参数与边界说明readtable在遇到空单元格时会自动填NaN这对后续处理其实是友好的但excel文件里若混有“—”、“N/A”这类非空文本MATLAB会把它解释成字符串导致整列不再是数值型。我一般会补充一句强制转换把明显是数字的文本列转回来写法是dataMat str2double(T{:, idx});转出来出现NaN就说明原表里有脏数据再去源文件里定位。还有一个长期被忽略的点相关系数具有“尺度不变性”对x、y同时做线性变换不会改变r值所以标准化、归一化在相关分析里不是必选项。需要标准化的场景是后续要把多个变量放进回归或聚类而不是计算相关系数这一步。数据清洗做完下一步就可以放心构建相关矩阵了。3. 用MATLAB建立相关性分析模型从矩阵计算到变量筛选的可复现流程3.1 一次性输出相关矩阵和显著性检验corr与corrplot的组合用法当变量不止两个时逐个算corr太低效。正确的是直接把整个数值矩阵交给corr它会返回一个对称的相关矩阵R和同尺寸的p值矩阵P。R的第i行第j列就是第i个变量和第j个变量的相关系数P里面对应位置是显著性p值。行和列的顺序与输入矩阵的列顺序一致所以最好在计算前先给变量命名方便阅读结果。% 假设dataMat是100行8列的数值矩阵8个变量 [R, P] corr(dataMat, Rows, complete); % 把矩阵打印成3位小数方便截图和写报告 disp(相关系数矩阵:); disp(round(R, 3)); disp(p值矩阵:); disp(round(P, 3));逻辑说明corr同时计算两两变量之间的相关系数和显著性R的对角线永远是1因为每个变量和自身完全相关。P矩阵对角线是0因为自身相关的p值没有意义。Rows取值为complete时只有当某一行在所有变量上都非空才会参与计算改成pairwise则每对变量各自使用非缺失的样本。这两个选项差异很大细节放在4.4里讲。可视化环节corrplot是最直观的出口。它能在下三角画散点图、上三角填色块表示相关系数强度对角线写变量分布。指定TestR为on时还会在显著相关的格子上打星号这在建模报告里非常好用。% 为变量命名方便corrplot显示 varNames {X1,X2,X3,X4,X5,X6,X7,y}; figure; corrplot(dataMat, varNames, varNames, TestR, on);参数说明TestR选项会在相关系数显著默认alpha0.05的格子标记显著性。corrplot内部做的是单变量相关性检验没有做多重比较校正当变量数超过10个时星号容易偏多这时更适合自己画热力图并配合后续的校正方法。另外如果变量量纲差异极大比如一列是“元”一列是“人数”散点图看起来会压扁不影响相关系数计算但影响人眼判断可以先对显示用的数据做标准化再画。从结果解读角度我不建议一上来就盯绝对值大于0.8的“强相关”。从建模经验看相关系数在0.3到0.6之间的变量组合反而更常见——它们说明变量“有贡献但不冗余”。如果两个自变量之间的r高达0.9后续回归会出现严重共线性这一点在3.2里必须用VIF兜住。3.2 把相关矩阵转成建模依据特征筛选与VIF双重确认相关性分析的最终目的是辅助建模不是停在“谁和谁有关系”这个描述层面。我把常见套路总结为三步先用相关矩阵找出与目标变量y显著相关的候选特征再检查这些候选特征彼此之间是否高度相关最后用方差膨胀因子VIF确认共线性风险。% 假设dataMat的最后一列是目标变量y X dataMat(:, 1:end-1); y dataMat(:, end); % 候选筛选找出与y相关系数绝对值大于0.3的自变量 [R, P] corr(X, y); candidateIdx find(abs(R) 0.3 P 0.05); fprintf(候选特征个数: %d\n, length(candidateIdx));逻辑说明这里是把X的每一列和y单独做相关得到的R是列向量。筛选条件是“相关系数绝对值超过0.3且p值小于0.05”这个阈值没有绝对标准样本量小时可以降低到0.2样本量大时建议提高到0.4依据是不要让大量弱相关变量进入后续模型。接着是共线性检查。两个候选特征之间的相关系数一旦超过0.8就要考虑只保留其中一个。更正式的做法是计算VIF公式是VIF_j 1 / (1 - R_j^2)其中R_j是把第j个自变量作为因变量、其余自变量做回归得到的决定系数。MATLAB没有一键VIF函数但可以用corrcoef加inv实现% 对候选特征矩阵计算相关系数矩阵再取逆 Xi X(:, candidateIdx); C corrcoef(Xi); VIF diag(inv(C)); % 展示每个候选特征的VIF for i 1:length(VIF) fprintf(特征 %d 的VIF %.2f\n, candidateIdx(i), VIF(i)); end逻辑说明相关系数矩阵取逆后对角线的值恰好是每个变量的VIF。这是线性代数里的既有结论不需要自己逐步回归去逼近。参数经验线上VIF大于10的特征一般直接剔除5到10之间需要结合业务判断VIF小于5可以放心进入模型。如果VIF超标的特征确实有业务价值优先考虑两两相关更高的那个删掉而不是强行同时保留。到这一步相关性分析已经从“描述关系”变成了“筛选建模变量”下一步的回归模型会有更稳的输入。fitlm可以快速验证一下变量组合的拟合效果% 用筛选出的特征建立线性模型 mdl fitlm(Xi, y); disp(mdl.Coefficients); % 残差图检查模型是否有明显的非线性残留 plotResiduals(mdl, fitted);逻辑说明fitlm的Coefficients表里能看到每个变量的回归系数、标准误、t统计量和p值。residual vs fitted图如果呈现“喇叭形”或“弯曲带状”说明可能存在异方差或漏掉非线性项这时回到第2章检查散点图看是否需要给某个变量做对数变换或用Spearman相关性佐证。模型的R-squared与调整R-squared也应该和单变量相关性的强度相互印证如果单变量相关很高、模型却很差多半是变量之间互相抵消或共线回去重新筛。4. 相关性分析常见问题排查五个数据中心与解释陷阱的实录4.1 异常值把结果带翻车一个点改变整个结论现象某组数据最初算出Pearson相关系数只有0.2看起来无关清理掉一个明显离群的样本点后r突然跳到0.75方向和结论都变了。原因Pearson相关系数在数学上对极端值几乎没有抵抗力。一个杠杆点如果同时远离x和y的均值就能凭一己之力把协方差拉高或压平。这个毛病在样本量小于50时尤其明显。解决拿到数据先画散点图或箱线图把离群点标出来。不要贸然删除而是分别计算“含离群点”和“剔除离群点”的相关系数两个结果都记录。如果差异超过0.2说明结论不稳定此时改用Spearman秩相关或者在报告中注明离群点的影响程度。常见做法是再用MAD绝对中位差识别离群点比3倍标准差更抗污染。4.2 线性假设盲区指标算出来很小不代表两个变量无关现象两个变量之间存在明显的单调上升关系但Pearson相关系数只有0.05p值也不显著业务方差点放弃这个特征。原因这不是计算错误而是Pearson只能捕捉线性共变。典型的例子是y随x呈指数增长或x取整数值时y出现阶梯跳变线性拟合的残差极大相关系数自然趋近0。解决先从散点图看形状再用corr(x, y, Type, Spearman)算秩相关。如果spearman显著而pearson不显著说明关系是非线性的但趋势稳定。更进一步可以做分箱统计把x切成5到10个区间看每个区间的y均值是否单调变化这是给非线性关系找证据的比较直观的手段。需要注意这种“补救”不能反过来证明因果关系只能证明关联形态。4.3 p值不是免死金牌大样本下什么都显得“显著”现象样本量达到2万以上时几乎所有变量的相关性p值都小于0.001看p值觉得遍地是宝但相关系数绝对值才0.03。原因p值受样本量影响极大。样本量足够大时即使总体相关系数为0抽样波动也会让p值趋近于0。这是显著性检验的数学属性不是bug。换句话说大样本下p值能告诉你“这个相关是否精确不为0”但无法告诉你“这个相关是否有价值”。解决同时报告相关系数及其95%置信区间重点看区间是否横跨0以及下界是否低于0.1这类实际意义阈值。大样本下我习惯把筛选阈值从0.3抬到0.4或0.5用“最小有意义的效应量”反向卡筛选标准。区间估计可以借助5.2节里的自举方法避免直接依赖p值做决定。4.4 缺失数据默认处理不同complete和pairwise结果竟然对不上现象同一份数据用corr(dataMat, Rows, complete)得到某对变量的相关系数是0.45用pairwise变成0.62两个结果相差悬殊不知道信哪个。原因complete要求整行所有变量都不缺失才进入计算样本量被压缩pairwise则利用每对变量各自可用的全部样本。如果缺失不是完全随机两种方式计算出的样本子集不同相关系数自然不同。解决先算每个变量的缺失率再绘制缺失模式图。变量缺失率低、缺失模式接近随机时pairwise更充分利用信息缺失率超过30%时两种方法都不可靠优先考虑插补后再算。这里最容易被忽略的是输出结果的样本量corr函数不会直接显示用了多少行必须自己用sum(~any(isnan(dataMat),2))确认避免拿两个样本量差距很大的指标做对比。4.5 多个变量一起检验时假阳性会累积现象8个变量两两相关共28对检验结果里有6对p值小于0.05看起来变量间关系紧密。但把显著性水平假定为0.05纯随机数据也有大约1.4对会被误判为“显著”。原因每做一次检验犯第一类错误的概率是alpha做m次检验至少出现一次假阳性的概率是1-(1-alpha)^m变量越多累积风险越大。相关矩阵里的每个格子的p值都来自一次独立检验没有做多重比较校正。解决手头变量超过5个时我会用Benjamini-Hochberg的FDR校正或Bonferroni校正。MATLAB没有内置的一行函数常见做法是提取P矩阵的上三角p值排序后从大到小迭代比较pvals P(triu(true(size(P)), 1)); % 取上三角非对角线p值 [p_sorted, idx] sort(pvals, descend); m numel(p_sorted); q 0.05; % FDR阈值 threshold q * ((m:-1:1) / m); % 从最大到最小的临界值 significant p_sorted threshold; pvals(idx(significant)) % 这些p值通过校正逻辑说明FDR校正的思路是先对p值从大到小排序每个位置对应的显著性临界值是q * 排名 / 总检验数从大到小比较并找到第一个通过的位置它的前面全部判定为显著。这样既控制了假阳性比例又比Bonferroni温和一些。说明一下P矩阵和R矩阵的行列顺序一致提取上三角后要记住索引便于回溯到具体变量对。5. 让结论站得住偏相关与自举置信区间的两个收尾动作5.1 用偏相关排除第三个变量的干扰相关性分析到最后一公里最容易被人追问的就是“这两个变量相关是不是因为共同受第三个变量影响”。比如销售量和广告投放强烈相关但可能两者同时受季节因素驱动。此时要计算的不是普通相关而是偏相关——在控制z变量影响后x与y的相关系数。MATLAB里对应函数是partialcorr用法很直接% 控制z后计算x和y的偏相关系数 [r_partial, p_partial] partialcorr(x, y, z); fprintf(偏相关系数 %.3f, p %.3f\n, r_partial, p_partial);逻辑说明partialcorr会先用线性回归把x和y中能被z解释的部分去掉再对残差求相关。如果偏相关比普通相关低很多说明原来观察到的关系很大程度来自z如果偏相关仍然显著说明x和y之间有相对独立的关联。这个动作能让结论从“表面相关”推进到“有条件的相关”在数学建模论文里也很加说服力。5.2 自举置信区间别再只丢一个r值给读者单次计算的相关系数没有误差范围容易被质疑。自举法通过对原始样本反复有放回抽样得到相关系数的一列重采样估计再取2.5%和97.5%分位数作为置信区间这是目前比较通行的做法不依赖正态假设。rng(7); nBoot 1000; % 每次抽样100个样本计算Pearson相关 bootR bootstrp(nBoot, (a, b) corr(a, b), x, y); ci quantile(bootR, [0.025, 0.975]); fprintf(相关系数95%%置信区间: [%.3f, %.3f]\n, ci(1), ci(2));参数说明rng(7)固定随机种子保证结果可复现nBoot设1000是性价比比较高的选择最少500追求稳定可以到2000以上。quantile取分位数时2.5%和97.5%对应95%区间的双侧边界。如果区间宽度超过0.3说明样本量不足或数据稳定性差此时对“强相关”的结论要留三分余地。从那以后我每次交付相关分析结果都会强制自己走完三个动作先看散点图确认形态没选错相关系数再算自举置信区间给范围最后用偏相关排除明显的第三方变量。这套流程不长但能在很大程度上避免“结论跑偏”的后期返工也省得建模阶段再为特征稳定性焦虑。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。