赞
踩
使用TuShare获取数据(需要在tushare网站申请账号,获取token号)
取1-4月数据作为训练集,5月数据作为测试集(测试集数据提取代码同训练集)
- ts.set_token('208cf0f7e03acf9024568071ab959d8cf3d1908385a7009906dc66d5')
- pro = ts.pro_api()
-
- time_temp = datetime.datetime.now() - datetime.timedelta(days=1)
- end_dt = time_temp.strftime('%Y%m%d')
-
- #准备训练集数据
-
- df = ts.pro_bar(ts_code='603912.SH', start_date='20210101', end_date='20210501', freq='D')
- df.head() #用 df.head() 可以查看一下下载下来的股票价格数据,显示数据如下:
-
- #把数据按时间调转顺序,最新的放后面
- df = df.iloc[::-1]
- df.reset_index(inplace=True)
- # print(df)
-
- training_set = df.loc[:, ['close']]
- #只取价格数据,不要表头等内容
- training_set = training_set.values
- #数据归一化
- sc = MinMaxScaler(feature_range = (0, 1))
- training_set_scaled = sc.fit_transform(training_set)
- # print(training_set_scaled)
-
- X_train = []
- y_train = []
- devia=10
- for i in range(devia, len(training_set_scaled)):
- X_train.append(training_set_scaled[i-devia:i])
- y_train.append(training_set_scaled[i, training_set_scaled.shape[1] - 1])
-
- X_train, y_train = np.array(X_train), np.array(y_train)
- print(X_train.shape)
- print(y_train.shape)
参考博客:人人都能看懂的LSTM - 知乎 (zhihu.com)
LSTM细节分析理解(pytorch版) - 知乎 (zhihu.com)
容易出现问题的地方是LSTM的输入和输出以及他们之间的关系,下面借这张图来说明一下:
我们要做的是通过对被预测序列(在此为时序序列)的学习 ,来预测该序列后面最新一天的数值。
输入即被预测序列,输入大小为batch_size*seq_len*input_size(每个时序的特征数量)——具体介绍可以看pytorch的官方文档(见下文代码部分)
我们要获取的输出是最新一天的数据,大小为batch_size*1。
明白了这些之后我们来看lstm网络的结构(下图),input和output已经清楚了,假设input的时间序列长度为t,每个时间对应的数据都进入一个蓝色方块,这样的蓝色方块一共有n层,是lstm的隐藏层。然后我们再横着看,在每一层蓝色方块中,左边的蓝色方块的值会作用于右边的蓝色方块,也就是前一天的数据对后面的数据造成的影响。
这样最右上角蓝色方块(t,n)的输出,就经历了所有隐藏层的输出,也经历了所有之前时间序列的作用,就是我们想得到的预测值。
API文档:LSTM — PyTorch 1.9.0 documentation
将LSTM模型构建为一个类,需要初始化init()函数和forward()函数。
- class LSTMNET(nn.Module):
- def __init__(self, input_size=1, hidden_layer_size=160, output_size=1,num_layers=8):
- super(LSTMNET,self).__init__()
- self.lstm_layer=nn.LSTM(input_size, hidden_layer_size, num_layers, batch_first=True)
- self.out_layer1 = nn.Linear(hidden_layer_size,output_size,bias=True)
- self.out_layer2 = nn.Linear(num_layers,output_size,bias=True)
-
- def forward(self,share):
- out,(h,c)=self.lstm_layer(share.to(torch.float32))
- out=h
- a,b,c=out.shape
- out=out.reshape(b,a)
- out=self.out_layer2(out)
- return out
采用RMSE(均方根误差)作为损失函数对模型进行优化
- for i in range(epochs):
- for shares, labels in train_loader:
- train = Variable(shares, requires_grad=True)
- labels = Variable(labels, requires_grad=True)
- outputs= model(train)
-
- loss_mse = loss_MSE(outputs.float(), labels.float())
- loss_rmse = torch.sqrt(loss_mse)
- loss_mae = loss_MAE(outputs.float(), labels.float())
-
- optimizer.zero_grad()
- loss_rmse.backward()
- optimizer.step()
-
- count=count+1
- if count%100==0:
- rmse.append(loss_rmse.data)
- mae.append(loss_mae.data)
-
- if i==epochs*bs-1:
- a,_=outputs.shape
- for j in range(a):
- pred.append(outputs[j])
- actl.append(labels[j])
-
- print("epoch:{} Train: RMSE:{:.8f} MAE:{:.8f} ".format(i, loss_rmse.data, loss_mae.data))
画出原始股票价格和预测股票价格的对比图像,同时绘制损失函数在训练过程中的图像
- plt.figure()
- plt.plot(pred,"r-")
- plt.plot(actl,"b-")
-
- plt.figure()
- plt.plot(rmse,"r-")
- plt.plot(mae,"b--")
预测结果:
完整代码:(将在项目结束后公开,敬请期待)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。