☰
MATLAB相关性分析从选型到建模落地:完整实操指南
2026/10/12 15:19:31 网站建设 项目流程

简介:面向数学建模参赛者与数据分析初学者,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对应Type
Pearson线性、近似正态、连续变量高,单个极端值可能主导结果'Pearson'
Spearman单调关系即可,不要求正态低,基于秩次'Spearman'
Kendall等级数据,允许大量并列低,基于样本对一致性'Kendall'

系数本身能给你一个数值,问题在于多数人只拿这个数值当结论,忽略了三个隐藏信息:一是相关系数的置信区间还没算,小样本下r=0.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选项会在相关系数显著(默认alpha=0.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.05,p值也不显著,业务方差点放弃这个特征。

原因:这不是计算错误,而是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,说明样本量不足或数据稳定性差,此时对“强相关”的结论要留三分余地。

从那以后,我每次交付相关分析结果都会强制自己走完三个动作:先看散点图确认形态没选错相关系数,再算自举置信区间给范围,最后用偏相关排除明显的第三方变量。这套流程不长,但能在很大程度上避免“结论跑偏”的后期返工,也省得建模阶段再为特征稳定性焦虑。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询