☰
Matlab LSTM时序预测实战:数据集、代码与评价指标全解析
2026/9/28 6:14:48 网站建设 项目流程

简介:这份资源面向需要掌握时序预测的 Matlab 用户与算法学习者,提供一套可直接运行的 LSTM 长短期记忆神经网络预测方案,用于解决单变量时间序列的建模与预测问题。压缩包共 7 个文件,包含 1 个 main.m 主程序、1 个 xlsx 格式数据集以及 5 张 png 结果图,整体约 363KB,体积轻便、结构清晰。代码中文注释详尽,按示例数据格式替换自己的 Excel 数据集即可运行,无需从零搭建网络。结果图覆盖训练集与测试集的预测值对比真实值曲线,并给出训练与测试阶段的预测结果对比,便于直观判断拟合效果。评价指标部分对误差进行量化说明,帮助读者理解模型精度。目前已有 620 人学习下载,适合课程设计、科研入门或需要快速验证 LSTM 时序预测效果的读者参考使用。

1. Matlab LSTM时序预测:从一份数据集到可复现的评价指标

手里有一串按时间排好的数,想预测下一段会怎么走,这是时序预测最朴素的诉求。Matlab 里的 LSTM 长短期记忆神经网络,就是干这件事的常用工具之一。它不像传统 ARIMA 那样要求序列平稳,也不像简单 RNN 那样在长序列上梯度消失,门控结构让它能记住几十步之前的模式。这个标题真正要交付的东西有三块:一份能直接跑的时序数据集、一套 LSTM 训练与预测的 Matlab 代码、以及预测图像和评价指标。适合谁?做设备寿命预测、金融时序预测、传感器信号预测的工程师,手头有 Matlab 但不想从零推导公式,只想把模型跑通、把指标算对、把图画出来。下面按「数据怎么组织 → 网络怎么搭 → 指标怎么算 → 坑在哪」的顺序讲透。

2. 时序数据怎么组织成 LSTM 能吃的格式

2.1 从单列序列到监督学习样本

LSTM 的输入不是原始的一维序列,而是滑窗切出来的「输入段 + 目标值」。假设原始序列是y(1), y(2), ..., y(N),用前lookback步预测下一步,就要构造样本:输入[y(t-lookback+1), ..., y(t)],目标y(t+1)。这一步做错,后面全白搭。

Matlab 里我一般用循环构造,虽然慢但可控:

% data: 1×N 的行向量或 N×1 的列向量 lookback = 24; % 回看步数,按采样频率定 data = data(:)'; % 强制成行向量 N = length(data); X = zeros(N - lookback, lookback); Y = zeros(N - lookback, 1); for t = 1:(N - lookback) X(t, :) = data(t : t + lookback - 1); Y(t) = data(t + lookback); end

逻辑说明:X的第 t 行是第 t 到 t+lookback-1 个点,Y的第 t 个是紧接着的下一个点。参数说明:lookback是唯一需要调的,采样周期是小时级就取 24,是分钟级可以取 60 或 120,太小模型看不到周期,太大样本数骤减。

2.2 划分训练集和测试集不能随机打乱

时序预测和图像分类最大的区别:不能randperm打乱。打乱等于用未来预测过去,指标会好得离谱,上线就翻车。正确做法是按时间顺序切:

trainRatio = 0.8; nTrain = floor(size(X,1) * trainRatio); XTrain = X(1:nTrain, :); YTrain = Y(1:nTrain); XTest = X(nTrain+1:end, :); YTest = Y(nTrain+1:end);

参数说明:trainRatio一般 0.7~0.8,测试集至少要覆盖一个完整周期。如果数据有明显趋势,还要考虑归一化用训练集的 min/max,而不是全量:

mu = mean(XTrain(:)); sg = std(XTrain(:)); XTrain = (XTrain - mu) / sg; XTest = (XTest - mu) / sg; % 用训练集参数,不能用测试集

注意:归一化参数必须从训练集算,测试集只做变换。这一步偷懒,测试指标就是自欺欺人。

2.3 数据集该长什么样

标题里说「含测试数据集」,一份合格的时序数据集应该包含:时间戳列、数值列、以及说明采样间隔的元信息。常见格式是 CSV 或 MAT。CSV 便于跨工具,MAT 便于 Matlab 直接load。我一般会准备两个文件:train_data.csv和test_data.csv,列名统一为timestamp,value。如果只有一列数值,至少要在文件名或注释里写清采样周期,否则lookback没法定。数据量方面,LSTM 不是越多越好,几百到几千个点就能看出效果,上万点要考虑分批训练。

3. Matlab 里搭 LSTM 网络:层结构、训练参数与预测

3.1 用 trainNetwork 还是 trainnet

Matlab 从 R2017b 引入 LSTM,早期用trainNetwork,新版本推荐trainnet。两者层定义方式类似,但trainnet对自定义训练循环更友好。如果你用的是 R2023b 之后的版本,直接用trainnet;老版本就用trainNetwork。下面以trainNetwork为例,因为兼容性更广。

3.2 定义网络层

numFeatures = 1; % 单变量时序 numResponses = 1; layers = [ ... sequenceInputLayer(numFeatures) lstmLayer(64, 'OutputMode', 'last') dropoutLayer(0.2) fullyConnectedLayer(numResponses) regressionLayer];

逻辑说明:sequenceInputLayer接收numFeatures维输入,单变量就是 1。lstmLayer的 64 是隐藏单元数,OutputMode设为last表示只取最后一步输出用于回归。dropoutLayer防过拟合,fullyConnectedLayer映射到输出维度,regressionLayer算 MSE。参数说明:隐藏单元数 32~128 之间试,序列复杂就加大;dropout 0.1~0.3,数据少就加大。

3.3 训练选项怎么设

options = trainingOptions('adam', ... 'MaxEpochs', 200, ... 'MiniBatchSize', 32, ... 'InitialLearnRate', 0.005, ... 'LearnRateSchedule', 'piecewise', ... 'LearnRateDropPeriod', 50, ... 'LearnRateDropFactor', 0.5, ... 'GradientThreshold', 1, ... 'Shuffle', 'never', ... 'Verbose', 0, ... 'Plots', 'training-progress');

参数说明:Shuffle必须设never,时序不能打乱。GradientThreshold设 1 防梯度爆炸,LSTM 常见问题。InitialLearnRate0.005 是常用起点,太大震荡,太小收敛慢。MiniBatchSize32 或 64,显存够就加大。MaxEpochs200 配合学习率衰减,一般够用。

3.4 训练与预测

net = trainNetwork(XTrain, YTrain, layers, options); YPred = predict(net, XTest);

XTrain的维度是[lookback, 1, nTrain],需要 reshape:

XTrain = reshape(XTrain', [lookback, 1, nTrain]); XTest = reshape(XTest', [lookback, 1, size(XTest,1)]);

预测完记得反归一化:

YPred = YPred * sg + mu; YTest = YTest * sg + mu;

3.5 画预测对比图

figure; plot(YTest, 'b-', 'LineWidth', 1.2); hold on; plot(YPred, 'r--', 'LineWidth', 1.2); legend('真实值', '预测值'); xlabel('时间步'); ylabel('数值'); title('LSTM 时序预测对比'); grid on;

这张图是判断模型好坏的第一眼依据。如果预测曲线整体滞后于真实曲线,说明lookback太小或模型没学到趋势;如果预测是一条直线,说明训练没收敛或学习率太低。

4. 评价指标怎么算才不骗自己

4.1 RMSE、MAE、MAPE、R2 四个指标

rmse = sqrt(mean((YPred - YTest).^2)); mae = mean(abs(YPred - YTest)); mape = mean(abs((YPred - YTest) ./ YTest)) * 100; ssRes = sum((YTest - YPred).^2); ssTot = sum((YTest - mean(YTest)).^2); r2 = 1 - ssRes / ssTot; fprintf('RMSE=%.4f MAE=%.4f MAPE=%.2f%% R2=%.4f\n', rmse, mae, mape, r2);

逻辑说明:RMSE 对大误差敏感,MAE 更稳健,MAPE 是百分比误差便于跨量纲比较,R2 看拟合优度。参数说明:MAPE 在YTest接近 0 时会爆炸,如果数据有零值或负值,MAPE 不可用,改用 SMAPE 或直接看 RMSE。

4.2 指标对比表

指标含义好的范围注意
RMSE均方根误差越小越好受量纲影响
MAE平均绝对误差越小越好对异常值稳健
MAPE平均绝对百分比误差<10% 较好零值附近失效
R2决定系数越接近 1 越好负值说明不如均值

4.3 别只看一个指标

我见过太多人只报 RMSE,结果模型在峰值处误差巨大。正确做法是四个指标一起看,再配合预测图。如果 RMSE 小但 MAPE 大,说明小数值处误差占比高;如果 R2 高但图上看预测滞后,说明模型只是学了均值。指标是辅助,图才是真相。

5. 避坑与排查:LSTM 时序预测最常见的 5 个翻车点

5.1 预测曲线整体平移滞后

现象:预测值看起来像真实值往右移了一步。原因:lookback太小,模型只能看到最近几步,学不到趋势。解决:加大lookback,或者改用差分序列建模。我一般会把lookback从 24 加到 72 再试。

5.2 训练 loss 不下降

现象:training-progress里 loss 一直平。原因:学习率太小、数据没归一化、或者Shuffle设成了every-epoch。解决:先检查归一化,再把InitialLearnRate调到 0.01,确认Shuffle是never。

5.3 测试集指标好得离谱

现象:R2 0.99 以上,但预测图明显不对。原因:归一化用了全量数据,或者划分时打乱了。解决:归一化参数只用训练集,划分严格按时间顺序。这是血泪经验,别问怎么知道的。

5.4 多变量输入维度对不上

现象:trainNetwork报维度错误。原因:sequenceInputLayer的numFeatures和X的维度不匹配。解决:多变量时X应该是[lookback, numFeatures, nSamples],numFeatures等于变量个数。reshape 时顺序别搞反。

5.5 预测结果全是同一个值

现象:YPred所有值几乎一样。原因:模型没学到东西,可能是lstmLayer单元太少,或者MaxEpochs不够。解决:隐藏单元加到 128,MaxEpochs加到 300,观察 loss 是否下降。如果还是不行,检查数据本身是否有规律。

6. 进阶技巧:用多步预测和残差分析验证模型

单步预测指标好看不代表模型有用,真正落地要看多步。多步预测有两种做法:递归预测和直接多输出。递归预测是拿预测值当输入继续预测,误差会累积;直接多输出是把fullyConnectedLayer的输出改成horizon维,一次预测未来多步。我一般先用递归跑 5 步看看误差累积速度:

horizon = 5; YPredMulti = zeros(horizon, size(XTest,1)); inputSeq = XTest; for h = 1:horizon yh = predict(net, inputSeq); YPredMulti(h, :) = yh'; inputSeq = [inputSeq(:, 2:end, :), reshape(yh, [1, 1, size(yh,1)])]; end

逻辑说明:每次预测后把新值拼到输入序列末尾,去掉最老的一个点。参数说明:horizon按业务需求定,设备寿命预测可能要看 10 步,金融时序看 1 步就够。跑完多步后,画误差随步数增长的曲线,如果第 3 步误差就翻倍,说明模型不适合长程预测。

残差分析是另一个后悔药。把YPred - YTest画出来,如果残差有周期性,说明模型没学到某个周期成分;如果残差在某个区间特别大,说明那段数据分布和训练集不一样。我习惯把残差图和预测图并排看,比单看指标有用得多。

最后说个习惯:每次跑完模型,我都会把lookback、隐藏单元数、学习率、四个指标存到一个表格里,跑十几组对比。LSTM 调参没有银弹,靠的是系统记录。希望帮到你。

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

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

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

立即咨询