基于PLS算法的MATLAB时间序列预测--不依赖工具箱函数的实践代码指南

基于PLS算法的MATLAB时间序列预测--不依赖工具箱函数的实践代码指南 基于偏最小二乘算法(PLS)的时间序列预测不调用工具箱函数PLS时间序列 matlab代码 注暂无Matlab版本要求--推荐2018B版本及以上咱们今天来盘一盘怎么手搓PLS时间序列预测。这玩意儿在金融、气象领域用得贼多但网上能找到的代码基本都是调工具箱的。不废话直接上干货先说清楚咱们的代码全程不碰plsregress这类内置函数纯手工打造PLS引擎。先搞明白时间序列预测的场景。假设咱们有个单变量序列[1,2,3,...,100]要预测未来k步的值。这时候得把时间序列重构为X和Y矩阵比如用前3个点预测第4个点raw sin(0:0.1:20) randn(201,1)*0.2; % 带噪声的正弦波 lag 3; % 滞后阶数 X []; Y []; for i 1:length(raw)-lag X [X; raw(i:ilag-1)]; Y [Y; raw(ilag)]; end重点来了PLS核心是迭代提取主成分。咱们得自己写权重计算这个最容易翻车。看这段权重更新的骚操作function [W,P,Q] pls_nipals(X,Y,ncomp) W zeros(size(X,2), ncomp); P zeros(size(X,2), ncomp); Q zeros(size(Y,2), ncomp); for i 1:ncomp u Y(:,1); % 随便初始化个向量 for iter 1:1000 w X*u/(u*u); % 权重计算 w w/norm(w); % 归一化 t X*w; % X得分向量 q Y*t/(t*t);% Y载荷 u_new Y*q/(q*q); if norm(u_new - u) 1e-6 break; end u u_new; end p X*t/(t*t); % X载荷 X X - t*p; # 矩阵缩减 Y Y - t*q; W(:,i) w; P(:,i) p; Q(:,i) q; end end这里用NIPALS算法迭代求解权重注意那个收敛条件别写太死不然容易无限循环。实际跑的时候建议加上最大迭代次数限制。基于偏最小二乘算法(PLS)的时间序列预测不调用工具箱函数PLS时间序列 matlab代码 注暂无Matlab版本要求--推荐2018B版本及以上预测部分才是重头戏得把建模时的参数都用上function y_pred pls_predict(X_new, W, P, Q, X_mean, Y_mean) T X_new * W; % 计算得分 y_pred Y_mean T*Q; % 重构预测值 end这里有个坑建模时如果做了中心化预测时也得用同样的均值来处理新数据。所以在训练阶段记得保存X和Y的均值X_mean mean(X); Y_mean mean(Y); X_centered X - X_mean; Y_centered Y - Y_mean;测试时用个滚动预测每次预测后把新数据塞回输入矩阵current_input X(end,:); % 最后一段已知数据 predictions zeros(10,1); for i 1:10 pred pls_predict(current_input, W, P, Q, X_mean, Y_mean); predictions(i) pred; current_input [current_input(2:end), pred]; % 滚动窗口 end这个滚动机制有个致命问题——误差累积。建议在预测时适当加入噪声或者用集成方法缓解。最后说几个实操要点主成分数别超过5个时间序列数据的信息量没那么大数据标准化用zscore会更好但咱们得自己写function [X_norm, mu, sigma] manual_zscore(X) mu mean(X); sigma std(X); X_norm (X - mu) ./ sigma; end可视化时对比真实值和预测值能明显看到PLS对噪声的过滤效果完整跑一遍流程在2018b上测试正弦波噪声的数据预测10步的平均绝对误差大概在0.3左右。要是效果不好试试给输入矩阵加些非线性变换比如把滞后值的平方也作为特征。