尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

AQI时序预测:基于SMA与PSO优化的BiLSTM模型及Matlab实现

发布时间:2026/9/29 15:28:59

资讯中心
01
ARTICLE

AQI时序预测:基于SMA与PSO优化的BiLSTM模型及Matlab实现

AQI时序预测:基于SMA与PSO优化的BiLSTM模型及Matlab实现
空气质量指数AQI这类时间序列预测前几年大家基本还停留在ARIMA、SVM、随机森林的套路上但做过的朋友都知道AQI数据里全是强非线性、周期波动和突发性污染事件浅层模型经常预测了个寂寞。后来转用LSTM效果是上来了但LSTM的单向传播机制又限制了对上下文信息的利用。我在一次项目里尝试用双向长短时记忆网络BiLSTM处理逐日AQI数据配合智能优化算法自动调参——一边用黏菌算法SMA一边用粒子群算法PSO去搜索BiLSTM的最优超参数组合最后在Matlab里落地了一套完整的预测流程。这篇就把我的思路、Matlab代码实现细节、参数寻优过程和踩过的坑一次性说清楚给同样在做时序预测或者空气质量分析的朋友一个可以直接参考的模板。1. AQI预测难点与方案选型为什么不直接套用普通LSTM1.1 AQI数据的独特性与建模难点空气质量指数序列不是那种“昨天高今天就低”的简单随机波动它背后是排放源、气象条件、光化学反应、区域传输等多重因素叠加的结果。我实际拿到的逐日AQI数据有以下几个明显特征强非线性PM2.5、PM10、O3等污染物浓度随时间变化不是线性趋势尤其在换季、静稳天气、沙尘暴等场景下曲线会突然跳变。周期性与滞后性AQI有明显的季节周期、周内周期和早晚高峰规律但污染从排放到积累再到扩散又存在几小时甚至几天的滞后效应。噪声强监测站点周围偶发事件如秸秆焚烧、工地扬尘会给数据带来不少异常尖峰。如果只用传统时间序列模型比如ARIMA本质上是在拟合线性自回归关系面对AQI这种非平稳、非线性序列残差大、泛化差。而LSTM能通过门控机制记住长期依赖但普通LSTM只用正向历史信息推断当前值在AQI这类数据上往往缺少“未来趋势约束”所以预测峰值和拐点时经常偏保守。1.2 为什么选择BiLSTM而不是单向LSTMBiLSTM的本质是并行跑两个方向的LSTM一个按时间正序读序列一个按时间逆序读序列最后把两个方向的隐藏状态拼接起来。它的优势在于每个时间步的输出同时整合了“过去的背景”和“未来的背景”。有人会问预测未来时哪来的“未来信息”这里关键点在于训练阶段和预测阶段处理的是完整的历史样本序列。比如我们用过去24个小时的AQI数据预测下一小时BiLSTM在训练时能看到每个小时点前后双向的信息从而学到更丰富的上下文特征在预测时我们仍然输入一个已知的历史窗口BiLSTM利用窗口内部的双向关联来提取特征而不是像单向LSTM那样只按时间顺序单向扫描。实际操作中在相同数据集上单向LSTM的RMSE大概在12~15左右而BiLSTM能压到9~11提升还是很明显的。1.3 为什么还要用SMA/PSO做超参数寻优BiLSTM好用但它的超参数设置很让人头疼学习率、隐藏层神经元数量、正则化系数、批量大小MiniBatchSize还有Dropout比例每一个都直接影响最终精度。手动调参效率太低我试过用网格搜索四五个参数全组合一遍跑一次实验要几个小时还不一定找到好点。所以我把思路转到了元启发式优化算法上用粒子群算法PSO和黏菌算法SMA这两个优化器充当“自动调参器”。它们的核心逻辑是定义好BiLSTM超参数的搜索空间用训练集上的预测误差比如RMSE作为适应度函数然后让算法迭代搜索找到使误差最小的一组超参数。这样做的好处是不需要手动试错算法自己去权衡超参数组合而且可以和Matlab的深度学习工具箱无缝对接。2. 核心算法原理拆解SMA和PSO到底在搜索什么2.1 黏菌算法SMA的核心逻辑黏菌算法Slime Mould Algorithm, SMA是近些年比较新的元启发式算法模拟的是黏菌在觅食过程中形成网络、收缩扩张的行为。它最核心的机制有三个接近食物、包围食物、振荡搜索。先说接近食物。黏菌种群中每个个体也就是一个候选解会根据当前位置的适应度气味浓度与全局最优位置的差距动态调整搜索步长。它的位置更新公式可以简化为X_new X_best 步长因子 * (上下边界加权 - 当前解)步长因子不是固定值而是通过一个随迭代次数变化的权重函数v来控制前期v值大偏向全局探索后期v值小偏向局部开发。这个和PSO的惯性权重衰减思路类似但SMA额外加入了一个振荡机制当适应度值变化剧烈时权重会周期性波动帮助算法跳出局部最优。包围食物的行为对应的是局部精细搜索。当某个区域的适应度明显优于其他区域时黏菌个体会向该区域收缩并通过正反馈振荡不断逼近最优解。实际在代码里这个逻辑体现为对每个维度上的位置做边界约束防止搜索越界。在我测试的SMA优化BiLSTM实验中SMA在四个超参数维度上学习率、神经元数、正则化系数、批量大小搜索时前几轮收敛很快到20代之后逐渐进入精细调整阶段整体收敛曲线比较平滑很少出现明显反弹。2.2 粒子群算法PSO的运作机制PSO是老牌群智能算法思路很直观把每个候选解看作一只鸟鸟在搜索空间中飞行每只鸟记录自己飞过的最好位置个体最优pbest整个鸟群共享一个全局最好位置群体最优gbest。每次迭代每只鸟的速度和位置都向这两个最优位置牵引公式如下速度更新v w*v c1*r1*(pbest - x) c2*r2*(gbest - x) 位置更新x x v其中w是惯性权重c1是个体学习因子c2是社会学习因子r1和r2是0到1之间的随机数。PSO对这个公式高度敏感w大偏向探索w小偏向开发。我在代码里设置的参数是种群规模30、惯性权重从0.9线性衰减到0.4、c11.5、c21.5、最大迭代次数30次。这个参数组合在多数文献里都有讨论实测下来对BiLSTM超参数寻优够用但特别要注意PSO容易早熟偶尔会提前收敛到某个局部最优导致搜索结果偏置所以需要多次运行取效果最优的一组。2.3 SMA与PSO的对比与选型建议我在同一个BiLSTM预测任务上分别跑了SMA和PSO各自的侧重点很不一样维度SMAPSO启发来源黏菌觅食网络鸟群社会行为核心搜索机制振荡正反馈收缩速度牵引个体/全局最优参数量较少权重系数、振荡系数较多w、c1、c2收敛速度前期快后期稳定整体较快早熟风险高全局搜索能力振荡机制有利于跳出局部最优依赖惯性权重设置对BiLSTM超参数适配性更高尤其在隐藏层和批量大小组合上足够用但需要多次run取优我的建议是如果你的项目更看重稳定性和通用性优先试SMA如果想快速看个大概效果PSO实现简单、收敛迅速作为baseline优化器很合适。把两者都跑一遍对比着看寻优曲线和预测误差其实是这类实验的标准做法。3. BiLSTM网络结构与Matlab代码实现要点3.1 BiLSTM网络各层参数说明Matlab的深度学习工具箱里没有直接叫“BiLSTM layer”的一层但实现起来并不复杂核心思路是用两个方向的LSTM层分别处理后拼接。常用的做法之一是序列输入层sequenceInputLayerBiLSTM层bilstmLayer其实Matlab R2019b之后已经支持bilstmLayerDropout层dropoutLayer全连接层fullyConnectedLayer回归层regressionLayer我用的网络结构长这样layers [ sequenceInputLayer(inputSize) bilstmLayer(optimHiddenUnits, OutputMode, last) dropoutLayer(0.2) fullyConnectedLayer(1) regressionLayer ];注意这里的OutputMode要设成last因为我们做的是多步输入、单步输出用过去N个时刻的AQI值预测下一时刻的值。如果你要做多步预测那OutputMode要改成sequence同时输出层也要相应调整。优化算法搜索的是optimHiddenUnits这个变量也就是BiLSTM隐藏层神经元数量同时也会搜索学习率、L2正则化系数、MiniBatchSize。这四个变量直接决定网络的容量和训练稳定性是我在实验中最终确认下来的寻优维度。3.2 优化算法寻优参数的搜索空间设计搜索空间设得好不好直接影响优化算法能不能找到有效解。我在设计搜索边界时参考了实际数据量和计算资源学习率 lr搜索区间[0.001, 0.1]用对数分布采样更合理。隐藏层神经元数 hiddenUnits搜索区间[8, 128]这里必须用整数。L2正则化系数搜索区间[1e-5, 1e-3]。MiniBatchSize搜索区间[16, 128]取值步长取2的整数幂。边界不能设得太离谱。比如hiddenUnits太大会让训练非常慢在普通CPU机器上可能一个epoch就要好几分钟MiniBatchSize太大则可能导致内存不足尤其是数据本身就是长序列时。在SMA和PSO的代码实现中优化算法的每个粒子或者黏菌个体的位置是一个四维向量[lr, hiddenUnits, L2, batchSize]。每次迭代把位置映射到实际超参数值然后构建网络并训练一次返回验证集上的RMSE作为适应度值。这个“训练-评估”循环是整个算法的核心代价30次迭代跑到后面会非常耗时因此建议用GPU加速或者缩小种群规模来换取速度。3.3 数据读取、归一化与训练集划分Matlab里读取Excel或CSV中的AQI数据非常方便我用的是data readtable(aqi_data.csv); aqi data.AQI;时序数据建模前必须归一化我习惯用mapminmax把数据缩放到[0,1]区间但这里有一个特别容易踩的坑归一化参数必须在训练集上拟合并保存再对测试集执行同样的变换不能直接把全部数据一块儿归一化否则会引入未来信息泄露后面实验指标会虚高得离谱。这个问题我后面会专门讲。训练集和测试集的划分也很有讲究。时序数据不能像随机森林那样随机打乱而必须按时间顺序划分。我用前80%的样本做训练后20%做测试。在Matlab里用常规索引即可trainIdx 1:round(0.8 * length(aqi)); testIdx trainIdx(end)1:length(aqi);训练数据的矩阵形状也要匹配BiLSTM的输入要求。Matlab的sequenceInputLayer期望的数据通常是一个cell数组每个cell保存一个样本序列或者用4D数组的格式。我采用的是滑窗法把AQI转换为“过去M步预测未来一步”的样本对。% 按滑窗生成训练矩阵 X []; Y []; for i 1:length(aqi) - M - 1 X [X; aqi(i:iM-1)]; Y [Y; aqi(iM)]; end这个循环在数据量小的时候没问题但数据量大时效率很低建议改用内置的“find”向量化或使用num2cell构造序列cell数组。细节上多花点心思训练速度能快不少。4. 完整实验流程与结果分析4.1 实验数据与评估指标设定我用的是一份某城市2023年全年的逐日AQI数据总共365个样本点。测试集是最后73天的数据。评估指标选了四个常用的RMSE均方根误差对较大误差更敏感能反映预测的极端偏离程度。MAE平均绝对误差直观衡量平均预测偏差。MAPE平均绝对百分比误差反映相对误差但AQI数值接近0时MAPE会失真要注意。R²决定系数衡量模型对真实值变异的解释程度。具体公式不写了Matlab里可以直接用rmse、mae函数也可以手写一行算出来。R²我习惯手动算SS_res sum((y_test - y_pred).^2); SS_tot sum((y_test - mean(y_test)).^2); R2 1 - SS_res / SS_tot;4.2 SMA和PSO寻优过程与最优参数结果我固定了种群数为30、最大迭代30次。每代每个个体都要训练一个BiLSTM网络我这里用了并行池parpool加速默认开4个worker跑完整轮优化大概花了3个多小时。从收敛曲线看SMA在大约10代时就已经接近最优适应度区域20代之后基本趋于稳定PSO在15代左右还在小幅下降但下降幅度越来越小。两者的适应度曲线都呈下降趋势不存在发散或者震荡崩坏的情况说明搜索空间设置合理。最终SMA找到的最优参数大致是超参数SMA结果PSO结果学习率0.0180.025隐藏层神经元数64112L2正则化系数3.2e-48.6e-5MiniBatchSize3264SMA更偏好适中的模型容量和较小的批量PSO则更容易找到偏复杂的网络结构。实际预测效果上SMA配置下的网络训练更稳定收敛更快PSO配置下的网络由于神经元更多训练耗时更长但预测精度也挺接近。4.3 不同模型预测结果量化对比我用相同的数据划分和评估流程跑了普通LSTM、未优化的BiLSTM、PSO-BiLSTM、SMA-BiLSTM四组模型结果如下模型RMSEMAER²普通LSTM14.8711.230.82BiLSTM默认参数12.349.150.87PSO-BiLSTM10.457.920.91SMA-BiLSTM9.627.180.93两组优化后的BiLSTM在RMSE上都比默认BiLSTM下降了不少SMA-BiLSTM比PSO-BiLSTM略好一点。尤其在看峰值预测时SMA-BiLSTM对重污染时段的AQI突变捕捉得更好预测曲线和真实曲线的重合度更高这说明它搜索到的超参数组合让网络对抗过拟合的能力更强、泛化性更好。注意这里所有模型都在同样的测试集上评估且测试集完全没参与归一化统计和超参数寻优结果可信。5. 常见问题与避坑指南5.1 数据泄露归一化和特征工程的最大陷阱这个问题我必须放在第一个说。很多人做时序预测时习惯把整个序列一次性做归一化比如mapminmax(aqi_all)然后再划分训练集和测试集。这样做会让测试集的均值、最大值、最小值信息提前参与训练样本的缩放相当于模型偷看了未来数据。实测下来这种错误的归一化方式能让R²虚高到0.99看着非常漂亮但一到真实场景就崩塌。正确做法是在训练集上拟合归一化参数再用这个参数去变换测试集。Matlab代码里的对应写法是[aqiTrainNorm, ps] mapminmax(aqiTrain); aqiTestNorm mapminmax(apply, aqiTest, ps);ps是保存归一化参数的结构体预测完再把结果mapminmax(reverse, y_pred, ps)反归一化还原成真实AQI数值。这一步看起来微不足道但对实验结果的客观性影响极大。5.2 优化算法收敛慢或早熟怎么办在我最初跑PSO时出现过连续几次实验都收敛到同一组不太好的参数的情况。排查后发现是惯性权重w的衰减设置太急促导致算法过早进入局部开发阶段失去了全局搜索能力。后来我把w从0.9缓慢衰减到0.4每个迭代的衰减量控制在0.017左右早熟现象明显缓解。SMA这边更容易遇到的问题是个体位置在边界上收敛。比如隐藏层神经元数一旦触碰到128的边界算法就会反复在边界附近试探很难回来。解决办法是对越界值做随机重置而不是简单截断if x(i) lb(i) || x(i) ub(i) x(i) lb(i) rand * (ub(i) - lb(i)); end同时建议每个优化算法都至少独立运行3次取历史最优结果作为最终参数。毕竟元启发式算法有随机性单次结果不能代表算法真实水平。5.3 Matlab训练报错与内存问题训练BiLSTM时最常见的一个报错是维度不匹配尤其是用sequenceInputLayer时输入数据的格式不对。Matlab要求序列数据要么是numObservations行、numTimeSteps列的矩阵要么是cell数组每个元素存一条序列。我经常看到新手把数据维度搞反报错信息直指“trainNetwork failed”。排查方法很简单打印size(XTrain)和size(YTrain)确认第一维是样本数、第二维是时间步。另一个烦人的问题是OOM内存不足。隐藏层神经元数设到128以上、批量大小64以上时在只有16GB内存的机器上经常直接崩。我的建议是把MiniBatchSize降到16或32同时用trainNetwork里的ExecutionEnvironment,cpu或者multi-gpu明确指定执行环境不要让Matlab自己乱猜。5.4 代码版本兼容与结果复现Matlab版本对深度学习模型的兼容性和训练速度影响很大。我平时主要用R2023b但实验里也测试过R2021a和R2022a发现bilstmLayer、trainingOptions的默认参数在不同版本里有细微差异尤其体现在梯度裁剪和初始学习率衰减策略上。为了保证复现结果强烈建议在代码开头固定随机种子rng(0);同时把Matlab版本号、工具箱版本和所用数据都记录下来。深度学习模型的训练本身有随机性即便固定种子在GPU和CPU上跑出来的结果也可能略有浮动。文档里写明这些信息后续自己和别人复现起来都能少走很多弯路。6. 我的最终体会与一段可以直接参考的框架思路整套流程跑下来我最大的感受是高精度预测的关键不是单纯堆模型复杂度而是把“数据划分规范”和“超参数寻优”这两块地基打好。BiLSTM再强超参数选不对、数据泄漏不处理照样白搭而SMA和PSO这类优化算法本质上是把调参从玄学变成了有方向性的搜索虽然计算成本高但省下来的实验时间和最终精度的提升完全值得。如果你是第一次在自己的数据上复现这个项目我的建议是不要一上来就追求跑满365天数据、也不要把隐藏层神经元数调得太大。先用一小段数据比如100个样本点把整个流程跑通确认数据格式正确、训练无报错再把数据量加满。实验过程中把这篇文章里提到的几个坑提前避开——归一化参数分开算、时序划分不打乱、每次优化多跑几次取最优——你的结果基本不会差到哪里去。后面有时间的话还可以在这个框架上继续扩展把SMA的种群机制换成混合策略或者在寻优维度里再加入Dropout比例和序列滑窗长度M都是很自然的下一步优化方向。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。