LSTM股票预测实战:从数据预处理到Django可视化完整指南

发布时间:2026/10/12 13:38:33
LSTM股票预测实战:从数据预处理到Django可视化完整指南 简介基于Python与LSTM神经网络的股市预测完整项目面向金融数据挖掘、深度学习入门及课程设计人群解决股价时序预测的建模与落地问题。项目整合源代码、预训练模型与真实数据集每个Python文件均带可读注释涵盖数据预处理、滑窗构造、模型训练与评估流程零基础也能跟读调试适合作为高校期末大作业、课程设计或毕业设计的直接参考。压缩包内共89个文件包括24个py脚本、19个pyc编译文件、13个txt说明文档以及4个HTML页面、5个CSS样式、4个JS脚本等前端资源并附带xls/xlsx表格数据、SQLite数据库与JPG/PNG图表整体约8.87MB目录结构清晰便于按模块检索学习。项目内置Django框架搭建的可视化界面可运行展示预测结果已有793人学习下载适合在此基础上二次开发或扩展至其他金融序列预测场景。1. 值得拆吗这份 LSTM 股市预测源码到底能跑出什么你可能也遇到过这种情况从网上下了一个股票预测项目配环境花了一个晚上最后跑出来的预测曲线却是一条平移线导师看完直接摇头。这份资源就是用来打破这种局面的。它是一份拿到 97 分的课程设计源码把 LSTM 神经网络、真实股票数据、训练好的模型和 Django 可视化页面完整地串在一起。代码里有注释数据有原始 CSV模型有训练好的权重下载解压后能沿着一条清晰路径跑起来。适合正在准备课程设计或期末大作业的学生也适合第一次接触 LSTM 时间序列预测、想看看完整项目长什么样的开发者。拆包之后你会发现它没有复杂的工程结构但数据预处理、模型训练、结果展示三个环节都能对上这正是初学者最需要的参考样板。2. 原理先行LSTM 时间序列预测的输入数据与窗口设计拿到代码先别急着跑先把原理和数据形态看明白。股票预测本质是时间序列预测LSTM 只是其中一个解法但它解决的是普通神经网络在时序数据上“记不住过去”的痛点。这个项目里真正决定预测效果的不是网络层数而是你喂给模型的数据长什么样。2.1 LSTM 凭什么预测股市门结构与长短期记忆传统 RNN 在处理长序列时有个天生缺陷反向传播的梯度在传递过程中会指数级衰减导致模型记不住几天前甚至一个月前的信息。LSTM 的核心贡献是在循环单元里加了一个记忆通道用遗忘门、输入门和输出门三个结构来控制信息的去留。打个比方遗忘门决定昨天暴跌的消息要不要淡出记忆输入门决定今天收盘后的趋势值不值得记住输出门决定最后输出多少信息给下一步。这套机制让梯度能沿着记忆通道快速回传长期依赖就有机会被学出来。股票价格天然适合用这种结构去描述。今天的股价不是一个孤立的值它是过去一段时间的交易行为共同作用的结果。LSTM 在读取一个窗口内的连续价格时每一步都在更新记忆最终输出这一窗口的综合结果。影响模型能力的两个最关键参数一个是时间步长 timesteps也就是一次看多少天的历史另一个是神经元数量 units也就是记忆容量有多大。训练脚本里最常调的就是这两个值。2.2 输入数据长什么样OHLCV 与滑动窗口构造拆包后会看到一个 CSV 格式的股票数据文件标准行情数据至少包含五列Open开盘价、High最高价、Low最低价、Close收盘价、Volume成交量。纯入门项目通常只取 Close 一列因为预测目标就是收盘价。但真正想提升效果会把五个字段全部灌进去让模型同时从价格振幅和交易量里找规律。LSTM 的输入必须是三维数组形状是样本数, 时间步, 特征数。原始数据是一行行的日期和价格没法直接进模型所以要用滑动窗口把序列切成样本。以窗口 60 天为例第 1 天到第 60 天是第一个样本标签是第 61 天收盘价第 2 天到第 61 天是第二个样本标签是第 62 天。这样一路滑下去数据量为 N 时能生成 N-60 个样本。我在给类似课程设计做预处理时习惯写这样一个函数import numpy as np def create_sliding_window(data, window_size): X, y [], [] for i in range(len(data) - window_size): X.append(data[i:i window_size]) # 窗口内连续数据 y.append(data[i window_size]) # 窗口后一天的结果 return np.array(X), np.array(y) # data 为归一化后的二维数组shape 为 (总天数, 特征数) X, y create_sliding_window(data, window_size60) print(样本形状:, X.shape) # 例如 (947, 60, 5)这里 X 的最后一个维度是特征数用了五列行情数据就是 5只用了收盘价就是 1。代码里要特别注意的是原始 DataFrame 必须先经过 .values 转成 NumPy 数组否则 pandas 的数据结构没法直接进行这种切片。2.3 归一化与按时间切分别让模型偷看未来股价动辄几十上百元LSTM 内部用的是 tanh 和 sigmoid 激活函数它们对 0 附近的值最敏感。直接把 200 元的股价喂进去激活函数会迅速进入饱和区梯度接近 0模型怎么训练 loss 都降不下来。所以第一步永远是归一化。我用 MinMaxScaler 把价格压缩到 0 到 1 之间这也是时间序列预测里最常见的做法。另外一个更隐蔽的坑是数据切分。时间序列不能用 train_test_split 的随机模式随机打乱会让未来数据混进训练集模型等于提前偷看了答案。正确做法是按时间顺序切前 80% 训练后 20% 测试。from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler(feature_range(0, 1)) scaled_data scaler.fit_transform(data) # 按时间顺序切分绝不 shuffle train_size int(len(scaled_data) * 0.8) train_data scaled_data[:train_size] test_data scaled_data[train_size:]特别注意 fit_transform 只能在训练集上执行一次测试集用同一个 scaler 做 transform不能重新 fit。否则测试集的统计信息泄漏到预处理阶段验证结果会虚高。很多课程设计看起来效果很好一换真实场景就拉胯原因往往就出在这里。3. 跑通代码从环境安装到 Django 可视化页面原理讲完开始动手。我会按解压后的文件顺序把每个文件的功能说清楚再带你把训练和页面跑起来。这份资源的目录结构并不复杂识破每个文件作用之后改起来就直截了当。3.1 项目文件结构code.py、Django 与数据集的关系解压后你会看到 stock_prediction-master 文件夹里面常见文件可以用树形结构表达stock_prediction-master/ ├── .gitattributes ├── README.md ├── code.py ├── django/ │ ├── settings.py │ └── urls.py └── stock_prediction/ ├── views.py ├── models.py └── templates/code.py 是训练脚本负责数据读取、LSTM 模型搭建和训练训练完会保存一个 H5 模型文件。django 目录是 Django 项目的配置存放 settings.py 和 urls.py。stock_prediction 是核心应用views.py 里加载模型做预测templates 里放展示页面的模板。.gitattributes 是 Git 配置文件和运行没有任何关系可以直接忽略。3.2 环境准备Python 版本与依赖安装这种涉及 TensorFlow、Django、pandas 的项目最忌惮的就是直接往全局环境里塞包。包与包之间版本冲突会把整个环境搞乱到时候 import 在哪一行报错都说不清。我每次都先用 conda 建一个独立环境。conda create -n stock python3.9 -y conda activate stock pip install tensorflow2.13.0 pandas numpy matplotlib scikit-learn djangoPython 版本建议固定在 3.8 到 3.10 之间。TensorFlow 2.x 在更高版本上兼容性变化大代码里写的 keras API 可能换位置。安装完成后花十秒钟验证避免后面训练才暴露问题python -c import tensorflow as tf; print(tf.__version__); import django; print(django.get_version())能同时打印出 TensorFlow 和 Django 版本说明基本依赖没问题。CPU 版 TensorFlow 不需要额外装 CUDA股票数据量并不大CPU 跑几十个 epoch 也就几分钟不值得为 GPU 配环境折腾。3.3 训练模型code.py 的执行流程与参数打开 code.py当前项目的核心流程就摆在眼前加载 CSV → 归一化 → 构造窗口 → 构建 LSTM → 训练 → 保存模型。实际训练代码大体是这个模样from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout model Sequential() model.add(LSTM(128, return_sequencesTrue, input_shape(60, 5))) model.add(Dropout(0.2)) model.add(LSTM(64)) model.add(Dense(1)) model.compile(optimizeradam, lossmean_squared_error) history model.fit( X_train, y_train, validation_data(X_test, y_test), epochs50, batch_size32, verbose1 ) model.save(stock_model.h5)input_shape 里的 60 是窗口长度5 是特征数这两个值必须和训练时完全一致后续 Django 加载模型时也要同步改。Dropout 放在两个 LSTM 层之间作用是随机丢弃一部分神经元防止过拟合。loss 用 mean_squared_error 是因为这是一个回归问题预测连续价格值。直接执行python code.py训练开始后终端会逐渐打印每个 epoch 的 loss。看到 loss 从 0.05 往下走到 0.001 附近说明模型收敛了。训练结束后当前目录会多出 stock_model.h5这就是后面页面要加载的模型权重。3.4 启动 Django 页面看到预测曲线模型训练完成紧接着启动 Django 开发环境。python manage.py migrate python manage.py runservermigrate 用于初始化 Django 自带的 SQLite 数据库即使项目里没有自定义表也需要跑一遍保证框架正常。打开浏览器输入 http://127.0.0.1:8000就能看到页面上的历史价格曲线和预测曲线。页面的后端逻辑在 stock_prediction/views.py 里典型的加载模型做法是from tensorflow.keras.models import load_model from django.http import JsonResponse def predict_price(request): model load_model(stock_model.h5) latest_window prepare_latest_data() # 构造最近60天数据 prediction model.predict(latest_window) return JsonResponse({predicted_price: float(prediction.flatten()[-1])})这套代码背后有一个工作习惯保存模型时最好把 scaler 也用 pickle 存下来。因为预测阶段对新的输入数据同样要做 MinMaxScaler 归一化如果只存模型不存 scaler新数据就没法使用和训练时相同的缩放参数预测出来的结果会完全跑偏。4. 调优方向窗口、网络结构与方向准确率验证项目能跑通只是刚刚及格。接下来要回答的问题是如何让预测结果更可信。这里我不推荐一上来就改网络结构而是先动窗口、再看评估指标最后才考虑增加层数。4.1 窗口大小和时间步的选择滑动窗口大小是影响样本数量和模型感受野的直接因素。窗口太小模型看到的信息不足比如只给 5 天数据很难体现中期趋势窗口太大训练样本数量减少还可能把数年前早已失效的价格模式也学进来。对日线数据来说20、30、60 是三个最常用的候选值分别对应一个月、一个半月和一个季度。我建议做一组对照实验代码层面只改 window_size 一个变量训练逻辑不动。记录不同窗口下的验证集 RMSE 和方向准确率结果往往会呈现一个峰值继续加大到 90 天性能反而下降。窗口大小训练样本数验证集 RMSE方向准确率20约 9000.2451.2%30约 8900.1954.8%60约 8600.1553.5%90约 8300.1852.1%这个表格只是示意真实数值由数据决定但窗口太大导致准确率回落的现象非常常见。调参别凭感觉多跑几次对比再定。4.2 评估指标RMSE 不够方向准确率才是核心模型输出的是价格数值很多人习惯用 RMSE 评估。但 RMSE 反映的是“数值偏差”和实际交易中的盈亏关系没那么直接。一个极端例子预测值永远等于前一天收盘价和真实价格差一条直线RMSE 可能不大方向准确率却只有 50%毫无用处。在金融场景里买入卖出的盈亏取决于方向判断所以方向准确率比 RMSE 更能说明问题。定义也很简单预测涨跌方向和真实涨跌方向一致的比例。import numpy as np # y_test: 真实收盘价序列 # y_pred: 模型预测的收盘价序列 direction (np.diff(np.ravel(y_test)) 0) (np.diff(np.ravel(y_pred)) 0) direction_acc np.mean(direction) print(f方向准确率: {direction_acc:.2%})这段代码先把二维数组展平再计算相邻两天价格的涨跌方向。随机猜是 50%如果能稳定在 55% 以上说明模型确实从历史数据中学到了某些模式。课程设计里把方向准确率写进报告比单纯贴一张 loss 曲线会有说服力得多。4.3 网络结构深度与早停法对于几千行股票数据两层 LSTM 已经足够。第一层设 return_sequencesTrue 保留完整序列第二层输出最后一刻的记忆到 Dense 层。第三层 LSTM 容易导致过拟合训练集 loss 降到很低测试集却一片混乱。控制过拟合的方法有两个Dropout 加早停。早停法的思路是监控验证集 loss当连续若干轮不下降时就终止训练并恢复表现最好的一组权重。这样做既能防止过拟合也能省下不必要的训练时间。from tensorflow.keras.callbacks import EarlyStopping early_stop EarlyStopping( monitorval_loss, patience5, restore_best_weightsTrue ) model.fit( X_train, y_train, validation_data(X_test, y_test), epochs100, batch_size32, callbacks[early_stop] )patience 表示连续 5 轮验证集 loss 没有改善就停。取值太大会让过拟合持续发生太小又会提前掐断训练我习惯从 5 开始试。学习率也可以调低常见做法是把 Adam 的默认学习率 0.001 改成 0.0001代价是训练变慢但离线训练有时间成本值得等。5. 避坑指南五个高频问题与现场排错拆这个项目时踩过的坑比模型本身的调参步骤更值得记录。下面五条按现象、原因、解决方式排列每一条都是真实发生过的翻车现场。5.1 loss 变成 NaN训练直接崩掉现象训练进行过程中 loss 突然变成 nan后面所有输出全是 nan。原因数据集里有缺失值或无穷大常见于停牌导致的空行。还有可能是学习率太大梯度更新一步越过安全范围。解决预处理时先用df.isnull().sum()检查缺失值用前一日价格填充或直接删掉空行。归一化后检查数据里有没有 inf。最后把学习率从默认 0.001 降到 0.0001大概率能稳住。5.2 预测曲线是一条平移线现象预测值几乎等于前一天价格曲线像被复制粘贴了一样整体右移一格。原因模型学到了“用昨天价格预测今天”这个偷懒策略。这种情况在只输入收盘价一个特征、窗口太短、网络太浅时经常出现LSTM 发现复制前值能让 loss 保持较低就不再去学更复杂的关系。解决从特征入手加入成交量、涨跌幅、均线等技术指标把窗口调成 30 或 60适当加深网络。评估时改用方向准确率平移线的方向准确率接近 50%一眼就能识别。5.3 TensorFlow 安装后 import 报错现象执行python code.py时提示No module named tensorflow或 keras 相关的导入错误。原因conda 和 pip 混用导致环境脏乱或 Python 版本与 TensorFlow 版本不兼容。比如用 Python 3.11 装旧版 TFimport 阶段就会报某些 C 库加载失败。解决新建一个干净的 conda 环境Python 固定 3.9升级 pip 后再安装 TensorFlow。安装后立刻在终端执行python -c import tensorflow验证别再急着跑项目。5.4 Django 页面打不开模型文件路径找不到现象Django 启动成功但打开页面返回 500日志里显示 open 失败找不到 stock_model.h5。原因views.py 里模型路径写的是相对路径比如load_model(stock_model.h5)。相对路径取决于 runserver 启动时的当前目录跟你在根目录还是子目录执行命令有直接关系路径一变自然找不到。解决把模型路径改成基于 Django 项目根目录的绝对路径。在 settings.py 里定义 BASE_DIR然后在 views.py 里用os.path.join(settings.BASE_DIR, model.h5)问题立刻消失。5.5 测试集效果虚高真实场景完全失效现象验证集 RMSE 极低方向准确率也高但把模型放到最新数据上去预测结果惨不忍睹。原因数据切分没按时间顺序。代码里如果调用了train_test_split(shuffleTrue)未来数据混进训练集模型等于提前看到答案。课程设计里出现得很多因为随机切分后验证集比例越低效果看起来越漂亮。解决重写切分逻辑按时间索引直接切。比如train_data scaled_data[:800]test_data scaled_data[800:]不调用随机切分函数。也要检查归一化环节测试集不得参与 fit_transform。6. 进阶验证用“基线对比”判断模型是否有效项目跑通了但答辩时如果导师问“你的模型到底有没有用”你该怎么回答只看 loss 曲线是不够的。我自己验证这类模型时第一件事是做两个对照实验。第一个对照是“昨天收盘价”基线。毕竟 LSTM 再不济也可以用前一天价格勉强充数。具体做法是把测试集里第 2 天到第 N 天的真实价格拿出来拿第 1 天到第 N-1 天的真实价格当作预测值计算这个基线的 RMSE。如果 LSTM 的 RMSE 和这个基线差不多甚至更差说明模型没有本质进步只是在一个复杂结构里复制了昨天的值。from sklearn.metrics import mean_squared_error baseline_pred np.roll(y_test, 1) # 把真实值整体后移一天 baseline_pred[0] y_test[0] # 第一个位置没历史值用自身填充 baseline_rmse mean_squared_error(y_test, baseline_pred, squaredFalse) model_rmse mean_squared_error(y_test, y_pred, squaredFalse) print(f基线RMSE: {baseline_rmse:.4f}, 模型RMSE: {model_rmse:.4f})模型 RMSE 必须明显低于基线 RMSE这个模型才是有效特征提取器而不是序列复制器。第二个对照是不同特征组合的比较。只输入收盘价的模型和加入成交量、涨跌幅的模型在同样的窗口和测试集上对比方向准确率。我实际观察过加入交易量特征后方向准确率通常能提升 3 到 5 个点。这个提升和调网络层数相比来得更快也更稳定。如果还想做得更扎实一点可以补一个 walk-forward 验证。把测试集切成若干段每段只用它之前的数据训练再预测当前这一小段。这种滚动训练方式更接近真实交易节奏也能检验模型在不同行情阶段是否稳定。源码里没有现成实现但你可以在这个资源基础上自己加这正好是二次开发的一个好方向。这份资源最大的价值是把“原始数据 → LSTM 训练 → 模型持久化 → Web 展示”这条链路完整地跑通了一次。模型精度不算惊人但工程路径是完整的你可以在这条路径上换数据、改特征、加验证模块。从那以后我拿到任何股票预测项目第一件事永远是先算基线 RMSE 和方向准确率而不是盯着训练 loss 曲线自我安慰。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询