LSTM股票收盘价预测实战:从Excel数据到可运行Python代码的完整工程
简介这份资源面向需要完成时间序列预测课程设计、期末大作业或入门深度学习实战的学生与开发者核心是用Python实现基于LSTM的股票收盘价预测。压缩包共30个文件约1.83MB包含1个可直接运行的py主程序、3个xlsx数据表与1个csv样本数据以及16张png原理示意图、2份md分析报告和若干xml、iml等工程配置文件兼顾代码运行与原理讲解。内容从RNN节点结构、LSTM与RNN的区别、中间变量与计算过程等图示切入配合源数据与预测分析报告帮助读者理解模型输入输出、训练流程与结果评估。目前已有1792人学习下载适合希望快速拿到完整可跑代码、对照图示理清LSTM时间序列建模思路并完成高分作业的读者参考。1. 从一份 95 分课设说起LSTM 股票收盘价预测到底交付了什么如果你正在搜「lstm时间序列预测python」或者「lstm模型代码」大概率是两种情况一是期末大作业压着 deadline需要一份能跑通、有分析报告、有配图的完整方案二是想拿股票收盘价这类真实序列练手但卡在数据切分、归一化、窗口构造这些细节上。这份资源就是冲着这两个诉求来的一个 zip 包里面同时给了 LSTM 原理讲解图RNN 节点、LSTM 与 RNN 节点区别、中间变量、计算过程、神经网络层、一份 Excel 源数据、一份 Markdown 分析报告以及可运行的 Python 项目代码。它解决的不是「从零教你 Python 语法」而是「给你一套结构完整、能复现、能改参数的 LSTM 时间序列预测工程」。适合有基础 Python 语法、想快速拿到可运行代码并理解每一步为什么这么写的人。2. LSTM 预测股票收盘价原理选型与工程结构拆解2.1 为什么股票收盘价预测优先选 LSTM 而不是普通 RNN股票收盘价是一条典型的时间序列今天的价格和昨天、上周、上个月都有关联而且这种关联有长有短。普通 RNN 在反向传播时会出现梯度消失序列一长早期信息基本传不到后面模型学不到「一个月前的趋势影响了今天」这种长程依赖。LSTM 通过遗忘门、输入门、输出门三个门控结构配合细胞状态cell state这条「信息高速公路」把需要长期保留的信息和需要丢弃的信息分开管理这是它比普通 RNN 更适合股价这类中长序列的根本原因。资源里那几张图LSTM-1 到 LSTM-4、RNN 神经网络、一个 RNN 节点其实就是把这条逻辑画出来了先看单个 RNN 节点怎么算再看 LSTM 节点多了哪些中间变量最后看整个神经网络层怎么堆叠。我建议的顺序是先看图建立直觉再对着代码找对应实现比直接啃公式快得多。选型上还有几个现实理由。第一股票收盘价是单变量序列LSTM 对单变量和多变量都支持入门门槛低。第二Keras/TensorFlow 或 PyTorch 里 LSTM 层都是现成的不需要自己写门控。第三这份资源的分析报告标题就是「用时间序列模型学习股票收盘价预测未来价格」说明它的定位就是单序列预测不是多因子选股目标清晰。2.2 这份资源的目录结构与每个文件的作用拿到 zip 先别急着跑代码先把结构看清楚不然很容易在路径上翻车。按项目正文包内大致是这么几块目录/文件作用使用时机LSTM-1 ~ LSTM-4 系列 pngLSTM 与 RNN 区别、中间变量、计算过程、神经网络层讲解图理解原理阶段RNN神经网络.png、一个RNN节点.pngRNN 基础结构对比 LSTM 之前先看数据文件/源数据.xlsx股票收盘价原始数据数据加载与预处理分析报告/用时间序列模型学习股票收盘价预测未来价格.md完整分析思路与结论写报告、理解流程项目代码文件/用时间序列机器学习模型做股票收盘价格预测主代码目录实际运行images/代码运行产出的图表结果可视化这里有个血泪经验很多人解压后直接在压缩包里双击运行结果相对路径全乱。正确做法是先解压到一个纯英文、无空格的路径下比如D:/lstm_stock/再进项目代码目录操作。中文路径和空格在部分环境下会让数据读取直接报错这是最常见的翻车点之一。2.3 环境准备Python 版本与依赖库怎么装代码是 Python 写的依赖主要是数据处理和深度学习两块。常见做法是建一个独立虚拟环境避免和你机器上其他项目的库版本打架。下面这套流程我一般会走一遍# 创建虚拟环境python 版本建议 3.8 ~ 3.10太新可能和旧版深度学习库不兼容 python -m venv lstm_env # 激活环境Windows lstm_env\Scripts\activate # 激活环境macOS / Linux source lstm_env/bin/activate # 安装核心依赖 pip install numpy pandas matplotlib openpyxl scikit-learn pip install tensorflow # 或 pip install torch看代码用的是哪个框架逻辑说明venv把依赖隔离在项目内openpyxl是读.xlsx必需的很多人只装 pandas 结果读 Excel 报Missing optional dependency openpyxl就是漏了它。scikit-learn主要用来做归一化MinMaxScaler和评估指标。深度学习框架二选一具体装哪个要打开代码看 import 的是tensorflow.keras还是torch别两个都装容易冲突。参数上Python 版本不要盲目追新。TensorFlow 对 Python 版本有硬性要求装之前先确认框架支持的版本区间否则会出现装上了但 import 报错的情况。3. 从 Excel 到可训练张量数据预处理与窗口构造实操3.1 读取源数据并确认收盘价列第一步是把源数据.xlsx读进来看清楚列名和数据类型。股票数据常见的列有日期、开盘、最高、最低、收盘、成交量这份资源做的是收盘价预测所以核心列是收盘价。import pandas as pd import numpy as np # 读取 Excel注意路径按你解压后的实际位置改 df pd.read_excel(数据文件/源数据.xlsx) # 打印前几行和列名确认结构 print(df.head()) print(df.columns.tolist()) print(df.shape) # 如果日期列存在转成 datetime 并排序时间序列顺序错了后面全错 if 日期 in df.columns: df[日期] pd.to_datetime(df[日期]) df df.sort_values(日期).reset_index(dropTrue) # 取出收盘价序列 close df[收盘价].values.reshape(-1, 1) print(close[:5], close.shape)逻辑说明read_excel依赖 openpyxlsort_values这一步很多人忽略但如果原始数据不是按时间升序构造出来的窗口就是乱的模型学到的全是错误时序关系。reshape(-1, 1)是把一维序列变成二维因为后面的归一化器要求输入是二维数组。参数上列名要按你实际 Excel 里的中文或英文列名调整别照抄。3.2 归一化为什么必须做以及 scaler 要保存股价数值可能几十到几百直接喂给 LSTM梯度会很大收敛慢甚至不收敛。常见做法是 MinMax 归一化到 [0, 1] 区间。from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler(feature_range(0, 1)) close_scaled scaler.fit_transform(close) print(close_scaled.min(), close_scaled.max()) # 应接近 0 和 1逻辑说明fit_transform在训练数据上同时完成拟合和转换。这里有个关键坑——预测出来的结果也是 [0,1] 区间的必须用同一个 scaler 做inverse_transform才能还原成真实价格。所以 scaler 对象一定要保留不能重新 new 一个。参数feature_range默认就是 (0,1)写出来是为了明确。3.3 滑动窗口构造用前 N 天预测下一天LSTM 的输入是「序列片段」不是单个点。所以要把连续序列切成一个个窗口用前look_back天的数据预测第look_back1天。def create_dataset(data, look_back60): X, y [], [] for i in range(len(data) - look_back): X.append(data[i:i look_back, 0]) # 前 look_back 天 y.append(data[i look_back, 0]) # 第 look_back1 天 return np.array(X), np.array(y) look_back 60 # 用过去 60 个交易日预测下一天 X, y create_dataset(close_scaled, look_back) # LSTM 输入要求三维[样本数, 时间步, 特征数] X X.reshape(X.shape[0], X.shape[1], 1) print(X.shape, y.shape)逻辑说明look_back是最重要的超参数之一。太小比如 5模型看不到中期趋势太大比如 250样本数骤减且容易过拟合。60 个交易日约等于一个季度是股票预测里比较常用的起点。reshape成三维是 Keras LSTM 层的硬性要求形状是(samples, timesteps, features)单变量时 features1。这一步忘了 reshape 是最常见的报错来源错误信息通常是expected ndim3, found ndim2。3.4 训练集测试集切分时间序列不能随机打乱这是时间序列和普通机器学习最大的区别。普通任务可以train_test_split随机切时间序列必须按时间先后切否则就是用未来数据预测过去属于数据泄露。split int(len(X) * 0.8) # 前 80% 训练后 20% 测试 X_train, X_test X[:split], X[split:] y_train, y_test y[:split], y[split:] print(训练集:, X_train.shape, 测试集:, X_test.shape)逻辑说明按顺序切保证测试集在时间上晚于训练集模拟真实预测场景。比例 80/20 是常见起点数据量小可以调到 70/30。切完之后不要再 shuffleLSTM 训练时fit里的shuffle参数对时间序列一般设为 False除非你确认窗口之间独立性足够否则同样会打乱时序。4. 搭 LSTM 网络、训练与预测还原代码逐段落地4.1 用 Keras 搭一个两层 LSTM 回归模型模型结构不用太复杂单变量股价预测一两层 LSTM 加一个全连接输出就够了。层数堆太多样本不够时过拟合非常快。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout model Sequential() # 第一层 LSTMreturn_sequencesTrue 才能接第二层 LSTM model.add(LSTM(50, return_sequencesTrue, input_shape(look_back, 1))) model.add(Dropout(0.2)) # 第二层 LSTM输出二维不需要再接 LSTM model.add(LSTM(50, return_sequencesFalse)) model.add(Dropout(0.2)) # 全连接层输出单个预测值 model.add(Dense(1)) model.compile(optimizeradam, lossmean_squared_error) model.summary()逻辑说明return_sequencesTrue表示这一层把每个时间步的输出都传给下一层只有后面还接 LSTM 时才需要最后一层 LSTM 设 False只输出最后一个时间步的结果。Dropout(0.2)是防过拟合的常规手段比例 0.2~0.3 比较稳。Dense(1)输出一个标量对应下一天的收盘价。损失函数用 MSE回归任务标配。优化器 adam 基本不用调。参数上LSTM(50)里的 50 是隐藏单元数样本多可以加到 64 或 100样本少就降到 32。input_shape只在第一层写值是(look_back, 1)要和前面构造的 X 对上。4.2 训练过程与 EarlyStopping 防过拟合训练轮数不是越多越好股价数据噪声大训练太久测试集误差反而上升。from tensorflow.keras.callbacks import EarlyStopping early_stop EarlyStopping(monitorval_loss, patience10, restore_best_weightsTrue) history model.fit( X_train, y_train, epochs100, batch_size32, validation_split0.1, shuffleFalse, callbacks[early_stop], verbose1 )逻辑说明validation_split0.1从训练集里再切 10% 做验证用来监控过拟合。EarlyStopping在验证损失连续 10 轮不下降时提前停止并恢复最优权重这是省时间又防过拟合的后悔药。shuffleFalse保持时序。batch_size32是常用值样本少可以降到 16。训练完可以画一下 loss 曲线看训练和验证是否分叉。4.3 预测、反归一化与评估指标预测出来的是归一化值必须还原成真实价格才能看。from sklearn.metrics import mean_squared_error, mean_absolute_error import math # 预测 pred model.predict(X_test) # 反归一化scaler 是前面 fit 过的那个 pred_real scaler.inverse_transform(pred) y_test_real scaler.inverse_transform(y_test.reshape(-1, 1)) # 评估 rmse math.sqrt(mean_squared_error(y_test_real, pred_real)) mae mean_absolute_error(y_test_real, pred_real) print(RMSE:, rmse) print(MAE:, mae)逻辑说明inverse_transform必须用训练时那个 scaler重新建一个结果全错。y_test是一维的要先reshape(-1,1)才能喂给 scaler。RMSE 对大误差敏感MAE 更平稳两个一起看。股价预测的 RMSE 通常不会特别小别指望个位数重点看预测曲线和真实曲线的趋势是否贴合。4.4 可视化把预测曲线和真实曲线画在一起import matplotlib.pyplot as plt plt.figure(figsize(12, 6)) plt.plot(y_test_real, label真实收盘价) plt.plot(pred_real, label预测收盘价) plt.title(LSTM 股票收盘价预测) plt.xlabel(时间) plt.ylabel(价格) plt.legend() plt.savefig(images/prediction_result.png, dpi150) plt.show()逻辑说明savefig存到 images 目录方便写报告时直接引用。dpi150保证清晰度。看曲线时重点观察预测曲线是否滞后于真实曲线LSTM 常见现象因为它在学趋势而不是突变、波峰波谷是否被平滑掉。如果预测几乎是一条直线说明模型没学到东西回去检查归一化和 look_back。5. 避坑与排查跑不通时先看这几条5.1 报错找不到 Excel 文件或 openpyxl 缺失现象FileNotFoundError或Missing optional dependency openpyxl。原因路径写错或者没装 openpyxl。解决确认当前工作目录用绝对路径或相对项目根目录的路径pip install openpyxl补上依赖。中文路径也建议改成英文。5.2 LSTM 输入维度报错 expected ndim3现象ValueError: Input 0 is incompatible... expected ndim3, found ndim2。原因X 没有 reshape 成三维。解决在喂给模型前执行X X.reshape(X.shape[0], X.shape[1], 1)确认model.summary()里第一层 input_shape 和 X 的时间步一致。5.3 预测结果全是同一条水平线现象预测曲线几乎不动。原因常见是归一化后没反归一化、look_back 太小、或者模型根本没训练收敛。解决先确认inverse_transform用的是训练时的 scaler把 look_back 调到 30~60 之间试检查 loss 曲线是否下降没下降就调学习率或加训练轮数。5.4 训练 loss 一直降但测试效果很差现象训练集拟合很好测试集 RMSE 很大。原因过拟合或者数据泄露随机切分导致。解决加 Dropout、减小隐藏单元数、用 EarlyStopping确认切分是按时间顺序而不是随机。股价数据本身噪声大测试误差偏大是正常的别为了压测试误差去反复调参那是另一种过拟合。5.5 图表中文显示成方块现象matplotlib 图里中文变方框。原因默认字体不支持中文。解决在画图前设置中文字体Windows 用plt.rcParams[font.sans-serif] [SimHei]macOS 用[Arial Unicode MS]并加plt.rcParams[axes.unicode_minus] False解决负号显示问题。6. 把这份代码改成你自己的多步预测与参数调优技巧跑通单步预测只是起点真正拉开差距的是能不能改成多步预测、能不能把参数调出合理结果。多步预测有两种常见做法直接多输出模型一次输出未来 N 天和滚动预测预测一天把预测值塞回输入再预测下一天。滚动预测实现简单但误差会累积直接多输出需要改Dense(N)和标签构造。我一般先用滚动预测验证思路再决定要不要上多输出。参数调优上look_back、LSTM 单元数、Dropout 比例、batch_size 是四个主要旋钮。我的习惯是固定三个调一个每次只动一个变量并记录 RMSE不然你根本不知道是哪个参数起了作用。下面这张表是我常用的起步区间参数起步值可调范围影响look_back6020 ~ 120太小看不到趋势太大样本不足LSTM 单元数5032 ~ 128越大拟合能力越强越易过拟合Dropout0.20.1 ~ 0.4越大越防过拟合太大欠拟合batch_size3216 ~ 64影响训练稳定性和速度epochs100配合 EarlyStopping不用手动定死验证方法上除了 RMSE 和 MAE我强烈建议画一张「预测 vs 真实」的散点图看点是否沿对角线分布。如果点散成一团说明模型没有预测能力RMSE 再小也是假的可能只是预测了均值。另外把测试集最后一段单独拎出来看模拟「用历史预测最近一段」的真实场景比整体指标更有说服力。还有个容易被忽略的点这份资源的分析报告是 Markdown 格式写课程报告时可以直接参考它的分析框架但结论部分要换成你自己跑出来的数字别照抄。图表用代码重新生成存到 images 目录报告里引用相对路径这样整个项目是自洽的。从那以后我每次拿到一份时间序列代码都强制先跑一遍数据形状检查print(X.shape, y.shape)和归一化范围检查再动模型。这两步能挡掉八成低级错误。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →