
简介一份面向数据建模与分析人员的MATLAB偏最小二乘PLS算法实现源码适用于具备一定统计基础、希望快速上手PLS回归建模的科研与工程用户。资源包仅含1个m文件整体体积约1KB代码精简紧凑便于直接阅读、调用和二次修改。PLS方法能在自变量高度相关或样本量小于变量数时稳定建模通过投影降维提取最具解释力的成分这套源码覆盖了从数据标准化、协方差计算到主成分提取与预测的核心流程。已有219人学习下载对理解PLS内部迭代机制和高维数据处理具有较好的参考价值。使用者可借助该实现对比不同主成分数目对模型的影响也可结合自身数据替换输入矩阵快速验证算法效果。1. 用 MATLAB 跑偏最小二乘法之前先弄清楚 PLS 到底解决什么问题做数据分析的人拿到一组多维自变量 X 和一个要预测的响应 Y第一反应是回归。但真实工程数据里 X 往往高度共线性比如近红外光谱的几百个波长点几乎线性相关、过程参数的相邻采样点彼此耦合。直接做多元线性回归回归系数方差被共线性放大模型在测试集上完全塌掉先做主成分回归PCR虽然能压缩维度却只盯着 X 的方差根本不关心这些主成分和 Y 有没有关系。偏最小二乘法Partial Least SquaresPLS的出发点就是同时考虑 X 和 Y它在 X 中寻找能最佳解释 Y 的潜变量方向而不是仅仅寻找 X 中方差最大的方向。这套思想让它成为化学计量学、工业过程建模、生物信息学等领域处理高维共线性数据的默认选择之一而 MATLAB 里既有内置的plsregress也有大量第三方源码很多入门者拿到pls.rar_matlab源码解压出来却不知道该调哪个参数、怎么选主成分数。本文按照理论定位、算法拆解、MATLAB 实现、交叉验证和进阶技巧这条线把偏最小二乘法在数据处理建模分析里的完整路径讲清楚代码可以直接跑参数含义逐一说明。2. 从 NIPALS 到潜变量偏最小二乘法的迭代结构和选择理由2.1 为什么是潜变量而不是主成分PLS 与 PCA、PCR 的本质差异传统的 PCA 对 X 做特征分解得到的每个主成分只保证自身方差最大和 Y 的相关性可能接近于零。PCR 把 PCA 和回归串联先用 PCA 压缩 X再对得分做回归但主成分的选择标准始终和 Y 无关。PLS 的潜变量和 PCA 的主成分表面上都是一种线性组合数学形式都是对 X 做投影但优化目标不同PLS 寻找的是使 X 得分与 Y 得分协方差最大的方向。% 展示 PLS 与 PCA 在目标函数上的区别 % 假设 X 是 n×p 的自变量矩阵Y 是 n×m 的响应矩阵 % PLS 的载荷向量 w 满足最大化 cov(X*w, Y) 的方差 % 对比 PCA 的载荷向量 v 满足最大化 var(X*v) % 生成一个存在共线性的示例数据 rng(42); n 100; p 10; X_true randn(n, 3); % 真正的三个潜在因素 X X_true * randn(3, p) 0.1 * randn(n, p); % 观测变量存在强共线性 Y X_true(:, 1) * 2 X_true(:, 2) * (-1) 0.05 * randn(n, 1); % 对 X 做 PCA观察前两个主成分与 Y 的相关性 [coeff_pca, score_pca] pca(X); fprintf(PCA第1主成分与Y的相关系数: %.3f\n, corr(score_pca(:,1), Y)); fprintf(PCA第2主成分与Y的相关系数: %.3f\n, corr(score_pca(:,2), Y)); % 对 X 与 Y 做 PLS观察前两个潜变量与 Y 的相关性 [Xloadings, Yloadings, Xscores, Yscores] plsregress(X, Y, 2); fprintf(PLS第1潜变量与Y的相关系数: %.3f\n, corr(Xscores(:,1), Y)); fprintf(PLS第2潜变量与Y的相关系数: %.3f\n, corr(Xscores(:,2), Y));这段代码直观对比了 PCA 和 PLS 的差异PCA 得分与 Y 的相关性不受任何约束可能很低PLS 得分在构造时就被迫向 Y 靠拢两者的相关系数在同样数据下会明显更高。这个差异是选择 PLS 而不是 PCR 的根本理由当建模目的以预测 Y 为中心且 X 存在严重多重共线性时PLS 用更少的潜变量就能达到同样的预测精度。2.2 NIPALS 算法的迭代步骤从标准化到收敛判断PLS 算法以 NIPALSNonlinear Iterative Partial Least Squares为核心迭代方案。MATLAB 内置的plsregress底层实现了该算法理解它的每一步对调试第三方源码至关重要尤其是当你自己写的 PLS 代码结果和plsregress不一致时。NIPALS 的核心流程如下% NIPALS 单潜变量的核心迭代过程 % 输入: X (n×p), Y (n×m) % 输出: 第一对潜变量的权重 w, c 和得分 t, u function [w, c, t, u] nipals_one_component(X, Y, max_iter, tol) % 初始化 u 为 Y 的第一列 u Y(:, 1); for iter 1:max_iter % 第1步: 在 X 上投影计算 X 的权重 w % w X*u / norm(X*u)让 X 得分与 u 协方差最大 w X * u; w w / norm(w); % 第2步: 计算 X 的得分 t t X * w; % 第3步: 在 Y 上投影计算 Y 的权重 c c Y * t; c c / norm(c); % 第4步: 更新 Y 的得分 u u_new Y * c; % 第5步: 检查收敛用 t 的变化量或 u 的变化量判断 if norm(u_new - u) / norm(u) tol u u_new; break; end u u_new; end end这段代码的关键在于每次迭代中w和c交替更新先固定u算w再固定w算t接着算c和新的u。收敛标准用u的相对变化量来判断一般容差设为1e-8到1e-10即可max_iter设为 100 足够。注意w在归一化时用的是 L2 范数这保证权重向量的单位长度否则迭代会发散。完成了第一个潜变量的提取后需要对 X 和 Y 做矩阵消去deflation让X X - t*wY Y - t*c然后对残差矩阵重复上述过程提取下一个潜变量。这套w、t、c、u交替迭代的机制就是 PLS 区别于 PCA 的核心所在PCA 一次特征分解就能得到所有主成分而 PLS 必须逐次迭代提取。2.3 SIMPLS 与 NIPALS 的选择考量MATLAB 的plsregress实际使用的是 SIMPLS 算法它在数学上与 NIPALS 等价但实现方式不同SIMPLS 直接对协方差矩阵做奇异值分解一次性计算出所有潜变量方向不需要逐次消去。NIPALS 的优势在于内存占用低适合 X 是稠密矩阵且样本量极大、无法一次载入内存的场景SIMPLS 的优势在于数值稳定性好且速度快当变量数 p 超过样本数 n比如基因表达数据、光谱数据时SIMPLS 不易因矩阵消去误差累积而崩溃。对比维度NIPALSSIMPLS核心操作交替投影迭代SVD 分解内存占用低适合逐块处理较高需要载入完整 X数值稳定性特征值接近时可能振荡更稳定MATLAB 对应第三方代码常见plsregress内置适合场景超大规模稀疏矩阵常规数据、高维低样本实际选择时我一般遵循一个简单规则数据在内存装得下就用plsregress装不下再用基于 NIPALS 的流式实现。用plsregress时要注意它返回的系数矩阵格式需要转换才能得到原始的回归系数这一点在下一章详细展开。3. 在 MATLAB 中用 plsregress 实现偏最小二乘回归核心代码与必调参数3.1plsregress的输入输出结构与回归系数还原plsregress是 MATLAB 统计和机器学习工具箱Statistics and Machine Learning Toolbox中的函数不依赖第三方代码语法简明[XL, YL, XS, YS, BETA, PCTVAR] plsregress(X, Y, ncomp)。其中XL是 X 的载荷矩阵YL是 Y 的载荷矩阵XS是 X 得分YS是 Y 得分BETA是回归系数PCTVAR是每个潜变量解释的方差百分比。% plsregress 完整建模流程 % 生成带噪声的共线性数据 rng(123); n 200; p 20; % 真正的潜变量只有3个 T randn(n, 3); % 载荷矩阵让 X 的变量之间存在强相关性 P randn(3, p); X T * P 0.05 * randn(n, p); % Y 只依赖前两个潜变量添加噪声 Y 2 * T(:, 1) - T(:, 2) 0.1 * randn(n, 1); % 中心化和标准化处理 X_centered X - mean(X); Y_centered Y - mean(Y); % 指定潜变量数为5 ncomp 5; [XL, YL, XS, YS, BETA, PCTVAR] plsregress(X_centered, Y_centered, ncomp); % BETA 的形状是 (p1)×m第一行是截距项 fprintf(BETA 矩阵大小: %d × %d\n, size(BETA, 1), size(BETA, 2)); % 手动计算预测值 Y_pred [ones(n, 1), X_centered] * BETA; % 计算 R² SS_res sum((Y_centered - Y_pred).^2); SS_tot sum((Y_centered - mean(Y_centered)).^2); R2 1 - SS_res / SS_tot; fprintf(模型 R²: %.4f\n, R2); % 解释方差百分比 disp(各潜变量解释的方差百分比:); disp(PCTVAR);BETA的输出维度是(p1) × m其中第一行对应截距项因为plsregress默认在 X 左侧加了一列 1。PCTVAR是两行矩阵第一行是每个潜变量对 X 的解释方差第二行是对 Y 的解释方差。值得注意的是plsregress内部并不自动标准化数据输入数据的量纲直接影响结果所以我在建模前手动做了中心化。如果变量量纲差异极大用zscore做标准化再送入模型回归系数则对应标准化后的变量。3.2 潜变量数的确定交叉验证与 PCTVAR 的配合潜变量数是 PLS 中最重要的超参数选少了欠拟合选多了把噪声也吸收进模型。最稳妥的确定方式是 K 折交叉验证MATLAB 的crossval可以配合plsregress一起使用也可以手动实现循环。% 用 10 折交叉验证确定最佳潜变量数 rng(456); K 10; max_ncomp min(15, rank(X_centered)); cv_rmse zeros(max_ncomp, 1); % 生成折索引 indices crossvalind(Kfold, size(X_centered, 1), K); for ncomp_i 1:max_ncomp rmse_fold zeros(K, 1); for k 1:K % 划分训练集与验证集 test_idx (indices k); train_idx ~test_idx; % 每次交叉验证都要重新做中心化防止数据泄漏 X_train X_centered(train_idx, :); Y_train Y_centered(train_idx, :); X_test X_centered(test_idx, :); Y_test Y_centered(test_idx, :); % 对训练集中心化并记录均值和标准差 mu_X mean(X_train); std_X std(X_train); mu_Y mean(Y_train); X_train_norm (X_train - mu_X) ./ std_X; X_test_norm (X_test - mu_X) ./ std_X; Y_train_norm Y_train - mu_Y; % 拟合 PLS [~, ~, ~, ~, BETA_fold] plsregress(X_train_norm, Y_train_norm, ncomp_i); % 预测并反标准化 Y_pred_norm [ones(size(X_test_norm, 1), 1), X_test_norm] * BETA_fold; Y_pred Y_pred_norm mu_Y; rmse_fold(k) sqrt(mean((Y_test - Y_pred).^2)); end cv_rmse(ncomp_i) mean(rmse_fold); end % 找出最小 RMSE 对应的潜变量数 [best_rmse, best_ncomp] min(cv_rmse); fprintf(最佳潜变量数: %d, CV RMSE: %.4f\n, best_ncomp, best_rmse); % 绘制 RMSE 随潜变量数的变化曲线 figure; plot(1:max_ncomp, cv_rmse, -o, LineWidth, 1.5); xlabel(潜变量数); ylabel(交叉验证 RMSE); title(潜变量数选择); grid on;这段代码有一个非常容易犯的错误交叉验证的每一折内部都要重新做标准化而不能用全样本的均值和标准差。如果先在全样本上标准化再划分折验证集的信息已经泄漏到了训练过程里会导致模型评估偏乐观。代码里每个折都单独计算了训练集的mu_X、std_X并应用于测试集这才是正确做法。从交叉验证曲线上看RMSE 通常会先快速下降然后进入平台期最后因为过拟合缓慢上升。选择 RMSE 最低点或者平台期起始点都可以我通常偏好比最低点差一个标准误差以内的最少潜变量数即 one-standard-error rule这样模型更简洁可解释。3.3 数据预处理对偏最小二乘建模分析的影响PLS 对数据的尺度和分布敏感。常见做法是先做中心化这几乎是必须的因为模型要估计截距项是否做标准化取决于变量的物理单位是否可比。对于近红外光谱数据不同波长的吸光度本身就是同尺度可比做中心化即可对于过程工业数据温度、压力、流量单位不同量纲差异大必须标准化到方差为 1。% 预处理的三种方案对比 % 方案1: 仅中心化 X_c X - mean(X); Y_c Y - mean(Y); % 方案2: 标准化到零均值单位方差 X_z zscore(X); Y_z zscore(Y); % 方案3: 映射到[-1, 1]区间 X_min min(X); X_max max(X); X_scaled 2 * (X - X_min) ./ (X_max - X_min) - 1; % 分别建模比较预测表现 [~, ~, ~, ~, BETA_c] plsregress(X_c, Y_c, 3); [~, ~, ~, ~, BETA_z] plsregress(X_z, Y_z, 3); [~, ~, ~, ~, BETA_s] plsregress(X_scaled, Y_z, 3);三种预处理方式中标准化zscore是最稳的选择因为它让每个变量在计算协方差矩阵时拥有相同的权重。区间映射到 [-1,1] 在存在离群点时会把正常值压缩到很小的范围一般不推荐。原始数据里有 NaN 时要先处理plsregress对 NaN 的直接报错并不友好常见的做法是先用rmmissing删除缺失行或者用knnimpute插补但插补高阶数据时要小心引入偏差。4. 用交叉验证评估 PLS 模型并与第三方源码对比避免踩坑的验证方法4.1 模型评估指标R²、RMSE、Q² 与 VIP 的综合运用建模完成后单看训练集的 R² 没有任何意义PLS 模型几乎总是能通过增加潜变量数把训练集 R² 做到接近 1。可靠的评估体系包含四个指标训练集 R² 反映拟合能力交叉验证 Q²也叫预测 R²反映泛化能力RMSE 反映预测误差的绝对水平VIPVariable Importance in Projection反映变量对模型的重要性排序。% 计算 Q² (交叉验证 R²) 和 VIP 分数 % 先计算交叉验证预测值 Y_cv_pred zeros(size(Y_centered)); for k 1:K test_idx (indices k); train_idx ~test_idx; X_train X_centered(train_idx, :); Y_train Y_centered(train_idx, :); X_test X_centered(test_idx, :); mu_X_tr mean(X_train); std_X_tr std(X_train); mu_Y_tr mean(Y_train); X_train_n (X_train - mu_X_tr) ./ std_X_tr; X_test_n (X_test - mu_X_tr) ./ std_X_tr; Y_train_n Y_train - mu_Y_tr; [~, ~, ~, ~, BETA_f] plsregress(X_train_n, Y_train_n, best_ncomp); Y_pred_n [ones(size(X_test_n, 1), 1), X_test_n] * BETA_f; Y_cv_pred(test_idx) Y_pred_n mu_Y_tr; end % Q² 1 - PRESS / SS_tot PRESS sum((Y_centered - Y_cv_pred).^2); SS_tot sum((Y_centered - mean(Y_centered)).^2); Q2 1 - PRESS / SS_tot; fprintf(Q²: %.4f\n, Q2); % 计算 VIP 分数 % 利用 plsregress 的输出重构 p_var sum(PCTVAR(2, :)); % 累计解释的Y方差 vip zeros(size(X_centered, 2), 1); w_norm2 sum(XL.^2, 1); % 每个潜变量载荷的平方和 for j 1:size(X_centered, 2) % VIP_j sqrt(p * sum(SSY_i * (w_ij/norm(w_i))^2) / sum(SSY_i)) ssy_i PCTVAR(2, 1:size(XL, 2)); contribution sum(ssy_i .* (XL(j, :) ./ sqrt(w_norm2)).^2); vip(j) sqrt(size(X_centered, 2) * contribution / sum(ssy_i)); end % 显示重要性排前5的变量 [sorted_vip, idx_sorted] sort(vip, descend); disp(VIP 排名前5的变量:); for i 1:5 fprintf(变量 %d, VIP %.3f\n, idx_sorted(i), sorted_vip(i)); endVIP 分数的经验阈值为 1.0VIP 大于 1 的变量对模型解释 Y 有显著贡献VIP 在 0.5 到 1 之间贡献一般VIP 低于 0.5 的变量可以考虑剔除。这段代码里XL是加载矩阵每一列是一个潜变量的载荷向量w_norm2是各载荷向量的 L2 范数平方VIP 的数学定义是各潜变量对 Y 的解释方差加权后的归一化指标。筛选变量时建议结合 VIP 和回归系数符号一起看VIP 高但回归系数接近零的变量可能与其他变量存在交互效应删掉后模型会更干净。4.2 第三方 PLS 源码和plsregress结果不一致时的排查路径很多工程师从pls.rar_matlab源码解压得到的是自编写的 PLS 代码跑出来的回归系数和plsregress不同。先别怀疑 MATLAB 内置函数出错绝大多数情况是以下三个原因第一预处理方式不同对方代码可能默认对 X 和 Y 同时做标准化而plsregress不做任何预处理第二算法版本不同NIPALS 和 SIMPLS 在潜变量得分上符号可能相反载荷和权重的符号翻转只要成对出现就不影响预测值但单独比较某一列会发现符号差异第三收敛容差不同NIPALS 迭代的容差如果设置过松比如1e-4提取的潜变量方向和 SIMPLS 会有微弱差异。% 验证你的 PLS 实现是否正确的标准化测试 % 生成单一潜变量的理想数据 n 50; p 5; t randn(n, 1); % 真正的潜变量 w_true [1; 2; -1; 0.5; 0.3]; % 真实权重 X t * w_true 0.001 * randn(n, p); Y 3 * t 0.001 * randn(n, 1); % 用 plsregress 拟合1个潜变量 [Xload, Yload, Xscore, Yscore, Beta] plsregress(X, Y, 1); % 手动计算第一潜变量的权重: 对 X*Y 做归一化 % 这是 PLS 第一潜变量权重的解析解 w_manual X * Y; w_manual w_manual / norm(w_manual); fprintf(plsregress 载荷: ); disp(Xload); fprintf(手动计算权重: ); disp(w_manual); fprintf(符号一致性: %.4f\n, dot(Xload(:, 1), w_manual));这个测试用人为构造的单个潜变量数据验证 PLS 实现是否正确。X * Y的方向向量是 PLS 第一潜变量权重的解析解如果plsregress的载荷列向量与它的点积绝对值接近 1说明实现正确如果点积为负只是符号翻转不影响预测。用这套方法可以快速排查第三方源码的正确性。4.3 离群点与非线性问题对偏最小二乘回归的干扰PLS 本质是线性模型对离群点非常敏感。在建模前用 Hotelling T² 统计量和 Q 残差统计量对样本做诊断是标准的做法T² 反映样本在潜变量空间中的分布偏移Q 残差反映样本对模型的拟合残差。% PLS 模型离群点检测 % 计算 Hotelling T² 和 Q 残差 [~, ~, XS, ~] plsregress(X_centered, Y_centered, best_ncomp); T2 sum((XS ./ std(XS)).^2, 2); % 计算 X 重建残差 X_hat XS * XL(:, 1:best_ncomp); Residuals X_centered - X_hat; Q_res sum(Residuals.^2, 2); % 设置显著性水平 0.05 的阈值F 分布和卡方分布 alpha 0.05; T2_threshold finv(1-alpha, best_ncomp, n - best_ncomp) * best_ncomp * (n-1)/(n-best_ncomp); Q_threshold chi2inv(1-alpha, best_ncomp) * median(Q_res); % 近似阈值 outlier_idx find(T2 T2_threshold | Q_res Q_threshold); fprintf(检测到 %d 个潜在离群点\n, length(outlier_idx));在实际项目中我一般先看 T² 阈值附近的点是否对应已知的异常工况再有选择地剔除而不是机械删掉所有超阈值样本。对于 X 与 Y 存在明显非线性关系的场景标准 PLS 效果有限常见做法是引入支持向量回归或高斯过程回归但非线性 PLS如平方项扩展、核 PLS的 MATLAB 源码质量参差不齐在数据量足够时优先考虑成熟的内置函数。5. 偏最小二乘法的三个进阶用法变量筛选、多响应建模与模型迁移5.1 用 VIP 做变量筛选后的 PLS 性能对比很多高维数据里 p 超过几百甚至几千全变量 PLS 虽然能运行但变量过多会引入噪声降低模型稳定性和可解释性。基于 VIP 分数做变量筛选是化学计量学里的通用流程先在全变量上建一个 PLS 模型计算 VIP按阈值剔除不重要的变量再在筛选后的变量上重建模型验证精度。% 基于 VIP 的变量筛选循环 vip_threshold 0.8; selected_idx find(vip vip_threshold); % VIP 阈值设为 0.8 % 用筛选后的变量重新建模 X_selected X_centered(:, selected_idx); [~, ~, ~, ~, BETA_selected] plsregress(X_selected, Y_centered, best_ncomp); Y_pred_selected [ones(n, 1), X_selected] * BETA_selected; SS_res_sel sum((Y_centered - Y_pred_selected).^2); R2_selected 1 - SS_res_sel / SS_tot; fprintf(变量数从 %d 减少到 %dR²: %.4f\n, ... size(X_centered, 2), length(selected_idx), R2_selected);这个例子把 VIP 阈值设为 0.8实际项目中这个阈值通常在 0.5 到 1.0 之间根据模型复杂度调整。筛选后的模型潜变量数可能也需要重新交叉验证因为删除了部分信息维度后原来确定的最佳潜变量数未必仍然最优。另外要注意重复进行 VIP 筛选和交叉验证构成的嵌套过程严格来说筛选应该放在交叉验证的每一折内部执行否则 VIP 计算过程本身存在信息泄漏的风险在样本量少时要格外小心。5.2 多响应 Y 的 PLS 建模用一张载荷图同时分析多个输出当 Y 是一个多列矩阵而不仅仅是一列时PLS 仍然可以直接建模plsregress无缝支持多响应。这在很多实际场景里非常有用比如同时预测产品的多个质量指标或者同时分析光谱和色谱两种输出。多响应 PLS 的潜变量会同时捕捉 X 中与多个 Y 相关的方向潜变量数量需要重新用交叉验证确定。% 多响应 PLS 建模示例 % Y 有3列分别对应3个相关质量指标 Y_multi [2 * T(:,1) - T(:,2) 0.1*randn(n,1), ... T(:,1) T(:,3) 0.1*randn(n,1), ... -T(:,2) 0.5*T(:,3) 0.05*randn(n,1)]; % 中心化 Y_multi_c Y_multi - mean(Y_multi); % 多响应交叉验证选择潜变量数 cv_rmse_multi zeros(max_ncomp, 1); for ncomp_i 1:max_ncomp rmse_fold zeros(K, 1); for k 1:K test_idx (indices k); train_idx ~test_idx; mu_X_tr mean(X_centered(train_idx, :)); std_X_tr std(X_centered(train_idx, :)); mu_Y_tr mean(Y_multi_c(train_idx, :)); X_tr_n (X_centered(train_idx, :) - mu_X_tr) ./ std_X_tr; X_te_n (X_centered(test_idx, :) - mu_X_tr) ./ std_X_tr; Y_tr_n Y_multi_c(train_idx, :) - mu_Y_tr; [~, ~, ~, ~, B_f] plsregress(X_tr_n, Y_tr_n, ncomp_i); Y_pr_n [ones(size(X_te_n, 1), 1), X_te_n] * B_f; Y_pr Y_pr_n mu_Y_tr; rmse_fold(k) sqrt(mean(sum((Y_multi_c(test_idx, :) - Y_pr).^2, 2))); end cv_rmse_multi(ncomp_i) mean(rmse_fold); end figure; plot(1:max_ncomp, cv_rmse_multi, -s, LineWidth, 1.5); xlabel(潜变量数); ylabel(多响应CV RMSE); title(多响应 PLS 潜变量数选择); grid on;多响应场景中RMSE 的计算需要对所有响应列做整体评估这里用每行所有响应列的平方和再开方作为该样本的误差。与单响应相比多响应 PLS 的潜变量数一般会更少因为单一潜变量可以同时捕捉多个 Y 的共享信息方向。在多列 Y 的量纲不一致时需要在计算 RMSE 前先对各列做标准化否则量纲大的响应会主导整个评估。5.3 模型迁移与在线部署把 PLS 回归系数导出为标准格式一个在实验室数据上表现良好的 PLS 模型最终要落地到生产环境可能是嵌入式设备、Python 服务或者另一套工业软件。由于 PLS 的本质是线性变换和回归的组合它导出的模型格式很简单权重矩阵、载荷矩阵、回归系数、均值与标准差向量这几样东西足以在任何语言中重建模型。% 导出 PLS 模型为独立可移植的格式 % 假设最终模型已用最佳潜变量数确定 [XL_final, YL_final, XS_final, YS_final, BETA_final, PCTVAR_final] ... plsregress(X_centered, Y_centered, best_ncomp); % 保存到结构化文件中 model struct(); model.BETA BETA_final; % 回归系数首行为截距 model.X_mean mean(X_centered); model.X_std std(X_centered); model.ncomp best_ncomp; model.PCTVAR PCTVAR_final; model.timestamp datestr(now, yyyy-mm-dd HH:MM:SS); save(pls_model.mat, model); % 如果要导出给 Python 等外部环境使用 % writematrix(BETA_final, pls_beta.csv); % writematrix(model.X_mean, pls_x_mean.csv); % writematrix(model.X_std, pls_x_std.csv);模型在线部署时最常见的坑是预处理参数不匹配训练时如果用了标准化预测时一定要用训练集的标准差和均值而不是新样本的统计量。另外 MATLAB 里保存的.mat文件在不同大版本间存在兼容性问题用-v7参数保存可以保证 MATLAB 2026b 及更早版本正常读取。对于需要嵌入 C/C 代码的场景直接使用saveLearnerForCoder配合 MATLAB Coder 生成独立执行程序plsregress本身不支持直接转 C但 BETA 一旦导出预测逻辑只是简单的矩阵乘法加偏移手写 C 代码做事最稳妥的方案。偏最小二乘回归的完整分析流程到这里算是闭环了实际工作中多花时间在数据预处理和潜变量数验证上比换算法、换工具带来更大的精度提升。本文还有配套的精品资源点击获取