简介:多元时间序列预测Python大作业项目源码,围绕时间序列预测核心任务展开,面向高校计算机、数据科学等专业需要完成课程设计或毕业设计的学生。项目覆盖ETT、天气、电力、交通、汇率等常见基准数据集,包含数据处理、模型定义、训练评估等完整流程,代码均已本地编译验证,难度适中,方便学习与二次改造。压缩包内共56个文件,以30个py代码文件为主体,配合19个sh实验脚本便于批量运行,另有png结果图、docx使用手册和pdf论文供对照理解。包体约548KB,目录按main、models、exp、data_provider等模块组织,结构清晰。目前已有414人浏览学习,对想要快速上手多元时间序列预测、准备高分课程项目的读者而言,是不错的参考素材。
1. python 多元时间序列预测大作业:这份源码不是示例代码,而是一套能直接跑通的完整工程
如果你正在找一份 python 多元时间序列预测的大作业源码,而不是另一篇贴几个公式就完事的模型讲解,那么这个 zip 值得在解压前先读完这篇拆解。它包含 DSTLinear 论文 PDF、模型实现、多个数据集的训练入口脚本,从 ETTh1、ETTm2 到 Electricity、Traffic、Weather、Exchange Rate,覆盖了多元时间序列预测课程设计里最常见的任务类型。
我拆过不少这类资源,最直观的感受是:模型代码只占整个工程的一小部分,真正决定能不能拿高分的是配套的数据加载、训练调度和评估模块。这份 zip 恰好把这三块都补齐了,难度定位适中,适合用来做本科大作业、研究生课程设计,或者给想跑对比实验的人当 baseline。
补充一句容易被忽略的:多元时间序列预测的分数很大程度不取决于模型结构多花哨,而取决于数据处理和超参调优是否细心。下面我从源码结构开始拆,把「能跑」和「跑得明白」都讲清楚。
2. 源码结构拆解:从 data_provider 到 models,一条完整的数据流水线
2.1 解压后先认目录:根目录和 code 目录各放什么
打开 zip 之后,你会看到根目录有一份 DSTLinear.pdf 和一份手册.docx,前者是对应模型的论文原文,后者是大作业配套的报告模板。code 目录才是真正要运行的代码主体。
| 路径/文件 | 作用 |
|---|---|
| code/models | 模型定义目录,DSTLinear 及其变体在这里实现 |
| code/data_provider | 数据集读取与预处理模块,提供统一的数据接口 |
| code/exp | 训练、验证、测试的调度代码,记录 loss 和保存模型 |
| code/utils | 工具函数,主要是早停机制等训练辅助逻辑 |
| code/run_longExp.py | 批量实验入口,把多组超参配置串起来跑 |
| code/main.py | 通用训练入口,适合自定义数据或模型时启动 |
| code/main_etth1.py / main_etth2.py | ETTh1、ETTh2 这两个小时级数据集各自的入口脚本 |
| code/main_ettm1.py / main_ettm2.py | ETTm1、ETTm2 这两个 15 分钟级数据集的入口脚本 |
| code/main_electricity.py / main_traffic.py | 电力、交通数据集的入口脚本 |
| code/main_weather.py / main_exchange_rate.py / main_ill.py | 天气、汇率、ILI 流感数据集的入口脚本 |
| code/main_complixity.py | 复杂度分析脚本,用来统计模型参数量和推理耗时 |
注意 main_complixity.py 这个文件名里的 complixity 拼写是仓库原本就有的,运行和阅读都不受影响,不用刻意改正。这些入口脚本逻辑几乎一致,区别只在数据路径、通道数和归一化方式,所以看懂一个 main_etth2.py,其他脚本本质上就都通了。
2.2 data_provider:数据如何被处理成模型输入
多元时间序列预测的第一步是把原始 csv 变成模型能吃的张量。data_provider 的核心逻辑通常是:读入 csv,取目标列,按时间顺序切分成 train / validation / test 三段,再做滑窗。
几乎所有的 LTSF(Long-term Time Series Forecasting)风格仓库都会遵循同一套接口约定:Dataset 返回 seq_x(历史序列)和 seq_y(未来序列),其中 seq_x[i] 的形状是 [seq_len, num_variables],seq_y[i] 的形状是 [pred_len, num_variables]。可以把它理解成一个「窗口滑动器」,每一次获取样本时都从原始数据里切出一对输入输出。
需要特别关注的是归一化位置。不同脚本的差异在这里也能体现出来:有的数据集按全局均值方差归一化,有的按每个通道分别归一化。推荐的做法是在原始训练段上计算均值和方差,验证集和测试集复用同一组统计量,否则会引入数据泄露,导致评估分数虚高。
2.3 exp 与 utils:训练调度和早停机制的配合
exp 目录承担的是真正让训练跑起来的职责。它内部通常会维护一个模型实例、一份优化器、一个早停计数器,以及训练循环和测试循环。训练循环里按 batch 喂数据、算 loss、反向传播;测试循环里用保存下来的最优模型预测,并输出 MAE 和 MSE。
utils 目录里的早停逻辑是时间序列项目比较关键的部分。它的作用是:如果连续 N 个 epoch 验证 loss 没有下降,就停止训练并恢复之前最优的一版权重。这套代码里做得比较完整,跑长序列任务时能省下大量无效训练时间。
第一次跑通后,建议把 exp 里每个 epoch 的 train loss、val loss 打印行保留,写大作业报告时直接从日志里截图使用,比事后补数据真实得多。
3. 模型设计与选型逻辑:DSTLinear 论文 PDF 在代码里怎么落地
3.1 多元时间序列预测的任务定义与 DSTLinear 的核心思路
先明确任务定义。多元时间序列预测的目标是:给定过去 seq_len 个时刻的多元观测值,形状为 [seq_len, C],预测未来 pred_len 个时刻的观测值 [pred_len, C],其中 C 是变量通道数。ETTh2 是 7 个温度相关通道,Electricity 是 321 个用电通道,Traffic 是 862 个道路占用率通道。
DSTLinear.pdf 对应的是一种基于线性分解思路的预测模型。它整体上沿着「长序列预测用线性模型也足够强」这条技术路线,把时间序列分解成趋势分量和周期分量,分别建模。LTSF-Linear 系列论文就提出过一个反直觉结论:在很多长序列基准上,简单线性层可以打败复杂的 Transformer 模型。DSTLinear 在这条路上继续往前走,重点强化了对序列中周期性结构的利用。
放到代码里落地时,模型接受 [B, seq_len, C] 的输入,经过内部处理后输出 [B, pred_len, C],中间不把时间步变成词向量,也不做自注意力。这带来一个现实的好处:显存占用远小于同规模的 Transformer,课设机器有 8GB 显存就基本够用。
3.2 六个数据集入口脚本的差异:频率、通道数、归一化
| 脚本 | 数据频率 | 典型通道数 | 训练脚本里需要注意的点 |
|---|---|---|---|
| main_etth1.py / main_etth2.py | 1 小时 | 7 | 温度序列尺度接近,建议做标准化 |
| main_ettm1.py / main_ettm2.py | 15 分钟 | 7 | 序列更长,训练时间约为 ETTh 的 4 倍 |
| main_electricity.py | 15 分钟 | 321 | 通道维大,batch 要适当调小 |
| main_traffic.py | 1 小时 | 862 | 稀疏程度高,loss 波动较大 |
| main_weather.py | 10 分钟 | 21 | 变量量纲差异大,按通道归一化更稳 |
| main_exchange_rate.py | 1 天 | 8 | 样本量很小,验证集别留太大 |
| main_ill.py | 周 | 7 | 流感数据非平稳性强,建议多跑几个 seed 取平均 |
这些脚本里模型类是公用的,大多数情况下它们只是把 data_path、features、seq_len、pred_len 等参数以不同方式传入同一个训练函数。改作业时最常做的操作就是复制 main_etth2.py、改几个参数、换数据集,models 目录一行都不用动。
3.3 一组能用的默认超参:先跑通,再谈调优
这套仓库的默认配置集中在入口脚本底部的参数区,第一次跑的时候直接用默认值,没做任何调整就能得到正常下降的训练曲线。下面是一组参考值:
| 参数 | 默认值参考 | 说明 |
|---|---|---|
| seq_len | 96 | 输入窗口长度,取 96 个历史时刻 |
| label_len | 48 | 解码器前缀长度,很多线性模型不用也能跑 |
| pred_len | 96 | 预测长度,也是大作业里最容易改的指标 |
| batch_size | 32 | 显存不足就降到 16 或 8 |
| learning_rate | 0.001 | 训练后期可以衰减到 0.0005 |
| patience | 3 | 验证集连续三轮不降就停 |
| loss | MSE | 时间序列预测最常用的回归损失 |
一个容易被忽略的点是 features 参数,它控制模型是只预测目标列(单变量)还是预测全部通道(多变量)。做大作业建议直接用多元预测,只有这样才能体现「多元时间序列」这个题目的工作量。调参优先级上,pred_len 对结果影响最大,其次是 batch_size 和数据归一化方式,最后才是学习率微调。
4. 环境与运行:装好依赖、放对数据,然后用一个命令跑出 train loss
4.1 用 conda 隔离环境,避免依赖打架
拿到资源后不建议直接在系统 Python 里 pip install,常见做法是先用 conda 建一个干净环境:
conda create -n mtsf python=3.8 -y conda activate mtsf pip install numpy pandas scikit-learn matplotlib pip install torch --index-url https://download.pytorch.org/whl/cu118torch 这一条按自己的显卡驱动选择,如果机器没有 NVIDIA GPU,把安装源换成 CPU 版本即可。numpy、pandas、scikit-learn 这三个是数据读取和预处理必需的依赖,matplotlib 用于画预测曲线。
为什么单独建环境这么重要?因为时间序列项目对 pandas 和 numpy 的版本比较敏感,系统环境里往往装有机器人、爬虫等其他项目的旧版本包,pip 解析依赖时容易把版本升级到不兼容的状态。独立环境里即使装坏了,删掉重来也就一两分钟,不会影响其他项目。
依赖装完后,先在 code 目录下执行一次:
python main_etth2.py --help这一步的目的是确认脚本接受的参数名。不同仓库的参数拼写有小差异,有的用 --seq_len,有的用 --input_len,先跑 help 能避免后面照着命令敲结果报 unrecognized arguments。
4.2 数据集的目录约定:运行前唯一必须手动做的事
接下来是整套资源里最容易踩坑的一步:数据集位置。多数时间序列仓库的代码会在某个配置变量里写明 root_path 和 data_path,例如 root_path='./data/ETT/'、data_path='ETTh2.csv',最终拼接出的完整路径是 ./data/ETT/ETTh2.csv。
如果你解压后没有看到 data 目录,需要自己建一个,把对应 csv 放进去。具体路径以脚本里的定义为准,这里给的是最常见约定。放好后重新运行,如果代码正确读取到了数据,终端会打印出数据集长度信息。
有一个细节容易被忽略:脚本内部通常不会自动下载数据集,找不到文件时只会抛 FileNotFoundError。所以「数据放进 data 目录」这一步优先级高于任何参数调优,数据都没读进来谈模型效果没有意义。
4.3 跑通第一个完整实验:用 main_etth2.py 复现一次训练
以 ETTh2 数据集为例,运行:
cd code python main_etth2.py --model DSTLinear --pred_len 96 --batch_size 32如果脚本的默认参数里已经包含这些值,这一步其实等价于直接 python main_etth2.py。训练开始后,终端会按 epoch 输出 train loss 和 val loss。第一次跑的时候不要去调任何参数,先观察 loss 是否逐轮下降,以及是否能在合理时间内完成一个 epoch。
一个 epoch 的耗时差异很大:CPU 上 ETTh2 可能几分钟到十几分钟,GPU 上通常在几十秒内。如果时间实在紧张,可以先临时把 seq_len 改成 48、pred_len 改成 48,验证整套流程能跑通,再恢复默认值做完整训练。这种方式特别适合交作业前做冒烟测试,避免最后一天才发现代码根本跑不起来。
4.4 用 run_longExp.py 一次性串起多组实验
很多课程作业要求对比至少两组超参或两个模型,这时候一条条命令跑既慢又容易漏。run_longExp.py 的作用就是把多组实验串起来,内部按顺序执行训练并汇总输出。
我一般会这样用:在 run_longExp.py 里找到实验配置列表,把 pred_len 依次改成 96、192、336,然后一次运行,睡一觉第二天早上收结果。这种批量方式比手动改参数重跑要稳得多,而且跑出来的多组 loss 记录天然就是大作业报告里的对比表素材。
5. 常见问题与排查:解压、依赖、路径、显存与结果波动
5.1 解压 zip 后文件名乱码,甚至找不到对应目录
现象:用 Windows 自带解压工具解压后,文件名变成乱码,或者 code 目录结构不完整;用代码读取路径时直接报错。
原因:zip 文件内部对中文文件名的编码不统一,旧工具按 GBK 写入时,新版解压软件会按 UTF-8 去解码,产生乱码;严重时整个目录结构都会错位。
解决:不要用系统自带解压,改用支持编码选择的工具,解压时指定 GBK。这个坑我碰到过不止一次,特别是资源里带手册.docx 这类中文文件名时乱码概率更高。解压完成后先检查 code 目录完整,再继续往下走。
5.2 ModuleNotFoundError:缺包和版本错位分不清
现象:python main_etth2.py 一运行就报 ModuleNotFoundError: No module named 'sklearn',或者报 numpy 里某个函数不存在。
原因:前者是环境里确实少装依赖;后者多半是 numpy 版本太新,某些老代码使用的 np.float 之类写法被移除了。
解决:先 pip install scikit-learn,再检查预处理相关代码里有没有 np.float、np.int 这类旧写法,有的话改成 float 和 int。这类版本兼容问题最让人头疼,但也最好排查:报错信息里的文件名和行号会把位置指得很清楚,按行号定位就行。
5.3 FileNotFoundError:数据路径和大小写都有可能是元凶
现象:训练脚本启动几秒后报错,错误信息里完整路径最后指向一个不存在的 csv。
原因:脚本的工作目录不对,或者路径大小写不一致。很多仓库里写的是 ETTh2.csv,Windows 大小写不敏感所以能过,Linux 下就找不到文件。
解决:始终从 code 目录启动训练,不要从外层目录用 python code/main_etth2.py 运行。如果还报错,把脚本里的 root_path 和 data_path 打印出来,对照实际文件路径检查一遍,这是最直接的定位方式。
5.4 CUDA out of memory:显存不够不一定要换显卡
现象:训练第一个 epoch 中途崩掉,报 CUDA out of memory,有时还伴随 RuntimeError。
原因:默认 batch_size 和 seq_len 在低显存显卡上占用超限,尤其是 Electricity 这种 321 通道的数据集,张量体积比 ETTh2 大一个量级。
解决:优先把 batch_size 从 32 降到 16,还不行就降到 8;再不行就把 seq_len 从 96 降到 48。一般降到 8 之后,除了 Traffic 这种通道特别多的数据集,大部分都能在 8GB 显卡上跑起来。训练速度慢一点无所谓,能跑完才是大作业的底线。
5.5 指标忽高忽低,复现不出稳定结果
现象:同一份代码连续跑两次,MSE 有高有低;或者用默认参数跑出的结果和资源里截图差距明显。
原因:没有固定随机种子,PyTorch 的模型初始化、数据 loader 的采样顺序都不确定。另一个隐藏原因是数据归一化时用了全量数据的均值方差,而不是只用训练段统计,导致验证集信息混进训练过程,分数虚高。
解决:在训练前固定种子,最低限度设置 Python 和 PyTorch 两边:
import random import numpy as np import torch def set_seed(seed): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed)多跑三个种子取平均,结果才敢写进报告。这算是我做过时间序列项目后最深刻的教训:不看标准差只看单次 loss,等于靠运气交作业。
6. 进阶用法:画预测曲线、换预测长度,把实验做成报告素材
6.1 先画预测图,再信指标数字
MSE 和 MAE 是数字,但数字不能告诉你模型到底在预测趋势还是在复读最后一个值。我拿到一份时间序列项目源码后,第一件事是把它跑通,第二件事就是找到预测结果张量,画一张真实值 vs 预测值的对比图:
import matplotlib.pyplot as plt plt.figure(figsize=(12, 4)) plt.plot(true_values[:96], label='ground truth') plt.plot(pred_values[:96], label='prediction') plt.legend() plt.savefig('prediction_check.png', dpi=150)如果预测曲线几乎是把输入序列尾部平移复制下来,说明模型退化成了「抄近道」方案,指标再好看也不能用。真正有效的预测会在一开始有一点滞后,但中段之后能跟上真实序列的波动节奏。这是一条非常硬核的验收标准。
6.2 改 pred_len 做多步预测,顺便拿对比数据填报告
把 pred_len 从 96 改成 192 和 336,各跑一遍,你会得到一组「预测长度越短误差越小」的典型曲线。这组对比实验放在大作业报告里,比任何描述都有说服力。调优顺序建议是:先保数据正确,再固定 seed,接着调 pred_len,最后才碰学习率。
从那以后,我每次跑时间序列项目都强制自己走一遍「跑通-画图-换长度」三步,不再盯着单次 loss 自嗨。这份资源里的代码和论文 PDF 足够支撑你把它讲清楚,剩下就看你要不要把它真正落到自己的实验里了。希望帮到你。
本文还有配套的精品资源,点击获取