ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LSTM股票收盘价预测实战:从数据预处理到模型调优的完整指南

LSTM股票收盘价预测实战:从数据预处理到模型调优的完整指南 简介这是一份基于深度学习LSTM算法实现股票收盘价格预测的Python源码项目面向计算机相关专业正在做大作业、毕业设计的学生以及需要项目实战练习的学习者也可用于课程设计与期末大作业。项目经导师指导并认可通过评审分98分属于高分毕业设计级别能帮助读者理解时序数据建模、LSTM网络搭建与股价预测的完整实现思路。资源包共8个文件包含1个核心Python脚本、1个Markdown说明文档、2个txt数据文件、2个xml配置、1个png结果图及1个gitignore压缩包约122KB结构精简便于快速阅读与二次修改。目前已有407人学习下载具备一定参考热度。读者可从中获取完整的预测代码、数据样例、依赖说明与项目说明文档适合作为入门深度学习时序预测的实战范本也可在此基础上调整网络结构、更换数据集进行扩展实验。1. 从一份 98 分毕设说起LSTM 股票收盘价预测源码能跑出什么股票收盘价预测这个题目每年毕业季都会被翻出来做一遍但真正能把 LSTM 跑通、把结果讲清楚的项目并不多。我手上这份PredictStock-master就是其中一个完成度比较高的它用 LSTM 对浦发银行SH600000的日线收盘价做单变量时间序列预测配套一份SH600000.txt历史行情数据、一份predictStock.py主脚本、requirements.txt依赖清单以及一张600000.png结果对比图。整个包结构干净没有多余的中间产物.idea目录说明作者是在 PyCharm 里开发调试的。它解决的核心问题很具体给定一段历史收盘价序列训练一个 LSTM 网络让它学会从过去 N 天的价格窗口推断下一天的价格最后把预测曲线和真实曲线画在同一张图上做对比。适合三类人正在做时间序列方向大作业或毕业设计的学生、想找一个能直接跑通的 LSTM 回归实战案例的初学者、以及需要一份结构清晰的最小可复现项目来改造成自己数据集的开发者。下面我按「数据长什么样 → 模型怎么搭 → 怎么跑起来 → 哪里会翻车 → 怎么改造成自己的东西」这条线把这份源码拆开讲。2. 数据与预处理SH600000.txt 的读取、归一化与滑窗构造2.1 先看清数据文件的真实结构SH600000.txt是浦发银行的日线行情导出文件常见格式是每行一条记录字段之间用制表符或逗号分隔通常包含日期、开盘、最高、最低、收盘、成交量、成交额这几列。在动手写代码之前第一件事是确认列的顺序和分隔符因为不同数据源导出的顺序不一样读错列会导致后面所有结果都是错的。import pandas as pd # 先探一下文件长什么样不要上来就指定列名 with open(SH600000.txt, r, encodingutf-8) as f: for i in range(3): print(repr(f.readline()))这段代码的作用是把前三行原样打印出来repr能让你看到制表符\t、空格和换行的真实位置。很多人直接pd.read_csv然后发现列全挤在一列里就是因为分隔符没对上。确认之后再用sep参数指定比如sep\t或sep,。如果文件没有表头要加headerNone并手动传names。2.2 只取收盘价但别急着归一化这个项目是单变量预测所以真正喂给模型的只有收盘价一列。常见做法是先df[close].values取出数组再做 Min-Max 归一化到 [0,1]。归一化这一步不是可选项LSTM 对输入尺度很敏感原始价格在十几到几十之间波动直接送进去梯度会很不稳定。import numpy as np from sklearn.preprocessing import MinMaxScaler close df[close].values.reshape(-1, 1) scaler MinMaxScaler(feature_range(0, 1)) close_scaled scaler.fit_transform(close)这里有个血泪经验scaler一定要在训练集上fit然后对全体做transform或者干脆先划分再分别处理。如果拿全体数据fit再划分测试集的信息就泄漏进训练过程了画出来的曲线会好看得不真实答辩时被问到就尴尬。这个项目数据量不大我一般会按 8:2 切分前 80% 训练、后 20% 测试fit只在训练段做。2.3 滑窗构造用多少天预测下一天LSTM 的输入是三维张量(样本数, 时间步, 特征数)所以要把一维价格序列切成一个个定长窗口。假设look_back60意思是用过去 60 个交易日的收盘价预测第 61 天。def create_dataset(data, look_back60): 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) x, y create_dataset(close_scaled, look_back60) x np.reshape(x, (x.shape[0], x.shape[1], 1))look_back是最关键的超参数之一。太小比如 5模型学不到趋势预测曲线会贴着真实值抖动太大比如 250样本数骤减训练容易过拟合而且对短期波动的响应变迟钝。60 个交易日大约对应三个月是这个数据集上比较稳的取值。reshape那一步不能省Keras 的 LSTM 层要求输入必须是三维的少一维会直接报 shape 错误。3. 模型搭建与训练Keras 下 LSTM 层的参数怎么定3.1 网络结构两层 LSTM 加全连接输出predictStock.py里的模型结构是典型的回归型 LSTM一层或两层 LSTM 堆叠最后接一个Dense(1)输出单个预测值。回归任务和分类任务的区别在于最后一层不加 softmax损失函数用mse或mae。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout model Sequential() model.add(LSTM(50, return_sequencesTrue, input_shape(60, 1))) model.add(Dropout(0.2)) model.add(LSTM(50, return_sequencesFalse)) model.add(Dropout(0.2)) model.add(Dense(1)) model.compile(lossmean_squared_error, optimizeradam)第一层 LSTM 的return_sequencesTrue是为了把完整序列传给第二层如果只有一层 LSTM这个参数设成False就行。50是隐藏单元数这个值不是越大越好单元数翻倍计算量翻倍但在这个数据规模上收益很小50 到 128 之间都算合理。Dropout(0.2)是防过拟合的常规手段时间序列数据噪声大不加 dropout 训练集 loss 会降得很快但测试集不跟。3.2 训练参数epoch、batch_size 与 early stoppinghistory model.fit(x_train, y_train, epochs100, batch_size32, validation_split0.1, verbose1)epochs100是上限实际训练中往往几十轮就收敛了。batch_size32是默认值样本量小的时候可以降到 16 或 8梯度更新更频繁。validation_split0.1从训练集里再切 10% 做验证用来观察是否过拟合。更稳妥的做法是加EarlyStopping验证 loss 连续若干轮不下降就停省时间也避免过拟合。提示如果你的环境里 TensorFlow 版本较新input_shape这种写法在 Sequential 里仍然可用但更推荐在第一层显式声明。跑之前先确认requirements.txt里的版本Keras 2.x 和 3.x 在 API 上有差异。3.3 预测与反归一化别忘了把结果还原回价格模型输出的是 [0,1] 区间的值必须用同一个scaler做inverse_transform才能和真实价格对比。这一步经常被漏掉导致画出来的图纵轴是 0 到 1看起来「预测很准」其实没有意义。pred model.predict(x_test) pred_price scaler.inverse_transform(pred) true_price scaler.inverse_transform(y_test.reshape(-1, 1))反归一化之后再用matplotlib画两条曲线600000.png就是这一步的产物。评估指标常用 RMSE 和 MAE但要注意这两个值受价格量级影响跨股票比较时最好用归一化后的误差或者 MAPE。4. 环境与运行requirements.txt 里的依赖怎么装不翻车4.1 依赖清单与版本冲突排查requirements.txt通常列了numpy、pandas、scikit-learn、tensorflow、matplotlib这几个。真正容易出问题的是 TensorFlow 和 numpy 的版本匹配新版本 numpy 有时会和旧版 TF 冲突报np.object之类的错误。python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install -r requirements.txt建虚拟环境这一步别省直接装在全局环境里一旦版本冲突会污染你其他项目。如果pip install过程中 TF 装得很慢或失败常见原因是网络和源的问题换国内镜像源即可这不是项目本身的毛病。4.2 运行主脚本与常见报错python predictStock.py跑起来之后常见的几类报错一是文件路径问题脚本里如果写的是相对路径必须保证在项目根目录下执行二是SH600000.txt的编码Windows 下可能是 GBK读的时候要指定encodinggbk三是 matplotlib 在无图形界面环境下报后端错误加一行matplotlib.use(Agg)就能绕过。4.3 结果图怎么看600000.png里一般有两条线真实收盘价和预测收盘价。判断模型好坏不是看两条线贴得多紧而是看预测线是否滞后于真实线。LSTM 做价格预测有个天然缺陷——它倾向于输出接近前一天的值导致预测曲线整体平移涨跌拐点抓不住。这是这类项目的通病答辩时如果被问到「为什么拐点预测不准」可以从这个角度解释比硬说「模型还需要优化」要专业得多。5. 避坑与常见问题这份源码跑不通时的排查清单5.1 现象loss 一直是 nan原因通常是学习率过大或者输入里有 NaN 值。原始数据里如果有停牌日、空值归一化之后会变成 nan喂进网络直接污染梯度。解决方法是读数据后先df.dropna()再检查np.isnan(close_scaled).sum()是否为 0确认干净了再训练。5.2 现象预测曲线是一条直线原因多半是模型没学到东西可能是look_back太小、LSTM 单元数太少或者训练轮数不够。也可能是归一化时用了全体数据导致信息泄漏训练 loss 很低但预测毫无变化。解决方法是先把look_back调到 60、单元数调到 50确认 loss 在下降再逐步调。5.3 现象测试集误差远大于训练集这是典型过拟合。数据量小、模型容量大时几乎必然发生。解决手段按优先级排加 Dropout、减小 LSTM 单元数、加 EarlyStopping、增加数据量。如果数据只有几百条别指望能把误差压得很低这时候老老实实报告结果比强行调参更诚实。5.4 现象换了自己的数据后 shape 报错多半是新数据的列数或行数和原数据不一致。create_dataset里假设了输入是一维收盘价如果你的数据是多列或者有缺失reshape 那一步就会崩。解决方法是先打印data.shape确认是(N, 1)再往下走。5.5 现象每次运行结果都不一样这是深度学习项目的正常现象权重随机初始化、dropout 随机失活都会导致结果波动。想复现就固定随机种子np.random.seed(42)和tf.random.set_seed(42)。但要注意固定种子只是让单次实验可复现不代表模型稳定多跑几次取平均才是靠谱的评估方式。6. 把它改成自己的项目换股票、加特征与结果验证拿到这份源码之后最有价值的动作不是原样跑一遍而是把它改成能处理你自己数据集的版本。换股票最简单把SH600000.txt替换成你导出的行情文件确认列名和分隔符对得上就行。但如果你想做多变量预测比如同时用开盘价、成交量、换手率改动就不止一处了。第一步是改数据读取把单列换成多列features df[[open, high, low, close, volume]].values scaler MinMaxScaler() features_scaled scaler.fit_transform(features)第二步是改create_dataset让x保留所有特征维度y仍然只取收盘价那一列def create_dataset_multi(data, look_back60, target_idx3): x, y [], [] for i in range(len(data) - look_back): x.append(data[i:i look_back, :]) y.append(data[i look_back, target_idx]) return np.array(x), np.array(y)第三步是改模型的input_shape从(60, 1)变成(60, 5)。这三处改完多变量版本基本就能跑。但要注意特征变多之后过拟合风险上升Dropout 和 EarlyStopping 要跟上。验证结果这块我一般会做两件事。一是把预测值和真实值按时间对齐后算 MAPE比 RMSE 更直观能直接说「平均误差在百分之几」。二是画误差分布直方图看误差是均匀分布还是集中在某些时段。如果误差在某个区间突然变大往往对应着行情剧烈波动的阶段这本身就是个值得在报告里讨论的点。还有个容易被忽略的细节这份源码用的是单步预测也就是用过去 60 天预测第 61 天。如果你想做多步预测比如预测未来 5 天create_dataset的y要改成取未来 5 天的序列模型输出层也要相应调整。多步预测的误差会累积第一天的偏差会传导到后面这是方法论层面的限制不是调参能解决的。从那以后我每次拿到这类时间序列项目都会先强制走一遍「数据探查 → 划分 → 归一化 → 滑窗 → 训练 → 反归一化 → 误差分析」这条链路任何一步跳过都会在后面某个环节以报错或离谱结果的形式找回来。这份PredictStock-master的价值不在于它预测得多准而在于它把这条链路完整地摆出来了你可以在它上面改数据、改结构、改评估方式把它变成真正属于自己的项目。希望帮到你。本文还有配套的精品资源点击获取
返回列表