使用 PyTorch 构建 LSTM 股票价格预测模型

目录

      • 引言
      • 准备工作
      • 1. 训练模型(`train.py`)
      • 2. 模型定义(`model.py`)
      • 3. 测试模型和可视化(`test.py`)
      • 使用说明
      • 模型调整
      • 结论

引言

在金融领域,股票价格预测是一个重要且具有挑战性的任务。随着深度学习的发展,长短期记忆网络(LSTM)因其在处理时间序列数据方面的出色表现而受到关注。本篇博客将指导你如何使用PyTorch构建一个LSTM模型来预测股票价格,我们将逐步介绍数据预处理、模型训练和结果可视化的完整流程。

准备工作

  1. 安装依赖
    确保你已经安装了以下 Python 库:

    pip install pandas numpy torch matplotlib scikit-learn
    
  2. 下载数据
    使用 yfinance 库下载你感兴趣的股票的历史数据,并保存为 CSV 文件。我们这里使用 Apple(AAPL)过去五年的数据,文件命名为 AAPL_5y_data.csv。以下是一个下载数据的代码示例:

    import yfinance as yf# 下载Apple股票过去5年的数据
    data = yf.download('AAPL', start='2019-01-01', end='2024-01-01')
    data.to_csv('AAPL_5y_data.csv')
    

1. 训练模型(train.py

在这个脚本中,我们将读取 CSV 文件,归一化数据,并使用 LSTM 模型进行训练。

import pandas as pd
import numpy as np
import torch
import torch.nn as nn
from sklearn.preprocessing import MinMaxScaler
from model import LSTM  # 导入LSTM类# 设置随机种子
torch.manual_seed(42)# 读取CSV文件
file_path = 'AAPL_5y_data.csv'  # 替换为你的CSV文件路径
data = pd.read_csv(file_path)# 确保日期列是 datetime 类型
data['Date'] = pd.to_datetime(data['Date'])
data.set_index('Date', inplace=True)# 选择多特征:'Close', 'Open', 'High', 'Low', 'Volume'
features = data[['Close', 'Open', 'High', 'Low', 'Volume']].values# 数据归一化
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(features)# 准备训练和测试数据
train_size = int(len(scaled_data) * 0.8)
train_data = scaled_data[:train_size]
test_data = scaled_data[train_size:]def create_dataset(data, time_step=1):X, y = [], []for i in range(len(data) - time_step - 1):a = data[i:(i + time_step)]X.append(a)y.append(data[i + time_step, 0])  # 预测收盘价return np.array(X), np.array(y)# 创建数据集
time_step = 50  # 时间步长
X_train, y_train = create_dataset(train_data, time_step)# 转换为PyTorch张量
X_train = torch.from_numpy(X_train).float()
y_train = torch.from_numpy(y_train).float().view(-1, 1)# 初始化模型、损失函数和优化器
model = LSTM()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)# 训练模型
num_epochs = 300
for epoch in range(num_epochs):model.train()optimizer.zero_grad()outputs = model(X_train)loss = criterion(outputs, y_train)loss.backward()optimizer.step()if (epoch + 1) % 10 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 保存模型
torch.save(model.state_dict(), 'lstm_model.pth')
print("模型已保存为 'lstm_model.pth'")

2. 模型定义(model.py

在这个文件中定义 LSTM 模型结构。

import torch
import torch.nn as nnclass LSTM(nn.Module):def __init__(self):super(LSTM, self).__init__()self.lstm = nn.LSTM(input_size=5, hidden_size=100, num_layers=2, batch_first=True)self.fc = nn.Linear(100, 1)def forward(self, x):out, _ = self.lstm(x)out = self.fc(out[:, -1, :])  # 取最后时间步的输出return out

3. 测试模型和可视化(test.py

在这个脚本中,我们将加载训练好的模型,并使用测试数据进行预测和可视化。

import pandas as pd
import numpy as np
import torch
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from model import LSTM  # 导入LSTM类# 设置字体为SimHei,用于显示中文
plt.rcParams['font.family'] = 'SimHei'# 读取CSV文件
file_path = 'AAPL_5y_data.csv'  # 替换为你的CSV文件路径
data = pd.read_csv(file_path)# 确保日期列是 datetime 类型
data['Date'] = pd.to_datetime(data['Date'])
data.set_index('Date', inplace=True)# 选择多特征:'Close', 'Open', 'High', 'Low', 'Volume'
features = data[['Close', 'Open', 'High', 'Low', 'Volume']].values# 数据归一化
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(features)# 准备训练和测试数据
train_size = int(len(scaled_data) * 0.8)
train_data = scaled_data[:train_size]
test_data = scaled_data[train_size:]def create_dataset(data, time_step=1):X, y = [], []for i in range(len(data) - time_step - 1):a = data[i:(i + time_step)]X.append(a)y.append(data[i + time_step, 0])  # 预测收盘价return np.array(X), np.array(y)# 创建测试数据集
time_step = 50  # 时间步长
X_test, y_test = create_dataset(test_data, time_step)# 转换为PyTorch张量
X_test = torch.from_numpy(X_test).float()
y_test = torch.from_numpy(y_test).float().view(-1, 1)# 加载模型
model = LSTM()
model.load_state_dict(torch.load('lstm_model.pth'))
model.eval()# 测试模型
with torch.no_grad():test_outputs = model(X_test)# test_outputs 是预测的收盘价,将其重新归一化为原始价格test_outputs = scaler.inverse_transform(np.concatenate((test_outputs.numpy(), np.zeros((test_outputs.shape[0], 4))), axis=1))[:, 0]  # 反归一化收盘价y_test_inverse = scaler.inverse_transform(np.concatenate((y_test.numpy(), np.zeros((y_test.shape[0], 4))), axis=1))[:, 0]# 可视化结果
plt.figure(figsize=(14, 7))
plt.plot(data.index[-len(y_test):], y_test_inverse, label='真实价格', color='blue')
plt.plot(data.index[-len(test_outputs):], test_outputs, label='预测价格', color='red')
plt.title('股票价格预测')
plt.xlabel('日期')
plt.ylabel('价格')
plt.legend()
plt.show()

使用说明

  1. 保存脚本

    • 将训练脚本代码保存为 train.py
    • 将模型定义代码保存为 model.py
    • 将测试脚本代码保存为 test.py
  2. 运行训练

    • 在命令行中运行训练脚本:
      python train.py
      
    • 训练完成后,模型将保存为 lstm_model.pth
  3. 运行测试和可视化

    • 在命令行中运行测试脚本:

      python test.py
      
    • 这将加载已训练的模型,并可视化预测结果。
      在这里插入图片描述
      这只是一个演示,模型的预测效果还有待进一步优化。

模型调整

如果预测的价格和真实价格差距较大,可能是由于以下几个原因:

  1. 数据规模不足

    • 如果训练数据不足,模型可能无法学到市场的长期趋势。
    • 改进:使用更多的历史数据,尽量包括多年的数据。可以尝试增加数据的时间跨度。
  2. 数据预处理问题

    • 数据没有正确归一化,或归一化范围过窄。
    • 改进:检查 MinMaxScaler 的应用。你可以尝试不同的归一化范围,例如 (0, 1)(-1, 1),也可以使用其他标准化方法(例如 StandardScaler)。
  3. 模型复杂度不足

    • 模型的层数或隐藏单元数量可能不足以捕捉数据的复杂性。
    • 改进:增加 LSTM 的隐藏层数量或隐藏单元数量。你还可以考虑添加其他类型的层,例如卷积层(CNN)或全连接层,以提高模型的表达能力。
  4. 超参数调整

    • 学习率、批大小和时间步长等超参数可能需要调整以优化模型性能。
    • 改进:尝试不同的学习率(例如,0.001、0.0001 等)、不同的批大小(如 16、32、64)和时间步长(如 30、60)。
  5. 更改损失函数

    • 在某些情况下,使用不同的损失函数可能有助于模型的收敛。
    • 改进:可以尝试使用其他损失函数,例如 Huber 损失函数(nn.SmoothL1Loss)或自定义损失函数,以更好地适应数据。

结论

通过使用 PyTorch 构建 LSTM 模型,我们成功地实现了股票价格的预测。在这个过程中,我们学习了如何处理时间序列数据,构建和训练深度学习模型,以及如何评估和可视化预测结果。尽管模型的性能可能需要进一步的优化和调整,但这个示例为未来的工作奠定了基础。

希望这篇博客能够帮助你在股票价格预测方面取得更好的成果。欢迎分享你的成果和经验,或者提出你的问题!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

即时通讯增加Redis渠道

情况说明 在本地和服务器分别启动im服务,当本地发送消息时,会发现服务器上并没有收到消息 初版im只支持单机版,不支持分布式的情况。此次针对该情况对项目进行优化,文档中贴出的代码非完整代码,可自行查看参考资料[2] 代码结构调…

电机PWM控制中的定时器配置与信号极性对电机转向的影响分析

文章目录 摘要关键词1. 引言2. PWM控制与定时器配置3. 实验与问题描述3.1 定时器配置代码分析3.2 问题分析 4. 解决方案5. 实验结果6. 结论 电机PWM控制中的定时器配置与信号极性对电机转向的影响分析 摘要 PWM(脉宽调制)信号是控制电机速度与方向的常…

Docker安装ocserv教程(效果极佳)

本章教程,介绍如何在Debain系统上安装ocserv。安装方式是使用Docker方式部署。 一、安装Docker curl -sSL https://file.ewbang.com/docker/debian/install_docker.sh -o install_docker.sh && bash install_docker.sh二、拉取镜像 docker pull tommylau/ocserv

数据库-01MYSQL-002MySQL5.7错误连接未释放导致数据库连接失败

**报错信息&#xff1a;** 信息&#xff1a; 11276:无法创建数据库<NAMSE_89>的连接:jdbc:mysql://xx.xx.xx.xx:3306/v_report xxxx_user 23246:无法创建数据库<NAMSE_89>的连接:jdbc:mysql://xx.xx.xx.xx:3306/v_report xnzb_user null, message from server: &qu…

工作窃取(Work-Stealing)是什么?

工作窃取&#xff08;Work-Stealing&#xff09;是什么&#xff1f; 工作窃取是一种并行任务调度算法&#xff0c;用于最大化 CPU 资源利用率&#xff0c;特别适合任务分解递归式的并发场景。其核心思想是&#xff1a;当某个线程完成了自己分配的任务后&#xff0c;如果其他线…

wsl下将exfat/NTFS类型的硬盘准换为ext4

问题 wsl 直接读 windows 文件速度慢如果 wsl 挂载一个 ext4 的硬盘会快些 方法 查看物理盘号 首先&#xff0c;你需要获取外置硬盘的磁盘标识符。你可以使用 Windows 的 diskpart 工具来获取&#xff1a; 打开命令提示符&#xff08;以管理员身份运行&#xff09;。 输入…

Jsoup在Java中:解析京东网站数据

对于电商网站如京东来说&#xff0c;其页面上的数据包含了丰富的商业洞察。对于开发者而言&#xff0c;能够从这些网站中提取有价值的信息&#xff0c;进行分析和应用&#xff0c;无疑是一项重要的技能。本文将介绍如何使用Java中的Jsoup库来解析京东网站的数据。 Jsoup简介 …

银河麒麟(debian)下安装postgresql、postgis

1、安装postgresql、postgis sudo apt update sudo apt install postgresql postgresql-contrib sudo apt install postgis postgresql-12-postgis-32、创建一个使用postgis的数据库 sudo -i -u postgres #postgres管理员用户createdb gisdb #创建新的gisdb数据库 psql -d gi…

c++日常积累

在 C 中&#xff0c;可以直接将 int 类型的值赋值给 bool 类型。C 会自动进行类型转换&#xff0c;任何非零的 int 值都会被转换为 true&#xff0c;而 0 会被转换为 false。 QDialog 有一个 finished(int) 信号&#xff0c;该信号在对话框关闭时发出&#xff0c;并传递一个整…

Linux部署redis保姆级教程

一、版本说明 Redis版本号(本文的版本号是6.2.12)的第二位如果是偶数,代表稳定版本,如果是奇数,代表非稳定版本。 所有历史版本下载地址:Index of /releases/ 二、基于压缩包安装(推荐) 2.1安装依赖 2.1.1安装gcc: yum -y install gcc 2.1.2验证gcc是否安装成功:(…

Vue使用OnlyOffice预览文档方案

服务器安装OnlyOffice ~~ 找后台或运维OfficePreview.vue <template><div id"officePreview"></div> </template><script setup> import { onMounted } from "vue";const props defineProps({previewUrl: {type: String,d…

Linux--多路转接之epoll

上一篇:Linux–多路转接之select epoll epoll 是 Linux 下多路复用 I/O 接口 select/poll 的增强版本&#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统 CPU 利用率。它是 Linux 下多路复用 API 的一个选择&#xff0c;相比 select 和 poll&#xff0c…

通过梧桐数据库分析客户价值

在现代商业环境中&#xff0c;对客户价值的分析至关重要。通过分析客户的消费行为&#xff0c;企业可以更好地理解其客户群体&#xff0c;并据此制定更有效的市场策略。本文将介绍如何使用SQL查询来分析客户价值&#xff0c;包括计算每个客户的总消费金额&#xff0c;并根据这些…

DevExpress WPF v24.1新版亮点:PDF查看器、富文本编辑器功能升级

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 DevExpress WPF控件日…

1971. 寻找图中是否存在路径

有一个具有 n 个顶点的 双向 图&#xff0c;其中每个顶点标记从 0 到 n - 1&#xff08;包含 0 和 n - 1&#xff09;。图中的边用一个二维整数数组 edges 表示&#xff0c;其中 edges[i] [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接&#x…

Laravel使用 Swagger

一、Swagger 基础 1、 什么是Swagger Swagger 是一个基于 Open Api 规范的 API 管理工具&#xff0c;通过项目注解的形式自动构建 API 文档&#xff0c;拥有在线调试的功能。提供了多语言的客户端&#xff0c;laravel 中也有相应的扩展包。 二、Swagger 接入 1&#xff0c;用…

第21~22周Java主流框架入门-Spring 3.SpringJDBC事务管理

Spring JDBC模块与事务管理课程总结 1. 课程介绍 本课程主要讲解Spring框架中的JDBC模块及其事务管理的相关内容&#xff0c;重点包括以下三个方面&#xff1a; Spring JDBC模块及核心对象JDBC Template的使用 通过学习如何使用Spring JDBC模块&#xff0c;了解JDBC Template…

Vue3 学习笔记(一)Vue3 介绍及环境部署

一、Vue.js 简介 1、Vue.js 是什么&#xff1f; Vue.js&#xff08;读音 /vjuː/, 类似于 view&#xff09; 是一套构建用户界面的渐进式框架。Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件…

【ARM】ARM架构参考手册_Part B 内存和系统架构(2)

目录 2.1 关于系统控制协处理器 2.2 寄存器 2.1 关于系统控制协处理器 所有标准内存和系统设施都由协处理器15&#xff08;CP15&#xff09;控制&#xff0c;因此它被称为系统控制协处理器。有些设施也使用其他控制方法&#xff0c;这些方法在描述这些设施的章节中有描述。例…

【Mysql】-锁,行级锁

Mysql mysql中的行锁 在 MySQL 的 InnoDB 存储引擎中&#xff0c;行级锁通常是加在索引上的&#xff0c;而不是直接加在数据行上。这种机制是基于索引的锁定策略&#xff0c;具体来说&#xff1a; 主键索引&#xff1a;如果查询更新使用了主键进行查找&#xff0c;InnoDB 会直…