首页 / 资讯中心 / 文章详情

LSTM股票预测实战:从数据清洗到模型调参的完整指南

LSTM股票预测实战:从数据清洗到模型调参的完整指南 ★ FEATURED ARTICLE
1. 毕设选型为什么选LSTM做股价预测毕设选题像开盲盒选得好皆大欢喜选不好天天返工。我最后敲定的是LSTM股价预测方向——从确定题目到系统上线前后花了三个月。回头看这个题目好在技术点集中、成果展示直观缺点也非常明显预测金融时间序列这件事本身坑比想象的多得多。数学系或计算机系的同学选这个题目很常见但很多人忽略了一个关键事实股价数据不满足平稳性假设噪声占比极高LSTM虽然在序列建模上很能打但拿它直接预测股票价格本质上是在和随机游走博弈。我在开题阶段就把目标做了收敛不去追求预测未来某一天的精确价格而是专注用历史行情数据训练LSTM神经网络评估模型在样本外数据上的跟踪能力与泛化表现。这个定位让后续实验目标始终清晰也方便在论文里围绕LSTM预测能力边界做深入讨论。另一个考量是技术栈的成熟度。LSTM模型代码在PyTorch和TensorFlow里都有完善封装公开教程一抓一大把踩坑时有大量资料可查。我最终选了TensorFlow 2.x加Keras API配合Pandas做数据清洗、Matplotlib做可视化整套流程跑通以后每个环节都能直观看到中间结果非常适合毕设这种需要过程可控的项目。这个方向适合谁来参考如果你正在做金融时间序列相关的毕设或课设或者想快速入门循环神经网络在真实数据上的应用这篇分享能帮你少走很多弯路。我会把数据获取、清洗、模型搭建、训练调参、结果评估一条线全部讲透包括那些论文里不会写的血泪坑。2. 股价预测第一步数据集的获取与清洗实操2.1 数据源选择与下载股价预测第一件事是搞到干净的数据。我对比过几个常见数据接口A股行情用Tushare和AkShare比较方便前者需要注册获取token后者完全免费、接口封装更友好。考虑到毕设需要稳定复现我选了Tushare的日线行情接口数据质量高字段也完整。股票标的的选择也是有讲究的。我一开始选了波动剧烈的题材股结果模型完全失控。后来换了流动性好的大盘蓝筹比如贵州茅台、招商银行这类。用成熟大票的原因很简单历史数据长、交易连续、停牌次数少能减少数据清洗的工作量把重心放到模型本身。如果你做毕设强烈建议先选一只日线数据超过5年的大盘股再用小盘股做补充对比实验。下载的字段默认有开高低收、成交量、成交额。我这里额外注意了复权问题因为股票除权除息会导致价格跳空前后价格不可比。Tushare里可以拿前复权数据让历史价格按当前价格做回溯调整。这个细节如果漏掉模型会把分红送股当成了真实波动去学习。注意下载数据时顺手记录一下数据区间。后续做训练测试集切分时起始日期和终止日期都会影响时间窗口的构造别等做完了才发现数据少了一段。2.2 数据清洗与特征工程拿到原始数据后我先做基础清洗检查缺失值、删除重复行、确认日期连续。A股数据会有停牌导致的空缺Tushare返回的日线数据一般会把停牌日去掉所以连续性检查要找那些数量对不上的情况。我的处理方式是按正常交易日历补齐日期缺失字段用前向填充因为股价通常被认为是跳跃不太大的序列用前一天数值填充是行业常规做法。特征工程这块我把特征分成三组。第一组是基础行情特征也就是OHLCV五元组第二组是衍生统计特征包括日涨跌幅、成交量变化率、5日均线、10日均线、20日均线第三组是常用技术指标比如RSI相对强弱指数和MACD的DIF、DEA值。这几组特征加在一起输入维度大概在12到15之间。这里有个经验特征多了模型收敛慢而且容易把噪声一起学进去。我做了一轮简单相关性分析把和收盘价相关性过低、方差过大的几个指标踢掉了。最后保留的输入特征不要超过10个否则在样本量有限的情况下LSTM的优势反而会被高维特征稀释。毕设论文里写特征工程这个筛选过程本身就是很好的工作量证明。2.3 归一化与数据集划分归一化是LSTM训练前必须做的一步而且方法上有讲究。LSTM使用tanh和sigmoid作为激活函数输入范围太大会直接把激活函数推向饱和区导致梯度消失。我用的MinMaxScaler把所有特征缩放到[0,1]区间公式是老一套from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler(feature_range(0, 1)) scaled_data scaler.fit_transform(features)但这里有个大坑测试集数据在训练阶段必须保持不可见。正确做法是用训练集fit后再transform测试集而不是对整个数据集一口气归一化。很多教程直接全量fit_transform这会造成数据泄漏——模型在训练时偷看了测试数据的统计信息测试评估结果虚高答辩时被问住就尴尬了。数据集划分也要注意时序性。我的做法是前80%做训练集最后20%做测试集。因为股票数据是强时序依赖的乱序随机切分会破坏时间上的先后关系让训练集里的数据预知未来。训练集内部再切出一部分做验证集用于早停和调参测试集只用来做最终评估全程不碰。3. 核心环节LSTM模型搭建、训练与调参全记录3.1 理解LSTM的输入输出结构开始写代码之前先搞明白LSTM的数据形状这是很多新手卡壳的地方。LSTM期望的输入是三维张量(样本数, 时间步长, 特征维度)。时间步长就是我们常说的look_back即用过去多少个交易日的特征来预测未来。我用的是60天大致相当于三个月的交易日数量既保留了足够的中短期行情信息又不会因为窗口太长引入过多噪声。特征维度对应上一步保留的特征数量比如10个。每一个样本是由连续的60行特征矩阵构成标签是对应第61天的收盘价。滑动窗口构造样本时窗口每次向后滑动一天这样5000条数据大概能生成4900多个样本。LSTM的内部结构如果展开讲核心是三个门遗忘门决定丢弃多少历史信息输入门决定写入多少新信息输出门决定当前时刻输出什么。这三个门配合细胞状态让信息可以在长序列中传递而不被过度稀释。理解到这一层就够用了不用去手推反向传播公式但答辩老师很爱问提前准备好一两句通俗解释很有必要。3.2 网络结构与关键参数我的模型结构比较经典三层构建一个LSTM层加一个Dropout层再接一个LSTM层最后接两个全连接层输出单一数值。第一个LSTM层用64个单元return_sequences设为True让输出继续传递到下一层LSTM第二个LSTM层用32个单元只返回最后一个时间步的输出全连接层先经过一个16维的隐藏层激活函数用ReLU最后的输出层用线性激活因为这里是回归任务。LSTM模型代码看起来不长但里面门道不少import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau model Sequential([ LSTM(64, return_sequencesTrue, input_shape(look_back, n_features)), Dropout(0.2), LSTM(32, return_sequencesFalse), Dropout(0.2), Dense(16, activationrelu), Dense(1) ]) model.compile(optimizeradam, lossmse, metrics[mae]) model.summary()Dropout比例我试过0.1、0.2、0.3在0.2附近验证集误差最小。这个本质上是正则化强度和数据规模的平衡毕设样本量通常不大Dropout太高反而会让模型欠拟合。输出层不用激活函数这一点很多人忽略回归预测的目标是任意实数最后一层若套了sigmoid或tanh预测范围就被限制死了。3.3 训练流程与监控指标训练配置上batch_size设为32epochs先跑100轮配上早停回调。早停的监控指标是验证集损失耐心值设10轮也就是说验证损失连续10轮没有改善就停止训练恢复到损失最小的权重。同时我还加了ReduceLROnPlateau回调在损失停滞时自动把学习率降为原来的五分之一帮助模型冲出平台期。训练过程中的loss曲线需要全程记录。Keras自带History回调训练结束后画出来看看。正常情况下训练loss和验证loss都应当缓慢下降如果验证loss先降后升说明过拟合了如果两个loss都持平不降可能是学习率偏大或特征质量问题。我在第一轮实验时就是验证loss一直震荡后来把学习率从默认0.001调到0.0005才稳定下来。训练完成后保存模型和Scaler对象。很多人只存模型不存Scaler导致预测新数据时报维度错误或者归一化不一致。模型只有一个预测能力但数据预处理和还原都依赖Scaler的参数不保存的话还原预测价格时根本没有逆变换的基准。4. 用指标和曲线说话预测结果评估与可视化4.1 评价指标怎么选股价预测是回归任务不能像分类任务那样用准确率。我用了三个指标均方根误差RMSE、平均绝对误差MAE、平均绝对百分比误差MAPE。RMSE对大误差的惩罚更大能反映出预测在某些极值点上的偏离程度MAE直观反映平均偏差MAPE能把误差变成百分比便于横向对比不同股票。计算这些指标的关键是还原真实量纲。模型输出的预测值是归一化后的数值需要先逆变换回真实价格再和真实收盘价做差。很多人直接在归一化域里比较算出来的RMSE在0.02这种量级看起来漂亮得不像话实际上毫无意义。4.2 训练集与测试集的曲线对比可视化是整个毕设里展示效果最好的环节。我的做法是把训练集和测试集的预测曲线与真实收盘价曲线画在同一张图上训练集部分展示模型对历史数据的拟合能力测试集部分展示样本外泛化能力。测试集部分用更深的颜色区分并给测试集的起始位置加一条竖线让看图的人一眼就能分清哪里是学过的数据哪里是没见过的新数据。第一次画出来的曲线让我既高兴又警惕。高兴的是训练集拟合得几乎完美警惕的是测试集的预测曲线总是比真实曲线滞后一段时间。真实曲线开始下跌预测曲线还要继续上涨一两天才掉头。这是LSTM预测金融序列的经典问题原因很简单训练时标签是下一个交易日的价格对模型来说最简单的最优解就是让预测值接近上一个已知价格因为价格在短期内确实有强自相关性。模型本质上学会了今天的价格大概就是昨天的价格这个平凡的规律。4.3 对比实验LSTM vs 传统基线为了证明LSTM的有效性我又跑了两个基线模型线性回归和ARIMA。线性回归直接把窗口内的60天价格展开成特征同样预测第61天收盘价ARIMA是经典时间序列模型只拿收盘价做预测。三者在同一份数据、同样的训练测试划分下对比RMSE和MAPE。结果不出意料LSTM的测试集RMSE比线性回归低约18%比ARIMA低约27%。但在不同股票上优势幅度不一样波动大的股票上LSTM的优势会被削弱。所以论文里我没有笼统地说LSTM优于其他模型而是加了个限定语在中低波动率的个股日线收盘价预测任务上LSTM在样本外测试中相对线性基线和ARIMA有明显优势。这样表述既严谨又能体现分析能力。我还额外做了小样本敏感性分析把训练数据量从80%降到60%、40%观察LSTM和ARIMA的性能变化。结论是数据量越小LSTM的优势越弱甚至可能被ARIMA反超。原因不难理解深度模型是数据饥渴型选手数据不够时参数复杂的优势发挥不出来反而是参数少的传统模型更稳。这个实验为毕设答辩增加了不少讨论空间。5. 毕设血泪史常见问题与避坑指南5.1 数据泄漏与预测滞后数据泄漏是时间序列预测最容易犯却最难发现的错误。除了前面说的归一化泄漏还有一类泄漏来自时间窗口构造——如果滑动窗口生成样本时不小心shuffle了数据集那么训练集里某个样本的历史可能包含测试集某天的数据模型等于提前看到了未来。我建议在构造样本这一步就把数据按时间顺序切好再生成特征序列最后再划分训练测试。预测滞后问题无法完全消除但我做了两个改进一是把标签从下一交易日收盘价改成未来5日平均收盘价让目标更平滑二是在输入特征中增加差分项把价格变化量而不是价格绝对值交给模型。这两个改动让测试集的MAPE降低了差不多4个百分点尽管滞后现象仍然存在但幅度缓解不少。如果你最终仍然看到曲线滞后不要慌这在金融预测论文里是公认现象关键在于你能解释清楚原因并给出改进方案。5.2 过拟合与训练稳定性问题LSTM层数越多、单元数越多过拟合来得越快。我的第一版模型用了三层LSTM、每层128个单元训练集loss降到接近0测试集却一路走差。后来砍到两层LSTM、单元数64和32情况明显好转。经验是毕设级别的数据量几千到几万条两层LSTM已经足够单元数超过128基本是在浪费算力。训练稳定性也值得单独说。LSTM对随机初始化比较敏感同样的代码跑两遍结果可能差5个百分点。我一开始没有设置随机种子导致一次实验里指标变好另一次变差根本没法判断是模型改进还是随机波动。后来在规定位置固定了随机种子才让实验可复现。这里提醒一下用Keras时要同时设置Python、NumPy和TensorFlow三个层面的随机种子只设一个是不够的。5.3 训练时间与资源管理很多人担心LSTM训练慢。实际上以我的数据量约4000个样本在CPU上训练一轮大概十几秒100轮下来半小时出头。如果你买了GPU服务器或者用Colab一轮只要一两秒完全不是瓶颈。真正耗时的是调参试错一次早停十几轮试几十组参数时间成本就上去了。我的做法是把不同超参数的组合结果记录在表格里包括units数量、Dropout比例、学习率、batch_size、早停轮数对比之后再选最优组合而不是盲目凭感觉改代码。实操心得训练时把日志输出打开每轮打印loss和val_loss。我遇到过一次诡异情况——loss降了但val_loss不降检查半天才发现是数据处理时把验证集顺序打乱了泄漏了未来信息。这种问题如果不开日志盯着很容易被忽略。5.4 答辩准备与论文写作建议毕设做到最后工作能不能拿高分很大程度上取决于呈现方式。我的论文框架是这样的绪论部分讲研究背景和LSTM引入动机相关技术部分讲RNN原理、LSTM三门结构和股价预测文献综述数据部分写数据描述、清洗流程和特征工程细节模型部分写网络结构设计、训练策略和超参数选择依据实验部分放评估指标、对比实验和可视化图表最后讨论模型的局限性和改进方向。答辩PPT我做了两个强调点一是模型的完整训练流程图从原始数据到预测结果每一步都有图有真相二是把我在第5章里写的问题与改进当作亮点来讲因为评委老师最关心的不是模型多厉害而是你清不清楚自己的模型在什么条件下会失效。能把预测滞后和数据泄漏讲清楚比单纯展示漂亮的RMSE更能加分。我个人在实际操作中还有一个体会不要把毕设当成深度学习竞赛目标不是刷到最低的loss而是把一个完整的研究流程走通每一步都有清晰的决策依据和反思。我最后提交的所有代码都整理成了一个带注释的notebook从数据下载到结果可视化一键运行论文里的每一张图都能找到对应代码段这对答辩和后续使用都非常重要。如果时间允许你可以继续沿着多只股票、多步预测或者加入新闻情绪特征的方向扩展这个题目后续还有很多值得挖的空间。
阅读完成 · 觉得有帮助?
咨询建站