目录
多步预测案例
原理简介
①分块嵌入
②通道独立
③实例归一化
结果展示
完整代码获取方式
这两年只要做多变量时序预测,翻来覆去还是CNN、LSTM、GRU这老三样。审稿人看到摘要里是这几个模型,往往直接贴上缝合、增量的标签,创新点越挖越浅,确实难写。
因此,今天给大家带来一期基于PatchTST的多变量时序多步预测Python代码。这是发表在机器学习顶会ICLR 2023上的工作,作者来自普林斯顿大学与IBM研究院。它与iTransformer是同一时期、思路互补的两个SOTA代表作,目前在知网和SCI上的应用文献同样非常少,可以说,你先用,你就是创新。
本代码适用于风电光伏功率、电力负荷、碳价、交通流量、空气质量、股票期货、降水量等一切多变量时间序列多步预测场景,只要是用多个特征列预测最后一列的未来值,全部都能用。最关键的是,我们已经将复杂的源代码转换成可以一键替换Excel数据、注释清晰、适合新手小白学习的代码格式。
需要完整代码的朋友可直接拉到最后~
您只需做的工作:替换Excel数据,一键运行文件!非常适合新手小白!
多步预测案例
这里我们用一份典型的多变量时间序列数据集进行演示,共1500条样本,包括5个特征列加1个输出列。
更换自己的数据时,只需最后一列放想要预测的列,其余列放特征即可,特征数量不限,无需更改代码。时间列可以保留也可以删除,程序会自动剔除非数值列,非常方便!
同时,本代码采用的是直接多步预测策略,即一次性输出未来多个时刻的预测值。代码中默认设置回看窗口为96,预测步长为3,您也可以根据自己的需求修改为1步、4步、12步、24步等任意步长,只需改一个参数!
原理简介
如果有小伙伴想要拿这个模型写论文,下面的文字都是可以借鉴和参考的!
为方便阅读,下文统一约定:回看窗口长度记为大写L,变量数也就是通道数记为大写M,待预测的未来步长记为大写T,模型隐藏维度记为大写D。
①分块嵌入
这是PatchTST最核心、也是论文标题所指的地方。它不再以单个时间点作为token,而是沿时间轴将序列切成一段段子序列,也就是patch,每个patch整体作为一个token送进Transformer。设patch长度为P,相邻patch的滑动步长为S,则分块后得到的patch数量为:
切块前会在序列末尾用最后一个值重复填充S个,以保证整除。随后,每个patch通过一个可训练的线性投影映射到D维隐空间,并叠加可学习的位置编码以保留patch的时序先后:
其中,投影矩阵把每个长度为P的patch映射为一个D维token,位置编码用于标记patch之间的先后顺序,得到的结果即送入Transformer编码器。
②通道独立
在面对多变量输入,PatchTST没有把所有变量混在一起,而是沿通道维把它们拆开,让每个变量构成一条单变量序列,再各自独立地切块、独立地送入同一个Transformer主干。这里的注意力作用在同一变量的不同patch之间,模型专心学习一个变量自身的时序演化。其数学表达为:
其中,第i条单变量序列的长度为L,i从1取到M。
③实例归一化
除上述两大核心外,PatchTST还沿用了一个对付非平稳性的实例归一化技巧。时间序列数据普遍存在均值、方差随时间漂移的现象,模型在训练集学到的分布到了测试集便对不上。为此,它在模型输入端对每个样本、每个通道独立做一次归一化,把统计量暂存下来,待模型输出端再反归一化恢复:
其中,均值与方差均取自该通道当前输入序列的统计量,分母里的小常数用于防止除零。这一策略进一步缓解了分布漂移带来的精度下降问题。
结果展示
我们在上述数据集上进行测试,模型超参数设置为:回看窗口96,预测步长6,patch长度16、滑动步长8,d_model为128,注意力头数8,编码器层数3,最大迭代次数50,Adam优化器加余弦退火学习率调度,划分70%训练集、10%验证集、20%测试集,并启用早停机制防止过拟合。
首先看下单步预测的效果,也就是1步:
可以看到预测曲线紧贴真实曲线,几乎没有滞后现象。再来看下3步:
效果也非常不错,与单步几乎无异,再来看下更长的6步:
效果也非常好,精度也只下降了一点点,这也是正常现象。
然后是预测值与真实值的散点图,散点紧密贴合在理想拟合线周围:
误差直方图:
训练与验证损失曲线,验证损失稳步下降并收敛,没有出现过拟合:
测试集评估指标柱状图,一目了然:
最后,命令行窗口也会清晰地显示R²、RMSE、MAE、MAPE四项核心误差指标:
在演示数据集上,R²达到了0.97以上,MAPE仅2%左右,效果非常不错!
更贴心的是,我们的程序文件夹内极其干净,没有任何乱七八糟的东西,您所需运行的文件只有main.py一个!并且代码中关键步骤的注释非常详尽,每一个超参数都标注了含义和调参建议,可以说非常适合新手小白学习与使用。
并且代码中关键步骤的注释非常详尽,每一个超参数都标注了含义和调参建议,可以说非常适合新手小白学习与使用。
data_path = "数据集.xlsx" # 数据文件路径(xlsx),前面几列为特征,最后一列为预测目标 seq_len = 96 # 回看窗口长度,模型用过去多少步的数据来预测未来 pred_len = 6 # 预测窗口长度,模型一次性预测未来多少步 train_ratio = 0.7 # 训练集比例 val_ratio = 0.1 # 验证集比例(用于早停和挑选最优模型) # test_ratio = 0.2 (剩余) # 测试集比例 = 1 - train_ratio - val_ratio # 模型超参 patch_len = 16 # patch长度,每个patch包含多少个时间步 stride = 8 # patch滑动步长,stride<patch_len则相邻patch有重叠 d_model = 128 # 模型隐藏维度,每个patch被映射到的维度大小 n_heads = 8 # 多头注意力的头数,d_model必须能被它整除 e_layers = 3 # 编码器堆叠层数,越深表达能力越强但也越容易过拟合 d_ff = 256 # 前馈网络中间层维度,一般取2~4倍的d_model dropout = 0.1 # 丢弃率,防止过拟合 activation = "gelu" # 激活函数,可选 "gelu" 或 "relu" # 训练超参 batch_size = 32 # 批大小,显存不足时调小 epochs = 50 # 最大训练轮数 learning_rate = 1e-4 # 初始学习率,配合余弦退火调度器衰减 patience = 10 # 早停耐心值,验证集连续多少轮无改善就停止训练 use_amp = False # 是否启用混合精度训练(当前未启用)另外,本代码纯PyTorch实现,无需任何外部预训练模型,CPU、GPU均可运行,程序会自动检测,普通笔记本电脑也能跑得动!相比那些动辄要配cuda、配虚拟环境、装一堆依赖才能跑通的开源项目,本代码真正做到了开箱即用。
完整代码获取方式
1、只想要文章中PatchTST单品的同学,可以查看链接:
https://mbd.pub/o/bread/mbd-YZaTlp5ubA==2、本文代码已加入多步预测全家桶中,点击下方小卡片,再后台回复关键词:
多步预测全家桶