pytorch_LSTM预测股票行情

7.8 用LSTM预测股票行情

7.8.1 导入数据

# Tushare是一个免费、开源的python财经数据接口包。主要实现对股票等金融数据从数据采集、清洗加工 到 数据存储的过程
import tushare as ts  
cons = ts.get_apis()
#获取沪深指数(000300)的信息,包括交易日期(datetime)、开盘价(open)、收盘价(close),
#最高价(high)、最低价(low)、成交量(vol)、成交金额(amount)、涨跌幅(p_change)
df = ts.bar('000300', conn=cons, asset='INDEX', start_date='2010-01-01', end_date='')
## 由于接口更新了,需要进行注册才能使用,在官网https://tushare.pro/中进行注册,具体如下,之后使用进行调用,等工作不忙后我会重新修改代码
#token='你的token'
#cons = ts.pro_api(token)
#df = cons.daily(ts_code='000001.SZ', start_date='20220301', end_date='20220317')

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本接口即将停止更新,请尽快使用Pro版接口:https://waditu.com/document/2
df = df.dropna()
df.to_csv('sh300.csv')
df.columns
Index(['code', 'open', 'close', 'high', 'low', 'vol', 'amount', 'p_change'], dtype='object')

7.8.2 数据概览

df.describe()
openclosehighlowvolamountp_change
count2751.0000002751.0000002751.0000002751.0000002.751000e+032.751000e+032751.000000
mean3312.7088593315.5001743341.2186803284.8662521.142116e+061.474558e+110.024391
std782.131796782.340288788.871807773.0299558.836562e+051.300980e+111.454752
min2079.8700002086.9700002118.7900002023.1700002.190120e+052.120044e+10-8.750000
25%2611.7600002613.5200002632.3550002591.3750006.063705e+056.562710e+10-0.640000
50%3273.8900003276.6700003304.2600003247.6900008.833630e+051.065559e+110.040000
75%3822.7350003827.8700003847.8550003790.3250001.329321e+061.751813e+110.720000
max5922.0700005807.7200005930.9100005747.6600006.864391e+069.494980e+116.710000

7.8.3 预处理数据

import pandas as pd
import matplotlib.pyplot as plt
import datetime
import torch
import torch.nn as nn
import numpy as np
from torch.utils.data import Dataset, DataLoader
import torchvision
import torchvision.transforms as transforms

%matplotlib inline
n = 30
LR = 0.001
EPOCH = 200
batch_size=20
train_end =-600

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
#通过一个序列来生成一个31*(count(*)-train_end)矩阵(用于处理时序的数据)
#其中最后一列维标签数据。就是把当天的前n天作为参数,当天的数据作为label
def generate_data_by_n_days(series, n, index=False):
    if len(series) <= n:
        raise Exception("The Length of series is %d, while affect by (n=%d)." % (len(series), n))
    df = pd.DataFrame()
    for i in range(n):
        df['c%d' % i] = series.tolist()[i:-(n - i)]        
    df['y'] = series.tolist()[n:]
    
    if index:
        df.index = series.index[n:]
    return df

#参数n与上相同。train_end表示的是后面多少个数据作为测试集。
def readData(column='high', n=30, all_too=True, index=False, train_end=-500):
    df = pd.read_csv("sh300.csv", index_col=0)
    #以日期为索引
    df.index = list(map(lambda x: datetime.datetime.strptime(x, "%Y-%m-%d"), df.index))
    #获取每天的最高价
    df_column = df[column].copy()
    #拆分为训练集和测试集
    df_column_train, df_column_test = df_column[:train_end], df_column[train_end - n:]
    #生成训练数据
    df_generate_train = generate_data_by_n_days(df_column_train, n, index=index)
    if all_too:
        return df_generate_train, df_column, df.index.tolist()
    return df_generate_train

7.8.4 定义模型

class RNN(nn.Module):
    def __init__(self, input_size):
        super(RNN, self).__init__()
        self.rnn = nn.LSTM(
            input_size=input_size,
            hidden_size=64,
            num_layers=1,
            batch_first=True
        )
        self.out = nn.Sequential(
            nn.Linear(64, 1)
        )

    def forward(self, x):
        r_out, (h_n, h_c) = self.rnn(x, None)  #None即隐层状态用0初始化
        out = self.out(r_out)
        return out


class mytrainset(Dataset):
    def __init__(self, data):        
        self.data, self.label = data[:, :-1].float(), data[:, -1].float()
             
    def __getitem__(self, index):
        return self.data[index], self.label[index]

    def __len__(self):
        return len(self.data)

7.8.5 训练模型

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
# 获取训练数据、原始数据、索引等信息
df, df_all, df_index = readData('high', n=n, train_end=train_end)

#可视化原高价数据
df_all = np.array(df_all.tolist())
plt.plot(df_index, df_all, label='real-data')
plt.legend(loc='upper right')  


#对数据进行预处理,规范化及转换为Tensor
df_numpy = np.array(df)

df_numpy_mean = np.mean(df_numpy)
df_numpy_std = np.std(df_numpy)

df_numpy = (df_numpy - df_numpy_mean) / df_numpy_std
df_tensor = torch.Tensor(df_numpy)


trainset = mytrainset(df_tensor)
trainloader = DataLoader(trainset, batch_size=batch_size, shuffle=False)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WC61e7BN-1619706519879)(output_16_0.png)]

#记录损失值,并用tensorboardx在web上展示
from tensorboardX import SummaryWriter
writer = SummaryWriter(log_dir='logs')

rnn = RNN(n).to(device)
optimizer = torch.optim.Adam(rnn.parameters(), lr=LR)  
loss_func = nn.MSELoss()

for step in range(EPOCH):
    for tx, ty in trainloader:
        tx=tx.to(device)
        ty=ty.to(device)
        #在第1个维度上添加一个维度为1的维度,形状变为[batch,seq_len,input_size]
        output = rnn(torch.unsqueeze(tx, dim=1)).to(device)
        loss = loss_func(torch.squeeze(output), ty)
        optimizer.zero_grad()  
        loss.backward()  
        optimizer.step()
    writer.add_scalar('sh300_loss', loss, step)  
D:\sofewore\anaconda\lib\site-packages\torch\nn\modules\loss.py:432: UserWarning: Using a target size (torch.Size([1])) that is different to the input size (torch.Size([])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)

7.8.6 测试模型

generate_data_train = []
generate_data_test = []

test_index = len(df_all) + train_end

df_all_normal = (df_all - df_numpy_mean) / df_numpy_std
df_all_normal_tensor = torch.Tensor(df_all_normal)
for i in range(n, len(df_all)):
    x = df_all_normal_tensor[i - n:i].to(device)
    #rnn的输入必须是3维,故需添加两个1维的维度,最后成为[1,1,input_size]
    x = torch.unsqueeze(torch.unsqueeze(x, dim=0), dim=0)
    
    y = rnn(x).to(device)
    if i < test_index:
        generate_data_train.append(torch.squeeze(y).detach().cpu().numpy() * df_numpy_std + df_numpy_mean)
    else:
        generate_data_test.append(torch.squeeze(y).detach().cpu().numpy() * df_numpy_std + df_numpy_mean)
plt.plot(df_index[n:train_end], generate_data_train, label='generate_train')
plt.plot(df_index[train_end:], generate_data_test, label='generate_test')
plt.plot(df_index[train_end:], df_all[train_end:], label='real-data')
plt.legend()
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ib6LvlGA-1619706519885)(output_19_0.png)]

plt.clf()
plt.plot(df_index[train_end:-500], df_all[train_end:-500], label='real-data')
plt.plot(df_index[train_end:-500], generate_data_test[-600:-500], label='generate_test')
plt.legend()
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-No24KTtM-1619706519889)(output_20_0.png)]

  • 22
    点赞
  • 172
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
Pytorch是一种深度学习框架,可以用来构建神经网络模型股票预测是金融领域的研究热点,支持向量机(SVM)、随机森林(RF)以及循环神经网络(RNN)等都可以用来做股票预测。其中LSTM(Long Short-Term Memory)是一种特殊的循环神经网络,能够解决传统RNN存在的梯度消失或梯度爆炸的问题,能够更好地处理长期依赖关系。 针对股票预测问题,可以通过Pytorch搭建LSTM模型进行预测模型的输入是历史股价的时间序列数据,输出是未来一段时间(比如一天或一周)的股价预测。具体步骤包括数据预处理、数据划分、模型搭建、模型训练和预测等。 对于数据预处理,应该先对原始数据进行清理和处理,去除异常值和缺失值,然后对数据进行归一化处理,以便使得数据尺度一致,便于训练。对于数据划分,将历史数据划分为训练集和测试集,通常采用80%的数据作为训练集、20%的数据作为测试集,并采用滚动窗口的方式将数据进行重叠,以增加数据量和模型的准确性。 接着,搭建LSTM模型。可以使用PyTorch中预定义好的LSTM模型,也可以自定义LSTM模型进行训练。要注意设定好模型中的超参数,如隐藏层的大小、激活函数、学习率等等。进行模型训练时,使用训练集进行反向传播和优化,以降低损失函数的值,提高模型预测准确率。最后,使用测试集对模型进行预测,并计算预测值与真实值之间的误差。 总之,利用pytorch构建的LSTM模型可以对股票价格进行预测。具体问题需要根据不同需求进行实际操作。
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值