CNN-LSTM时间序列预测基于卷积神经网络(CNN)-长短期记忆神经网络(LSTM)的时间序列预测 替换数据直接使用。 1、运行环境要求MATLAB版本为2020及其以上 2、评价指标包括:R2、MAE、MSE、RMSE等,图很多,符合您的需要 3、代码中文注释清晰,质量极高 4、测试数据集,可以直接运行源程序。 替换你的数据即可用 适合新手小白
江湖救急!刚入坑时间序列预测的新手总被模型结构搞懵?试试这个CNN-LSTM混合网络,直接把代码甩脸上跑起来。老规矩,先看效果再讲原理——我测试时随便找了个股票数据集,R2干到0.92,预测曲线和真实值贴得那叫一个亲密。
上硬菜!先看数据预处理部分(别怕,代码都带保姆级注释):
% 暴力加载你的数据集,把下面这行换成你自己的.mat文件路径 load('your_data.mat'); % 这里假设数据变量名为rawData,格式是N×1时序数组 % 数据标准化才是王道 [normalizedData, dataParams] = mapminmax(rawData', 0, 1); data = normalizedData'; % 滑动窗口造样本,窗口长度自己调 seqLength = 30; % 这个参数很重要!根据数据周期特性调整 X = []; Y = []; for i = 1:length(data)-seqLength X = [X; data(i:i+seqLength-1)]; % 输入窗口 Y = [Y; data(i+seqLength)]; % 输出值 end % 手把手拆分训练集和测试集 trainRatio = 0.8; splitPoint = floor(size(X,1)*trainRatio); XTrain = X(1:splitPoint,:); YTrain = Y(1:splitPoint,:); XTest = X(splitPoint+1:end,:); YTest = Y(splitPoint+1:end,:);这段代码的灵魂在滑动窗口——把时序数据切成一个个小窗口,相当于教模型认"时间局部特征"。比如设置seqLength=30,就是让模型每次看30个时间点的数据来预测下个点。
模型构建才是重头戏,看这个CNN接LSTM的骚操作:
layers = [ sequenceInputLayer(1) % 输入特征维度(单变量就是1) convolution1dLayer(3, 64, 'Padding', 'same') % 一维卷积核扫时间轴 batchNormalization % 防梯度爆炸神器 reluLayer maxPooling1dLayer(2, 'Stride', 2) % 降采样提取关键特征 lstmLayer(100, 'OutputMode', 'sequence') % 百维LSTM吃进时间特征 fullyConnectedLayer(50) % 全连接层做高阶组合 reluLayer fullyConnectedLayer(1) % 输出预测值 regressionLayer];这里有个坑要注意——LSTM层的输入需要保持序列结构!所以前面的池化层别把序列长度压没了。用MATLAB的trainingOptions配Adam优化器:
options = trainingOptions('adam', ... 'MaxEpochs', 200, ... 'MiniBatchSize', 64, ... 'InitialLearnRate', 0.001, ... 'LearnRateSchedule', 'piecewise', ... 'LearnRateDropPeriod', 100, ... 'Verbose', false);跑完训练后上评价指标,这四件套必须齐全:
% 预测并反标准化 YPred = predict(net, XTest); YPred = mapminmax('reverse', YPred', dataParams)'; YTest = mapminmax('reverse', YTest', dataParams)'; % 四大指标计算 R2 = 1 - sum((YTest - YPred).^2)/sum((YTest - mean(YTest)).^2); MAE = mean(abs(YTest - YPred)); MSE = mean((YTest - YPred).^2); RMSE = sqrt(MSE); % 画图三连击 figure subplot(3,1,1) plot(YTest,'LineWidth',1.5) hold on plot(YPred,'--') legend('真实值','预测值') subplot(3,1,2) scatter(YTest, YPred, 'filled') xlabel('真实值') ylabel('预测值') subplot(3,1,3) histogram(YTest - YPred, 20) title('预测误差分布')实际跑出来的效果看,在股价这种高波动数据上,测试集预测值与真实值的走势基本同步。误差分布直方图呈典型钟型,说明模型没抽风乱预测。
几个避坑指南:
- 输入数据记得做标准化,不然LSTM会训到怀疑人生
- 卷积核大小建议选奇数,方便对称填充
- 训练时如果loss震荡,把学习率调低一个量级
- 序列长度别设太长,一般取数据周期的2-3倍
替换数据时注意保持输入格式为N×1的列向量,遇到维度报错大概率是数据没转置。代码自带的测试数据集已做噪声处理,替换真实数据时建议先做异常值处理,毕竟现实数据比女朋友的心情还难预测。
最后说句大实话——没有哪个模型能通吃所有时序数据,但CNN-LSTM这个组合在大多数场景下都能打个七八十分。关键是理解代码每个模块的作用,数据质量到位了,调参才有意义。