利用 RNN 预测股票价格:从数据处理到可视化实战

在金融领域,预测股票价格走势一直是众多投资者和研究者关注的焦点。今天,我们将利用深度学习中的循环神经网络(RNN)来构建一个简单的股票价格预测模型,并详细介绍从数据加载、预处理、模型搭建、训练到最终结果可视化的全过程。

一、项目概述

本项目旨在通过历史股票价格数据,训练一个 RNN 模型,使其能够对未来股票价格进行一定程度的预测。我们将使用 Python 作为主要编程语言,结合 NumPy、PyTorch 以及 Scikit-learn 等强大的库来实现这一目标。

二、数据准备

  1. 加载数据:首先,我们使用 np.loadtxt 函数从 CSV 文件(假设名为 data-02-stock_daily.csv)中读取股票价格数据。这里需要注意指定正确的分隔符,通常股票数据 CSV 文件是以逗号分隔的,所以我们传入 delimiter=','。读取到的数据是一个二维数组,每一行代表一天的股票相关信息,如开盘价、收盘价、最高价、最低价等。为了让数据按照时间顺序排列,方便后续处理,我们使用切片操作 data = data[::-1] 将数据反转。
  2. 归一化处理:不同特征的数值范围可能差异很大,这会影响模型训练的效率和效果。因此,我们引入 MinMaxScaler 类进行归一化处理。它会将数据的每一个特征都映射到 0 到 1 的区间内,具体操作是通过 data = MinMaxScaler().fit_transform(data) 实现。经过这一步,数据的分布更加规整,有助于模型更快更好地收敛。
  3. 构建输入输出序列:为了让 RNN 模型能够学习到股票价格的时间序列特征,我们需要设置一个时间步长 c(这里设为 7)。通过循环遍历归一化后的数据,构建输入序列 x 和对应的输出序列 y。对于输入序列,我们将连续 c 天的数据作为一个样本,即 x.append(data[i:i + c]);而输出序列则是第 c + 1 天的股票价格,也就是 y.append(data[i + c][-1])。最后,将 x 和 y 转换为 PyTorch 张量,方便后续在深度学习框架中使用,使用 x = torch.tensor(x, dtype=torch.float) 和 y = torch.tensor(y, dtype=torch.float) 完成转换。
  4. 划分数据集:使用 sklearn 的 train_test_split 函数将数据集划分为训练集和测试集。为了保证实验的可重复性,我们指定 test_size=0.2,表示测试集占总数据集的 20%,以及 random_state=42 作为随机种子。通过 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42) 得到划分后的数据集,并打印出训练集的形状,以便了解数据的维度信息,用于后续模型参数的设置。

三、模型搭建

我们定义了一个自定义的 RNN 模型类,继承自 torch.nn.Module。在 __init__ 方法中:

  1. 首先调用父类的初始化方法 super().__init__(),确保模型的基础结构正确初始化。
  2. 接着创建两个 RNN 层,第一个 self.rnn1 的输入大小根据训练数据的特征维度确定,即 input_size=x_train.shape[2],这里 x_train.shape[2] 表示输入数据的特征数量,隐藏层大小设为 128,并且设置 batch_first=True,使输入张量的批次维度在第一维,方便与后续的数据加载器等组件配合;第二个 self.rnn2 的输入大小为第一个 RNN 层的隐藏层大小 128,隐藏层大小设为 256,同样设置 batch_first=True
  3. 最后定义一个线性层 self.linear,将第二个 RNN 层的输出映射到预测的股票价格维度,其输入特征数量为 256,输出特征数量为 1。

在 forward 方法中:

  1. 输入数据 x 首先经过第一个 RNN 层 self.rnn1,得到输出 x 和隐藏状态 y,由于在这个预测场景中我们不需要关注隐藏状态,所以直接忽略 y,即 x, _ = self.rnn1(x)
  2. 接着 x 再经过第二个 RNN 层 self.rnn2,同样忽略隐藏状态,x, _ = self.rnn2(x)
  3. 最后将经过两层 RNN 处理后的 x 的最后一个时间步的输出(也就是 x[:, -1, :])传入线性层 self.linear,得到最终的预测结果并返回。

四、模型训练

  1. 实例化模型:创建 RNN 模型的实例,即 model = RNN()
  2. 定义损失函数:选用均方误差损失函数(MSELoss)来衡量模型预测值与真实值之间的差异,loss_fn = torch.nn.MSELoss()。这是因为在预测股票价格这种连续值的任务中,均方误差能够很好地反映预测的准确性。
  3. 定义优化器:使用 Adam 优化器来更新模型的参数,指定学习率为 0.01,通过 optimizer = torch.optim.Adam(model.parameters(), lr=0.01) 完成定义。Adam 优化器在实际应用中表现出良好的收敛性能,能够自适应地调整学习率,使得模型训练更加高效。
  4. 训练循环:设置训练的轮数为 1000,在每一轮训练中:
    • 首先使用 optimizer.zero_grad() 清空上一轮训练的梯度信息,确保每一轮的梯度计算都是基于当前轮次的输入数据。
    • 然后将训练数据 x_train 传入模型,得到预测输出 h = model(x_train),并使用 loss_fn 计算预测值与真实值 y_train 之间的损失。
    • 接着调用 loss.backward() 进行反向传播,计算模型参数的梯度。
    • 最后使用 optimizer.step() 根据计算得到的梯度更新模型参数,并将当前轮次的损失值添加到损失列表 loss_list 中。为了便于观察训练过程,每 100 个轮次打印一次损失值,如 if (epoch + 1) % 100 == 0: print(f'Epoch [{epoch + 1}/{num_epoch00}, Loss: {loss.item():.4f}')

五、模型预测与可视化

  1. 预测测试集:训练完成后,将测试集数据 x_test 传入模型,得到预测结果 predictions = model(x_test).squeeze(),这里的 squeeze 操作是为了去除可能存在的多余维度,使预测结果的维度与真实值 y_test 相匹配。
  2. 绘制预测结果:使用 matplotlib 库绘制预测结果和真实结果的对比图。首先创建一个新的绘图窗口,设置合适的图幅大小,如 plt.figure(figsize=(10, 6))。然后分别绘制预测值和真实值的折线图,用红色表示预测值 plt.plot(predictions.detach().numpy(), c='r', label='Prediction'),绿色表示真实值 plt.plot(y_test.detach().numpy(), c='g', label='Actual'),并添加标题、坐标轴标签以及图例,最后通过 plt.show() 展示绘图结果。这使得我们能够直观地看到模型预测的股票价格与实际价格的接近程度,评估模型的性能。
  3. 绘制损失曲线:为了进一步了解模型训练过程中的收敛情况,我们还绘制了训练损失随轮次变化的曲线。同样创建一个新的绘图窗口,绘制损失列表 loss_list 中的值,用蓝色表示训练损失 plt.plot(loss_list, c='b', label='Training Loss'),添加相应的标题、坐标轴标签和图例,最后展示绘图结果。通过观察损失曲线,我们可以判断模型是否收敛,以及收敛的速度如何,为后续模型的优化提供参考。

通过以上完整的步骤,我们成功地利用 RNN 模型对股票价格进行了预测,并通过可视化手段直观地展示了预测结果和训练过程。当然,这只是一个简单的示例,在实际应用中,还可以进一步优化模型结构、调整参数、增加更多的数据特征等,以提高预测的准确性。希望这个项目能够为你在深度学习应用于金融领域的探索中提供一些帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/57.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为RH2288H V3服务器极速重装:从RedHat到openEuler 24超详细重装指南

1 登录iBMC口 2 配置启动项 点击:配置,点击:系统启动项 点击:单次有效,选择:光驱,点击:保存 3 进Remote Contro 点击:远程控制,进入如下界面 点击&#xff1…

+++++背到厌倦。持续更新

Spring IoC 的工作流程: 读取 BeanDefinition: Spring 容器启动时,会读取 Bean 的配置信息 (例如 XML 配置文件、注解或 Java 代码),并将这些配置信息转换为 BeanDefinition 对象。创建 Bean 实例: 根据 BeanDefinition 中的信息,Spring 容器…

【机器学习算法】基于python商品销量数据分析大屏可视化预测系统(完整系统源码+数据库+开发笔记+详细启动教程)✅

目录 一、项目背景 二、技术思路 三、算法介绍 四、项目创新点 五、开发技术介绍 六、项目展示 一、项目背景 本项目基于Python技术栈构建了"商品销量数据分析与预测系统",通过自动化爬取淘宝商品多维数据(价格、销量、评价、品类等&a…

Server-Sent Events一种允许服务器向客户端发送实时更新的 Web API

Server-Sent Events(SSE)是一种允许服务器向客户端发送实时更新的 Web API。它基于 HTTP 协议,提供了一种单向的、服务器到客户端的通信机制,客户端可以通过监听服务器发送的事件来接收实时数据。下面从原理、使用场景、代码示例等…

用Perl和HTTP::Tiny库的爬虫

HTTP::Tiny是Perl的一个轻量级HTTP客户端,适合简单的请求,但不像LWP那样功能全面,不过对于基本需求应该足够了。 首先,我需要熟悉HTTP::Tiny的基本用法。比如如何发起GET请求,设置user-agent,处理响应。用…

Vue3性能优化终极指南:编译策略、运行时调优与全链路监控

一、Vue3性能优化体系框架 1.1 性能优化全景图谱 1.2 关键性能指标定义表 指标测量方式优化目标核心影响因子FCPLighthouse<1.5s资源加载速度LCPPerformance API<2.5s关键资源大小TTIWebPageTest<3.5s主线程阻塞时间Memory UsageChrome DevTools<50MB对象引用策略…

sqlite3基本语句

创建表 CREATE TABLE student ( id INTEGER PRIMARY KEY, -- 学号&#xff0c;主键 name TEXT NOT NULL, -- 姓名&#xff0c;不能为空 age INTEGER, -- 年龄 gender TEXT -- 性别 ); SQLite常用数据类型 主键 …

蓝桥杯补题

方法技巧&#xff1a; 1.进行循环暴力骗分&#xff0c;然后每一层的初始进行判断&#xff0c;如果已经不满足题意了&#xff0c;那么久直接continue&#xff0c;后面的循环就不用浪费时间了。我们可以把题目所给的等式&#xff0c;比如说有四个未知量&#xff0c;那么我们可以用…

配置与管理代理服务器

安装squid Squid软件包在标准yum存储库中可用&#xff0c;因此&#xff0c;我们正在使用yum命令安装Squid代理。 [rootserver ~]# dnf install -y squid //安装 [rootserver ~]#systemctl enable --now squid.service [rootserver ~]#systemctl status squid.serv…

《从零搭建Vue3项目实战》(AI辅助搭建Vue3+ElemntPlus后台管理项目)零基础入门系列第六篇:页面跳转功能实现(Router的引入和使用)

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 《从零搭建Vue3项目实战》&#xff08;AI辅助…

Windows 图形显示驱动开发-WDDM 2.0功能_分配用法跟踪

随着分配列表的消失&#xff0c;视频内存管理器 (VidMm) 不再能够查看特定命令缓冲区中引用的分配。 因此&#xff0c;VidMm 不再能够跟踪分配使用情况和处理相关同步。 此责任现在由用户模式驱动程序 (UMD) 承担。 具体而言&#xff0c;UMD 需要处理与直接 CPU 访问分配和重命…

TCP 与 UDP

TCP 与 UDP 的区别&#xff08;重要&#xff09; 是否面向连接&#xff1a;UDP 在传送数据之前不需要先建立连接。而 TCP 提供面向连接的服务&#xff0c;在传送数据之前必须先建立连接&#xff0c;数据传送结束后要释放连接。是否是可靠传输&#xff1a;远地主机在收到 UDP 报…