news 2026/10/2 2:45:38

LSTM时间序列预测Python代码实现:从数据处理到模型搭建全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LSTM时间序列预测Python代码实现:从数据处理到模型搭建全解析

简介:这是一份面向高校课程设计与期末大作业的LSTM时间序列预测Python项目源码,适合具备Python基础、希望快速上手深度学习预测任务的在校学生参考。项目已获高分通过,包含完整可运行代码、公开数据集与说明文档,覆盖数据预处理、模型训练、评估与结果可视化等关键环节。压缩包共31个文件,以Python脚本、CSV数据文件、PNG图表及工程配置文件为主,整体大小28.48MB,目录结构清晰,便于直接部署和二次修改;其中14张PNG结果图可直观查看预测曲线与误差情况,3个CSV数据集支持多场景验证。代码中不仅实现了LSTM模型,还额外提供RNN与Transformer对比实现,方便分析不同循环结构在预测任务上的表现差异;数据集涵盖电力负载、污染物等多类时间序列,有助于验证模型的泛化能力。目前已有1026人学习该资源,说明其在实际作业和课程设计中具有较高参考价值。下载后按说明配置环境即可运行,既可作为期末作业的完整模板,也能用于答辩演示或进一步研究的基础。

1. 拿到这个期末大作业压缩包,先搞懂 LSTM 时间序列预测到底在做什么

如果你下载过一个名字叫「时间序列预测(LSTM模型)python代码实现源码(期末大作业).zip」的压缩包,多半是要交一门机器学习的课程设计。里面通常是一段 Python 脚本、一组历史数据、几张预测曲线图,外加一份实验报告模板。你要做的不是把代码跑通就交,而是能讲清每一步在干什么、参数为什么这么设、预测结果为什么长这样。LSTM 时间序列预测的核心,是用过去一段连续观测值去预测未来若干个值——比如用过去 30 天的客流量预测明天的数值。它和普通回归最大的区别是:数据有前后依赖,顺序不能乱,时间窗口决定模型能看到多远的“记忆”。这篇文章按照我实际做过的期末大作业和工业小项目的经验,把从数据处理、模型搭建到最终出图的完整路径拆开讲,新手能照着复现,熟手也能对照检查自己的参数和边界。

2. 读懂 LSTM 预测代码前,先把数据形态和时间窗口这两个地基打牢

很多同学拿到的源码第一眼是懵逼的:reshape、look_back、MinMaxScaler满天飞。其实这些都是在解决同一个问题——把普通表格数据变成 LSTM 能吃进去的“序列样本”。先把这个弄明白,后面所有代码都顺了。

2.1 单变量还是多变量:先看你的 CSV 长什么样

打开压缩包里的数据文件,最常见的两种格式:

  • 单变量:只有一列数值,比如某日客流量、某设备温度、某股票收盘价。你要预测的就是这一列的未来值。
  • 多变量:有多列,比如天气、湿度、节假日标记,外加一个目标列。模型要用这些特征一起预测目标。

LSTM 的输入张量形状是(样本数, 时间步长, 特征数)。单变量时特征数是 1,多变量时特征数是列数。源码里如果有data[:, 0]这种切片,说明它只取了第一列,属于单变量预测。如果你手里的数据有多列,却只喂一列,等于白白扔掉了辅助信息。

处理时我一般先打印数据概览,确认有没有缺失值和异常值:

import pandas as pd df = pd.read_csv('data.csv', encoding='utf-8') print(df.head()) print(df.info()) print(df.isnull().sum())

这里的head()看前五行结构,info()看列类型和数量,isnull().sum()检查空值。如果有缺失,常见做法是前一行的值填充,或者线性插值,千万不要直接删行——时间序列一旦删行,时间间隔就乱了。如果数据里有日期列,建议先解析成datetime类型并设为索引,后面画图时 x 轴才正常。

2.2 时间窗口(look_back)怎么选:3 个必调参数和一组经验值

时间窗口,也叫look_back或seq_len,是指用过去几个时刻的数据预测当前时刻。源码里通常有一个全局变量:

look_back = 10 # 用前10个时刻预测当前时刻

这个值直接决定了模型能看到的“记忆长度”。选太大,模型参数量增加、训练变慢,而且可能引入过多噪声;选太小,模型看不到周期性。三个相关参数:

  • look_back:时间步长。对日级别数据,如果存在周周期,至少取 7;月周期取 30。
  • n_features:输入特征数,单变量填 1。
  • n_outputs:预测目标数的另一种写法,常见于多步预测,源码里可能没有。

经验值:数据点只有几百条时,look_back取 5~15 比较稳;数据量上千,可以取 20~60。别一上来就搞 100,样本数会被压得很少——因为每个样本要连续look_back个点,能构造出的样本总数是len(data) - look_back。窗口越大,可训练样本越少,二者是矛盾的。

2.3 数据归一化为什么必须做:MinMaxScaler 的用法与反归一化

LSTM 用的是 tanh 和 sigmoid 激活函数,对输入数值范围很敏感。如果原始数据是几千的大数,梯度会爆炸或消失,loss 根本降不下去。源码里出现MinMaxScaler就是干这个的:

from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1)) scaled_data = scaler.fit_transform(df['value'].values.reshape(-1, 1))

注意两件事。第一,fit_transform只能用在训练集上,测试集要单独transform,不能重新fit,否则测试集的信息会泄露到训练过程里。第二,预测出来的结果也是 0~1 之间的缩放值,要看到真实数值,必须做反归一化:

predicted = model.predict(X_test) predicted = scaler.inverse_transform(predicted)

我见过不少大作业就是忘了最后这一步,画出来的预测曲线全在 0 到 1 之间,和真实曲线差一个数量级,直接扣分。另外,如果时序数值波动剧烈,也可以考虑StandardScaler,但 LSTM 配 MinMax 是最常见、最不容易出错的组合。

3. 用 PyTorch 还是 TensorFlow/Keras 实现:以 Keras 为例把模型搭起来

压缩包里的模型实现,大概率是 Keras 或 PyTorch 二选一。先说结论:期末大作业图省事,Keras 的Sequential最直接;如果想在报告里多写点自定义结构,PyTorch 更灵活。但无论哪种,核心的 LSTM 层定义思路是一致的。

3.1 二选一之前,先看期末大作业最常见的打分点

一般老师评分的点无非这几个:能跑通、预测曲线和真实曲线贴合、有 loss 曲线、有模型结构说明、有参数分析。用 Keras 写十几行就能搭完,不容易在框架语法上翻车。PyTorch 需要自己写训练循环,代码量多一倍,但如果你之前用过 PyTorch,或者要展示nn.LSTM的细节,也不难。

我一般建议:压缩包里如果已经带了 Keras 代码,就顺着它改;如果让你自己选,优先 Keras。环境配置上,pip install tensorflow keras pandas matplotlib scikit-learn就够了。注意新版 Keras 可能内置在 TensorFlow 里,导入方式为:

from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense

3.2 搭一个能跑的 LSTM 模型:核心代码与逐段说明

以单变量、单步预测(用前look_back个点预测后 1 个点)为例,典型模型如下:

from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense model = Sequential() model.add(LSTM(units=50, return_sequences=True, input_shape=(look_back, 1))) model.add(LSTM(units=50, return_sequences=False)) model.add(Dense(units=1)) model.compile(optimizer='adam', loss='mse')

逻辑说明:第一个LSTM层设置return_sequences=True,原因是它后面还要接一个 LSTM 层,必须输出完整序列给下一层;第二个LSTM层设置return_sequences=False,只输出最后一个时间步的结果,然后接一个Dense层输出预测值。units=50表示这一层有 50 个 LSTM 记忆单元,单元数越多,模型表达能力越强,但也越容易过拟合。loss='mse'因为预测连续数值,均方误差是最自然的损失函数。

这里有个常见改法:如果你是多变量预测,input_shape=(look_back, n_features)里的第二维要改成特征数,n_features对应你的列数。还有,如果不想堆两层 LSTM,完全可以只留一层,return_sequences就不用了:

model.add(LSTM(units=50, input_shape=(look_back, 1)))

两层 LSTM 能捕捉更抽象的时序特征,但数据量小的时候一层反而更稳。什么意思?数据长度只有几百时,两层 LSTM 的参数量几乎翻倍,训练集又少,很容易在训练集上拟合得好、测试集上一塌糊涂。数据量少于 1000 个点,我建议先用一层试跑。

3.3 训练参数怎么定:epochs、batch_size、optimizer 的取舍

模型编译好之后,fit里三个参数最常被反复调:

history = model.fit( X_train, y_train, epochs=100, batch_size=32, validation_split=0.2, verbose=1 )

epochs=100:训练轮数。不是越大越好——loss 降到一定程度后就不再下降,甚至开始反弹。我会先跑 50 轮看 loss 曲线,如果还在明显下降,再往上加。

batch_size=32:每批喂多少个样本。它影响收敛速度和显存占用。数值越小,梯度更新越频繁,训练震荡越厉害;越大越稳定,但对小数据集可能陷入局部最优。32 和 64 是大多数场景的默认选择。

validation_split=0.2:从训练集里切出 20% 当验证集,用来观察有没有过拟合。如果验证 loss 先降后升,而训练 loss 一直降,那就是过拟合,需要减少units、增加Dropout或减小look_back。

optimizer='adam'基本不用换,它自适应学习率,比 SGD 省心得多。如果你发现 loss 抖动剧烈,可以试试把学习率调到0.001以下,但用adam默认值通常就够。

4. 训练到预测的完整流程:从 train_test_split 到 inverse_transform

数据处理好了,模型也搭起来了,接下来是串联。这一章看的是源码里从train_test_split到predict再到画图的整条链路,也是期末报告里流程图最常照抄的部分。

4.1 数据切分:千万不能把时间序列随机打乱

很多人写机器学习代码习惯了train_test_split(X, y, test_size=0.2, shuffle=True),轮到时间序列也这么干,结果模型“偷看”了未来,测试集上准确率奇高,一换新数据就被打回原形。时间序列的切分必须按时间顺序:

train_size = int(len(scaled_data) * 0.8) train_data = scaled_data[:train_size] test_data = scaled_data[train_size:]

这里不shuffle,保持原始时间顺序。train_size取前 80%,剩下的 20% 作为测试集。还有一种更符合时间序列的做法是用TimeSeriesSplit,但期末作业里手动切片足以说明问题。

接下来构造样本对。假设原始序列是[x0, x1, x2, ..., xn],用前look_back个点预测下一个点,生成方式如下:

import numpy as np def create_dataset(data, look_back=10): X, y = [], [] for i in range(len(data) - look_back): X.append(data[i:i+look_back, 0]) y.append(data[i+look_back, 0]) return np.array(X), np.array(y)

这段代码的逻辑:遍历序列,每次取i到i+look_back-1共look_back个值作为输入,第i+look_back个值作为目标。最终X的形状是(样本数, look_back),y是(样本数,)。注意,训练集和测试集要分别调用这个函数,不能把整个序列先构造好再切——否则测试集样本可能混进训练集前面的点,造成信息重叠。

给 LSTM 输入前,还得把Xreshape 成三维:

X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1) X_test = X_test.reshape(X_test.shape[0], X_test.shape[1], 1)

这里第三维是特征数 1。如果你多变量,这一维对应列数。很多人reshape报错,基本都是因为X_train的 shape 和input_shape对不上。打印一下X_train.shape,把(样本数, look_back)变成(样本数, look_back, 1),模型就能吃了。

4.2 训练过程与 loss 曲线的判读

训练结束后,源码里一般会画 loss 曲线,代码大致是:

import matplotlib.pyplot as plt plt.plot(history.history['loss'], label='train_loss') plt.plot(history.history['val_loss'], label='val_loss') plt.legend() plt.show()

判断标准很简单:两条曲线都下降并趋稳,说明训练正常。如果val_loss明显高于train_loss且还在上升,是过拟合。如果两条曲线都在高位波动不降,可能是数据没归一化、学习率太大、或者look_back太小。这里最容易翻车的点是:只贴训练集上的预测图,不贴测试集。期末报告里,测试集上的预测曲线才最有说服力。

4.3 用训练好的模型做多步预测的两种常见写法

部分大作业要求预测未来 7 天或 30 天,这时单步预测就不够了。两种常见方案:

方案一:递归预测。每预测出一个新值,把它拼到输入序列末尾,丢掉最前面的旧值,再预测下一个。代码类似:

last_sequence = X_test[-1] # 形状 (look_back, 1) predicted = [] for _ in range(7): pred = model.predict(last_sequence.reshape(1, look_back, 1))[0, 0] predicted.append(pred) last_sequence = np.roll(last_sequence, -1, axis=0) last_sequence[-1, 0] = pred

np.roll把所有值往前移一位,最后一位填入新预测值。注意,误差会随步数累积——第一步预测的小偏差,会成为第二步的输入,然后被放大。所以递归预测只适合短期几步,7 步以内还能看,30 步以上基本飘了。

方案二:多输出预测。把Dense的输出改成目标步数,比如预测未来 7 天,Dense(7),训练集的y也要相应改成连续 7 个未来值。这需要重新构造数据集,复杂一些,但每一步预测不依赖前面步的结果,误差不会累积。期末大作业如果只要求“预测趋势”,递归预测就够用;如果要求“预测未来 N 天数值”,建议用多输出。

5. 期末大作业避坑指南:5 个最容易让你翻车的细节

这一章是血泪经验汇总,每一条都是我在跑 LSTM 预测代码时真实遇到过的。现象、原因、解决,按这个顺序写清楚。

5.1 现象:预测曲线比真实值“平移”了一段

你画出来的预测曲线和真实曲线形状几乎一样,但整体向右(或向左)偏移了一个时间点,看起来像“抄了一段过去”。原因:很多人构造训练样本时把y取错了位置。比如应该用data[i+look_back]作为预测目标,结果写成了data[i+look_back-1],相当于模型学到的是“把上一个时间点的值搬过来”。解决:核对create_dataset里y.append(data[i+look_back, 0]),确保预测目标是窗口之后的第一个点。如果代码没错,还有一种可能——数据本身做了一阶差分,但预测完忘了把差分还原。

5.2 现象:训练 loss 降了,但预测结果全是一条直线

这是 LSTM 最常见的病。原因通常是两个:一是损失函数用mae或mse,模型发现“输出所有样本的平均值”就能让 loss 降到很低,尤其是当序列变化不大、预测步长又短的时候。二是look_back设得过大,模型过度依赖最近几个点的平均值,学不到波动规律。解决:改用loss='mse'并加入early stopping;减小look_back;或者检查数据是否被错误地排序了。如果是多步预测,递归预测时直线问题更明显,因为第一步预测的误差会把后续预测压平。

5.3 现象:用测试集整体预测时,结果好得离谱

有些源码喜欢这样操作:把整个测试集的输入一次性喂给模型,得到一串预测,然后画图和真实测试序列对比。如果这串预测和真实值贴合得太完美,多半有问题——因为X_test里的每个样本和y_test的对应位置,存在窗口重叠:第 i 个样本的输入包含第 i+1 个样本的输入的一部分,导致测试集的样本不是独立的。更隐蔽的是,如果你的数据预处理用了全局MinMaxScaler的fit_transform(在整个原始序列上做的),测试集的信息已经被模型间接见过了。解决:先切分训练测试,再在训练集上fit缩放器,测试集只transform。这也是为什么前面强调,scaler.fit_transform不能用在全部数据上。

5.4 现象:中文路径导致读取数据报错

压缩包解压后,数据文件或代码路径带中文,比如C:\Users\张三\期末作业\data.csv,在 Windows 上用 pandas 读取时可能报UnicodeDecodeError或路径找不到。原因不是代码错了,而是 Python 的默认编码策略在中文路径上容易出问题。解决:一是把整个项目移到纯英文路径下,例如D:\workspace\lstm_project,这是最快的方法;二是如果有中文读文件需求,用pd.read_csv(file_path, encoding='utf-8'),文件本身是 GBK 编码时换成encoding='gbk'。期末交作业前,最好把压缩包的解压路径和文件夹名都改成英文,避免老师那边打开直接报错。

5.5 现象:LSTM 单元数设太大,训练慢且过拟合

看到别人的模型用 128 个单元,自己也照抄,结果几百条数据训练了十分钟还没收敛,测试集预测结果更是惨不忍睹。原因:单元数决定了模型容量,小数据集配上大容量模型,必然过拟合。解决:小数据量(<1000 条)用 32~50 个单元足够;如果加了Dropout(0.2),可以适当加大到 64。再一个参数是return_sequences=True的两层结构,数据量小的时候改成单层,参数量直接减半,训练速度明显提升。

6. 把大作业从“能跑”做到“高分”:3 个验证技巧和一份报告结构

到这里代码基本能跑通,但期末大作业的分数往往不在代码本身,而在你怎么验证它、怎么把结论写进报告。分享三个我常用的验证技巧。

第一个技巧是残差图。预测值与真实值相减,画一条残差曲线。如果残差随机分布在零轴附近,说明模型捕捉到了主要规律;如果残差有明显周期性或趋势性,说明还有信息没学到,可以增加look_back或增加 LSTM 层数。这个图老师最爱看,因为它比预测曲线更能说明问题。

第二个技巧是基准对比。拿一个简单模型当参照——比如“用昨天的值预测今天”或者“用过去 7 天平均值预测今天”。如果 LSTM 连这个基准都打不过,那说明要么数据没有强时序依赖,要么你的模型调参有问题。对比结果直接写进报告,能证明你做了充分的实验分析。

第三个技巧是多组参数实验。把look_back分别设为 5、10、20,记录每种配置下的测试集 MSE,做成小表格。这比单纯贴一张最终预测图有说服力得多,也正好回应了老师最爱问的“为什么选这个窗口”。

报告结构我建议按这个顺序写:问题定义与数据描述 → 数据预处理方法(归一化、窗口构造) → 模型结构(LSTM 层数、单元数、为什么选这个结构) → 训练与调参过程(loss 曲线、参数对比表) → 测试集验证结果(预测图、残差图、MSE/RMSE 指标) → 结论与不足。每一段都要配图和代码片段,代码要用英文注释。

说一个我自己的习惯:每次跑完实验,我一定把模型结构和关键参数用三行话记录在报告开头,防止第二天自己都忘了look_back为什么设成 10。很多同学在答辩时被问“你的look_back怎么确定的”,支支吾吾半天。其实只要你做过那组对比实验,任何回答都比“我试出来的”强。

希望这篇笔记能帮你的 LSTM 时间序列预测大作业少走弯路,把“能跑”变成“能讲清楚”,这是期末拿高分最实在的一条路。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 2:45:36

GESP四级排序题详解:C++ sort自定义比较器与稳定排序避坑指南

GESP四级第二题&#xff0c;六个字“排序”&#xff0c;每年都能让一批同学从信心满满到怀疑人生。今年6月的这道题&#xff0c;实际上并不复杂&#xff0c;核心就是排序规则的理解 C sort 的自定义比较器。如果你今早在考场上用了 sort&#xff0c;却因为比较函数写反或者没搞…

作者头像 李华
网站建设 2026/10/2 2:44:46

混合模型时间序列预测实战:LSTM与Transformer融合路径

简介&#xff1a;这份资源面向具备一定深度学习基础、希望上手时间序列预测实战的开发者与学习者&#xff0c;聚焦LSTM与Transformer混合模型的构建与落地。内容围绕如何将LSTM的局部序列建模能力与Transformer自注意力机制的全局依赖捕捉相结合&#xff0c;用于处理金融、气象…

作者头像 李华
网站建设 2026/10/2 2:44:20

CSDN博客插图尺寸调整全攻略:从拖拽到源码的四种方法

写技术博客这几年&#xff0c;我最头疼的往往不是文章内容本身&#xff0c;而是配图排版。很多人应该都有过这种经历&#xff1a;辛辛苦苦写了几千字&#xff0c;插入一张运行效果截图&#xff0c;结果图片尺寸要么大得撑满整个版面&#xff0c;要么小得看不清细节&#xff0c;…

作者头像 李华
网站建设 2026/10/2 2:44:01

Python金融风控建模实战:从特征工程到模型监控的完整链路

简介&#xff1a;这份资源面向金融风控方向的初学者与在校学生&#xff0c;提供一套基于机器学习的Python大数据风控建模完整实战项目&#xff0c;可用于毕业设计、期末大作业或课程设计场景。压缩包共106个文件&#xff0c;约20.13MB&#xff0c;以40个py源码文件为核心&#…

作者头像 李华
网站建设 2026/10/2 2:43:42

SSM+Vue交通规则考试系统:从数据库设计到部署实战

每年这个时候&#xff0c;都有一批人对着毕设题目发愁。如果你拿到的是“基于SSMVue的交通规则考试系统”这个题&#xff0c;恭喜你&#xff0c;这套组合拳在毕设圈里属于最稳的一类&#xff1a;后端是SpringSpringMVCMyBatis这套老牌SSM组合&#xff0c;前端是Vue&#xff0c;…

作者头像 李华
网站建设 2026/10/2 2:43:39

基于YOLOv8的西红柿成熟度检测系统:从数据集训练到PyQt5界面部署

简介&#xff1a;本资源是一套基于YOLOv8深度学习框架的西红柿成熟度检测系统&#xff0c;面向计算机、人工智能、自动化等专业的在校学生、教师及企业开发者&#xff0c;也适合作为毕设、课程设计或实战演示项目。系统通过PyQt5构建图形化界面&#xff0c;可对西红柿进行成熟与…

作者头像 李华