竞赛保研 LSTM的预测算法 - 股票预测 天气预测 房价预测

0 简介

今天学长向大家介绍LSTM基础

基于LSTM的预测算法 - 股票预测 天气预测 房价预测

这是一个较为新颖的竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 基于 Keras 用 LSTM 网络做时间序列预测

时间序列预测是一类比较困难的预测问题。

与常见的回归预测模型不同,输入变量之间的“序列依赖性”为时间序列问题增加了复杂度。

一种能够专门用来处理序列依赖性的神经网络被称为 递归神经网络(Recurrent Neural
Networks、RNN)。因其训练时的出色性能,长短记忆网络(Long Short-Term Memory
Network,LSTM)是深度学习中广泛使用的一种递归神经网络(RNN)。

在本篇文章中,将介绍如何在 R 中使用 keras 深度学习包构建 LSTM 神经网络模型实现时间序列预测。

  • 如何为基于回归、窗口法和时间步的时间序列预测问题建立对应的 LSTM 网络。
  • 对于非常长的序列,如何在构建 LSTM 网络和用 LSTM 网络做预测时保持网络关于序列的状态(记忆)。

2 长短记忆网络

长短记忆网络,或 LSTM 网络,是一种递归神经网络(RNN),通过训练时在“时间上的反向传播”来克服梯度消失问题。

LSTM 网络可以用来构建大规模的递归神经网络来处理机器学习中复杂的序列问题,并取得不错的结果。

除了神经元之外,LSTM 网络在神经网络层级(layers)之间还存在记忆模块。

一个记忆模块具有特殊的构成,使它比传统的神经元更“聪明”,并且可以对序列中的前后部分产生记忆。模块具有不同的“门”(gates)来控制模块的状态和输出。一旦接收并处理一个输入序列,模块中的各个门便使用
S 型的激活单元来控制自身是否被激活,从而改变模块状态并向模块添加信息(记忆)。

一个激活单元有三种门:

  • 遗忘门(Forget Gate):决定抛弃哪些信息。
  • 输入门(Input Gate):决定输入中的哪些值用来更新记忆状态。
  • 输出门(Output Gate):根据输入和记忆状态决定输出的值。

每一个激活单元就像是一个迷你状态机,单元中各个门的权重通过训练获得。

3 LSTM 网络结构和原理

long short term memory,即我们所称呼的LSTM,是为了解决长期以来问题而专门设计出来的,所有的RNN都具有一种重复

在这里插入图片描述

LSTM 同样是这样的结构,但是重复的模块拥有一个不同的结构。不同于单一神经网络层,这里是有四个,以一种非常特殊的方式进行交互。

在这里插入图片描述

不必担心这里的细节。我们会一步一步地剖析 LSTM 解析图。现在,我们先来熟悉一下图中使用的各种元素的图标。

在这里插入图片描述

在上面的图例中,每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入。粉色的圈代表 pointwise
的操作,诸如向量的和,而黄色的矩阵就是学习到的神经网络层。合在一起的线表示向量的连接,分开的线表示内容被复制,然后分发到不同的位置。

3.1 LSTM核心思想

LSTM的关键在于细胞的状态整个(如下图),和穿过细胞的那条水平线。

细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。

在这里插入图片描述
门可以实现选择性地让信息通过,主要是通过一个 sigmoid 的神经层 和一个逐点相乘的操作来实现的。

在这里插入图片描述
sigmoid 层输出(是一个向量)的每个元素都是一个在 0 和 1 之间的实数,表示让对应信息通过的权重(或者占比)。比如, 0
表示“不让任何信息通过”, 1 表示“让所有信息通过”。

LSTM通过三个这样的本结构来实现信息的保护和控制。这三个门分别输入门、遗忘门和输出门。

3.2 遗忘门

在我们 LSTM 中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为忘记门层完成。该门会读取和,输出一个在 0到
1之间的数值给每个在细胞状态中的数字。1 表示“完全保留”,0 表示“完全舍弃”。

让我们回到语言模型的例子中来基于已经看到的预测下一个词。在这个问题中,细胞状态可能包含当前主语的性别,因此正确的代词可以被选择出来。当我们看到新的主语,我们希望忘记旧的主语。

在这里插入图片描述
其中

在这里插入图片描述

表示的是 上一时刻隐含层的 输出,

在这里插入图片描述

表示的是当前细胞的输入。σ表示sigmod函数。

3.3 输入门

下一步是决定让多少新的信息加入到 cell 状态 中来。实现这个需要包括两个步骤:首先,一个叫做“input gate layer ”的 sigmoid
层决定哪些信息需要更新;一个 tanh 层生成一个向量,也就是备选的用来更新的内容。在下一步,我们把这两部分联合起来,对 cell 的状态进行一个更新。

在这里插入图片描述

3.4 输出门

最终,我们需要确定输出什么值。这个输出将会基于我们的细胞状态,但是也是一个过滤后的版本。首先,我们运行一个 sigmoid
层来确定细胞状态的哪个部分将输出出去。接着,我们把细胞状态通过 tanh 进行处理(得到一个在 -1 到 1 之间的值)并将它和 sigmoid
门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。

在语言模型的例子中,因为他就看到了一个代词,可能需要输出与一个动词相关的信息。例如,可能输出是否代词是单数还是负数,这样如果是动词的话,我们也知道动词需要进行的词形变化。

在这里插入图片描述

4 基于LSTM的天气预测

4.1 数据集

在这里插入图片描述

如上所示,每10分钟记录一次观测值,一个小时内有6个观测值,一天有144(6x24)个观测值。

给定一个特定的时间,假设要预测未来6小时的温度。为了做出此预测,选择使用5天的观察时间。因此,创建一个包含最后720(5x144)个观测值的窗口以训练模型。

下面的函数返回上述时间窗以供模型训练。参数 history_size 是过去信息的滑动窗口大小。target_size
是模型需要学习预测的未来时间步,也作为需要被预测的标签。

下面使用数据的前300,000行当做训练数据集,其余的作为验证数据集。总计约2100天的训练数据。

4.2 预测示例

多步骤预测模型中,给定过去的采样值,预测未来一系列的值。对于多步骤模型,训练数据再次包括每小时采样的过去五天的记录。但是,这里的模型需要学习预测接下来12小时的温度。由于每10分钟采样一次数据,因此输出为72个预测值。

    future_target = 72x_train_multi, y_train_multi = multivariate_data(dataset, dataset[:, 1], 0,TRAIN_SPLIT, past_history,future_target, STEP)x_val_multi, y_val_multi = multivariate_data(dataset, dataset[:, 1],TRAIN_SPLIT, None, past_history,future_target, STEP)

划分数据集

    
​    train_data_multi = tf.data.Dataset.from_tensor_slices((x_train_multi, y_train_multi))
​    train_data_multi = train_data_multi.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()
​    val_data_multi = tf.data.Dataset.from_tensor_slices((x_val_multi, y_val_multi))val_data_multi = val_data_multi.batch(BATCH_SIZE).repeat()

绘制样本点数据

def multi_step_plot(history, true_future, prediction):
​        plt.figure(figsize=(12, 6))
​        num_in = create_time_steps(len(history))
​        num_out = len(true_future)
​    plt.plot(num_in, np.array(history[:, 1]), label='History')plt.plot(np.arange(num_out)/STEP, np.array(true_future), 'bo',label='True Future')if prediction.any():plt.plot(np.arange(num_out)/STEP, np.array(prediction), 'ro',label='Predicted Future')plt.legend(loc='upper left')plt.show()for x, y in train_data_multi.take(1):multi_step_plot(x[0], y[0], np.array([0]))

在这里插入图片描述

此处的任务比先前的任务复杂一些,因此该模型现在由两个LSTM层组成。最后,由于需要预测之后12个小时的数据,因此Dense层将输出为72。

    
​    multi_step_model = tf.keras.models.Sequential()
​    multi_step_model.add(tf.keras.layers.LSTM(32,
​                                              return_sequences=True,
​                                              input_shape=x_train_multi.shape[-2:]))
​    multi_step_model.add(tf.keras.layers.LSTM(16, activation='relu'))
​    multi_step_model.add(tf.keras.layers.Dense(72))
​    multi_step_model.compile(optimizer=tf.keras.optimizers.RMSprop(clipvalue=1.0), loss='mae')

训练

    multi_step_history = multi_step_model.fit(train_data_multi, epochs=EPOCHS,steps_per_epoch=EVALUATION_INTERVAL,validation_data=val_data_multi,validation_steps=50)

在这里插入图片描述

在这里插入图片描述

5 基于LSTM的股票价格预测

5.1 数据集

股票数据总共有九个维度,分别是

在这里插入图片描述

5.2 实现代码

    import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport tensorflow as tfplt.rcParams['font.sans-serif']=['SimHei']#显示中文plt.rcParams['axes.unicode_minus']=False#显示负号


def load_data():
test_x_batch = np.load(r’test_x_batch.npy’,allow_pickle=True)
test_y_batch = np.load(r’test_y_batch.npy’,allow_pickle=True)
return (test_x_batch,test_y_batch)

#定义lstm单元
def lstm_cell(units):cell = tf.contrib.rnn.BasicLSTMCell(num_units=units,forget_bias=0.0)#activation默认为tanhreturn cell#定义lstm网络
def lstm_net(x,w,b,num_neurons):#将输入变成一个列表,列表的长度及时间步数inputs = tf.unstack(x,8,1)cells = [lstm_cell(units=n) for n in num_neurons]stacked_lstm_cells = tf.contrib.rnn.MultiRNNCell(cells)outputs,_ =  tf.contrib.rnn.static_rnn(stacked_lstm_cells,inputs,dtype=tf.float32)return tf.matmul(outputs[-1],w) + b#超参数
num_neurons = [32,32,64,64,128,128]#定义输出层的weight和bias
w = tf.Variable(tf.random_normal([num_neurons[-1],1]))
b = tf.Variable(tf.random_normal([1]))#定义placeholder
x = tf.placeholder(shape=(None,8,8),dtype=tf.float32)#定义pred和saver
pred = lstm_net(x,w,b,num_neurons)
saver = tf.train.Saver(tf.global_variables())if __name__ == '__main__':#开启交互式Sessionsess = tf.InteractiveSession()saver.restore(sess,r'D:\股票预测\model_data\my_model.ckpt')#载入数据test_x,test_y = load_data()#预测predicts = sess.run(pred,feed_dict={x:test_x})predicts = ((predicts.max() - predicts) / (predicts.max() - predicts.min()))#数学校准#可视化plt.plot(predicts,'r',label='预测曲线')plt.plot(test_y,'g',label='真实曲线')plt.xlabel('第几天/days')plt.ylabel('开盘价(归一化)')plt.title('股票开盘价曲线预测(测试集)')plt.legend()plt.show()#关闭会话sess.close()	

在这里插入图片描述

6 lstm 预测航空旅客数目

数据集

airflights passengers dataset下载地址

https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-
passengers.csv

这个dataset包含从1949年到1960年每个月的航空旅客数目,共12*12=144个数字。

下面的程序中,我们以1949-1952的数据预测1953的数据,以1950-1953的数据预测1954的数据,以此类推,训练模型。

预测代码

    import numpy as npimport matplotlib.pyplot as pltimport pandas as pdimport torchimport torch.nn as nnfrom sklearn.preprocessing import MinMaxScalerimport os


# super parameters
EPOCH = 400
learning_rate = 0.01
seq_length = 4 # 序列长度
n_feature = 12 # 序列中每个元素的特征数目。本程序采用的序列元素为一年的旅客,一年12个月,即12维特征。

# data
data = pd.read_csv('airline-passengers.csv')   # 共 "12年*12个月=144" 个数据
data = data.iloc[:, 1:5].values        # dataFrame, shape (144,1)
data = np.array(data).astype(np.float32)
sc = MinMaxScaler()
data = sc.fit_transform(data)          # 归一化
data = data.reshape(-1, n_feature)     # shape (12, 12)trainData_x = []
trainData_y = []
for i in range(data.shape[0]-seq_length):tmp_x = data[i:i+seq_length, :]tmp_y = data[i+seq_length, :]trainData_x.append(tmp_x)trainData_y.append(tmp_y)# model
class Net(nn.Module):def __init__(self, in_dim=12, hidden_dim=10, output_dim=12, n_layer=1):super(Net, self).__init__()self.in_dim = in_dimself.hidden_dim = hidden_dimself.output_dim = output_dimself.n_layer = n_layerself.lstm = nn.LSTM(input_size=in_dim, hidden_size=hidden_dim, num_layers=n_layer, batch_first=True)self.linear = nn.Linear(hidden_dim, output_dim)def forward(self, x):_, (h_out, _) = self.lstm(x)  # h_out是序列最后一个元素的hidden state# h_out's shape (batchsize, n_layer*n_direction, hidden_dim), i.e. (1, 1, 10)# n_direction根据是“否为双向”取值为1或2h_out = h_out.view(h_out.shape[0], -1)   # h_out's shape (batchsize, n_layer * n_direction * hidden_dim), i.e. (1, 10)h_out = self.linear(h_out)    # h_out's shape (batchsize, output_dim), (1, 12)return h_outtrain = True
if train:model = Net()loss_func = torch.nn.MSELoss()optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)# trainfor epoch in range(EPOCH):total_loss = 0for iteration, X in enumerate(trainData_x):  # X's shape (seq_length, n_feature)X = torch.tensor(X).float()X = torch.unsqueeze(X, 0)                # X's shape (1, seq_length, n_feature), 1 is batchsizeoutput = model(X)       # output's shape (1,12)output = torch.squeeze(output)loss = loss_func(output, torch.tensor(trainData_y[iteration]))optimizer.zero_grad()   # clear gradients for this training iterationloss.backward()         # computing gradientsoptimizer.step()        # update weightstotal_loss += lossif (epoch+1) % 20 == 0:print('epoch:{:3d}, loss:{:6.4f}'.format(epoch+1, total_loss.data.numpy()))# torch.save(model, 'flight_model.pkl')  # 这样保存会弹出UserWarning,建议采用下面的保存方法,详情可参考https://zhuanlan.zhihu.com/p/129948825torch.save({'state_dict': model.state_dict()}, 'checkpoint.pth.tar')else:# model = torch.load('flight_model.pth')model = Net()checkpoint = torch.load('checkpoint.pth.tar')model.load_state_dict(checkpoint['state_dict'])# predict
model.eval()
predict = []
for X in trainData_x:             # X's shape (seq_length, n_feature)X = torch.tensor(X).float()X = torch.unsqueeze(X, 0)     # X's shape (1, seq_length, n_feature), 1 is batchsizeoutput = model(X)             # output's shape (1,12)output = torch.squeeze(output)predict.append(output.data.numpy())# plot
plt.figure()
predict = np.array(predict)
predict = predict.reshape(-1, 1).squeeze()
x_tick = np.arange(len(predict)) + (seq_length*n_feature)
plt.plot(list(x_tick), predict, label='predict data')data_original = data.reshape(-1, 1).squeeze()
plt.plot(range(len(data_original)), data_original, label='original data')plt.legend(loc='best')
plt.show()

运行结果

在这里插入图片描述

在这里插入图片描述

7 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

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

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

相关文章

Android RecyclerView 动画处理 流程 原理(源码分析第二篇)

零、本文主题 本文要解决的问题: 1. Recyclerview 动画的实现原理是什么? 2. 处理的主要流程大概是怎样的? 一、核心原理 我们抛开代码,想一下,RecyclerView中的view动画有几种? 添加一个view:…

react Hooks之useLayoutEffect和useInsertionEffect

在介绍这两个hooks之前。让我们先对比一下useEffect、useLayoutEffect、useInsertionEffect 执行时机: useEffect 在组件渲染完成后执行,属于异步执行。useInsertionEffect 在组件渲染并插入 DOM 后执行,也属于异步执行。useLayoutEffect 在组…

互联网公司,哪个部门才是鄙视链最顶端?

文章目录 每日一句正能量前言财务部法务部公关部销售部前台行政IT部创意部后记 每日一句正能量 我们必须在失败中寻找胜利,在绝望中寻求希望。 前言 在互联网公司中,不同职位的鄙视链是存在的。有些职位享有高尚的地位,而有些则被看作是次要…

python 爬虫 m3u8 视频文件 加密解密 整合mp4

文章目录 一、完整代码二、视频分析1. 认识m3u8文件2. 获取密钥,构建解密器3. 下载ts文件4. 合并ts文件为mp4 三、总结 一、完整代码 完整代码如下: import requests import re import os from tqdm import tqdm from Crypto.Cipher import AES# 创建临…

Shopify二次开发之五:元字段(Metafields)

目录 解释 操作 1、添加Custom data 2、选择特定类型的数据 3、为Page配置元子段和值 4、模板访问 解释 Shopify Metafields 是一种用于存储和管理自定义数据的功能。它们允许商户在商城中的产品、订单、客户、Page等对象上添加自定义字段,以满足特定业务需求…

c语言->自定义类型联合体和枚举类型

系列文章目录 文章目录 前言 ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:橘橙黄又青_C语言,函数,指针-CSDN博客 目的:学习联合体和枚举类型的…

[cleanrl] ppo_continuous_action源码解析

1 import库(略) import os import random import time from dataclasses import dataclassimport gymnasium as gym import numpy as np import torch import torch.nn as nn import torch.optim as optim import tyro from torch.distributions.normal…

Kubernetes实战(八)-防止k8s namespace被误删除

1 背景 运维新同学在预发环境操作删除pod的时候,不知道什么原因把kubectl delete pod命令敲成了kubectl delete ns pre把预发环境删了,几十个模块,将近一个小时才恢复。幸亏是测试环境啊,如果是生产可以可以跑路了。 2 解决方案…

jsonpath:使用Python处理JSON数据

使用Python处理JSON数据 25.1 JSON简介 25.1.1 什么是JSON JSON全称为JavaScript Object Notation,一般翻译为JS标记,是一种轻量级的数据交换格式。是基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清…

java对二维数组进行排序

一、按行排序&#xff1a; 对二维数组按进行排序&#xff0c;直接调用Arrays.sort就行&#xff1a; private static int [][] sortRows(int[][] arr) {//行排序for (int i 0; i < arr.length; i) {Arrays.sort(arr[i]);}return arr;}二、按列排序&#xff1a; 1.使用比较…

计算机网络:应用层(一)

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

鸿蒙开发之状态管理@Observed和@ObjectLink

一、使用场景 当对象内引用对象&#xff0c;改变内部对象属性的时候其他状态管理如State、Provide、Consume等是无法触发更新的。同样&#xff0c;在数组内如果有对象&#xff0c;改变对象的属性也是无法更新的。在这种情况下就可以采用Observed和ObjectLink装饰器了。 二、使…

C# WPF上位机开发(简易图像处理软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 图像处理是工业生产重要的环节。不管是定位、测量、检测还是识别&#xff0c;图像处理在工业生产中扮演重要的角色。而c#由于自身快速开发的特点&a…

玩转 Go 语言并发编程:Goroutine 实战指南

一、goroutine 池 本质上是生产者消费者模型在工作中我们通常会使用可以指定启动的 goroutine 数量-worker pool 模式&#xff0c;控制 goroutine 的数量&#xff0c;防止 goroutine 泄漏和暴涨一个简易的 work pool 示例代码如下&#xff1a; package mainimport ("fmt…

小程序跳转tabbar,tabbar页面不刷新

文章地址&#xff1a;12.小程序 之切换到tabBar页面不刷新问题_360问答 解决办法备份&#xff1a; wx.switchTab&#xff1a;跳转到 tabBar 页面&#xff0c;并关闭其他所有非 tabBar 页面 wx.reLaunch&#xff1a;关闭所有页面&#xff0c;打开到应用内的某个页面。 wx.reLa…

解决微信小程序中 ‘nbsp;‘ 空格不生效的问题

在微信小程序开发中&#xff0c;我们经常会使用 来表示一个空格。这是因为在 HTML 中&#xff0c;空格会被解析为一个普通字符&#xff0c;而不会产生实际的空白间距。而 是一种特殊的字符实体&#xff0c;它被解析为一个不可见的空格&#xff0c;可以在页面上产生真正的空…

力扣70. 爬楼梯

动态规划 思路&#xff1a; 使用递归比较容易理解&#xff0c; f(n) f(n - 1) f(n - 2)&#xff1b; 到剩余1级台阶有 f(n - 1)&#xff0c;到剩余2级台阶有 f(n-2)&#xff1b;边界情况是 n 0, f(0) 1n 1, f(1) 1n 2, f(2) 2 递归代码实现&#xff1a; class Soluti…

Axure RP 9 入门教程

1. Axure简介 Axure 是一个交互式原型设计工具&#xff0c;可以帮助用户创建复杂的交互式应用程序和网站。Axure 能够让用户快速构建出具有高度可交互性的原型&#xff0c;可以在团队中进行协作、分享和测试。 使用 Axure 可以设计出各种不同类型的原型&#xff0c;包括网站、移…

系列十五、搭建redis集群

一、概述 上篇文章介绍了redis集群的相关知识&#xff0c;本章实战演示redis的集群环境的详细搭建步骤。如果帮助到了你&#xff0c;请点赞 收藏 关注&#xff01;有疑问的话也可以评论区交流。 二、搭建步骤 2.1、预备知识 判断一个集群中的节点是否可用&#xff0c;是集群…

【SpringBoot篇】详解基于Redis实现短信登录的操作

文章目录 &#x1f970;前言&#x1f6f8;StringRedisTemplate&#x1f339;使用StringRedisTemplate⭐常用的方法 &#x1f6f8;为什么我们要使用Redis代替Session进行登录操作&#x1f386;具体使用✨编写拦截器✨配置拦截器&#x1f33a;基于Redis实现发送手机验证码操作&am…