Directory
0.概述
循环神经网络:用基础RNN、LSTM、GRU实现股票预测。
1.知识点
1.RNN
type | destination | feature |
---|---|---|
CNN | 分类、目标检测等 | 借助卷积核从空间维度提取信息,卷积核参数空间共享。 |
RNN | 预测 | 借助循环核从时间维度提取信息,循环核参数时间共享。 |
1.1RNN函数理解
tf.keras.layers.SimpleRNN()
输入至RNN时,x_train为3D数组。
简记:维度从前向后依次为,每个圈输入几次数据,有几个圈,每个圈几个数据。
也可理解为此处整个数据集送入,送入样本数为len(x_train);输入1个字母出结果,循环核时间展开步数为1; 表示为独热码有5个输入特征,每个时间步输入特征个数为5
或者:总共要做多少个RNN大循环,每个大循环内分几步,每步输入几个数据。
1.2易错点
- 一个循环核是一个循环计算层。
- 循环核中的记忆体的个数可以理解为cnn输出卷积特征通道数。(易混点注意:记忆体的个数实在SimpleRNN() 函数中设置的。每个循环核要循环多少次是x_train[ ] 这个三维数组的第一个维度定义的。)
- 在前向传播时只有记忆体是随时间变化的(这时 ω x h \omega_{xh} ωxh , ω h h \omega_{hh} ωhh, ω h y \omega_{hy} ωhy 是不变化的),在反向传播时计算出 ω x h \omega_{xh} ωxh , ω h h \omega_{hh} ωhh, ω h y \omega_{hy} ωhy 。
- 一个SimpleRNN() 代表一个循环核,函数中第一个参数才代表循环核中记忆体的个数。
- 最后层的循环核的参数return_sequence = False(循环核仅在最后时刻会把 h t h_t ht 推向下一层),中间层的return_sequence = True(循环核在各个时刻把 h t h_t ht 推向下一层)。
- 当记忆体个数被指定,输入 x t x_t xt 输出 y t y_t yt 被指定,则 ω x h \omega_{xh} ωxh, ω h h \omega_{hh} ωhh, ω h y \omega_{hy} ωhy 的维度也被限定了。
2.LSTM
type | feature |
---|---|
RNN | 后面节点相对于跨度很大的前面时间节点的信息感知能力太弱,可以使用梯度截断去解决梯度爆炸问题,但无法轻易解决梯度消失问题。 |
LSTM | 3 门 2 记忆 1 候选态 |
LSTM中比较重要的是:遗忘门,给遗忘门加入1的bias偏置,能让LSTM变得与已知的最佳变种一样健壮。
这里直接引用由曹健老师口述,B站大神手打的笔记:
2.1函数理解
tf.keras.layers.LSTM()
输入的训练集,以及易错点同上。
3.GRU
type | feature |
---|---|
LSTM | 参数多,训练量大 |
GRU | 将遗忘门和输入门合并成更新门,将记忆单元和隐藏层合并成重置门。 重置门:有助于捕捉时间序列里短期的依赖关系。 更新门:有助于捕捉时间序列里长期的依赖关系。 |
3.1函数理解
tf.keras.layers.GRU()
输入的训练集,以及易错点同上。
2.其他知识点
2.1读取csv文件
pandas模块
import pandas as pd
maotai = pd.read_csv('./SH600519.csv')
# 转换成值
training_set = maotai.iloc[0:2426-300, 2:3].values
validation_set = maotai.iloc[-300:, 2:3].values
2.2归一化
2.2.1数据归一化方法:
- 最值归一化
- 均值方差归一化
2.2.2函数
from sklearn.preprocessing import MinMaxScaler
# 1.定义数据归一化范围
sc = MinMaxScaler(feature_range = ( , ))
# 2.fit 进行找均值,方差,最大值,最小值等操作,transform 进行转换。fit_transform把这两步连起来。
data = sc.fit_transform(data)
.fit_transform() 和 .transform() 的作用
2.3结果预测
model.predict() 输出 | detail |
---|---|
分类 | 一般在预测后常接——tf.argmax( , axis = 1),这时返回的index在对应的数据集上为真实结果 |
预测值 | 预测后返回正确结果,有些可能要进行一次反归一化把数据彻底还原。 |
3.程序框架
三个预测方向:
- onehot
- Embedding
- 数据曲线
3.1 onehot
- 模块加载。
- (1)编辑字符串,(2)创建单词映射到数值 id 的词典,(3)创建 id 编码为one-hot。
- 制作训练集和标签。(本例训练时无验证集)
- random训练集和标签。
- reshape训练集,使之符合RNN数据输入标准。
- 六步法 + 断点续训 + 参数提取 + acc / loss 可视化。
- predict:手动输入验证次数及验证集进行预测。
3.1.1 training essential
训练的本质依旧是训练集的数字和标签集的数字之间的对应关系,程序无法直接将字符和标签数字联系在一起。创建单词映射到数值 id 的词典,创建 id 编码为 one-hot 的行为本质上,就是将字符转化为数字,将数字转换为对应的独热码。predict 时,程序预测的也是数字,数字的格式要与训练集相同。
3.2 Embedding
3.2.1 Introduce
type | Feature |
---|---|
独热码 | 1.数据量大,过于稀疏,映射之间是独立的,没有表现出关联性。 2. 训练集格式:[总共要做多少个RNN大循环,每个大循环内分几步,每步输入几个数据] |
Embedding | 1.float 型向量,容量更大,是一种单词编码方法,用低维向量实现了编码,这种编码通过神经网络训练优化,能表达出单词间的相关性。 2.训练集格式:[送入样本数, 循环核时间展开步数] 3.函数位置:Sequential([ ]) 内第一个函数。 |
3.2.2 Function
3.2.2.1 Function Usage
tf.keras.layers.Embedding(词汇表大小,编码维度)
# 编码维度就是用几个数字表达一个标签
# 例:tf.keras.layers.Embedding(100, 3 )
# 对1-100进行编码, [4] 编码为 [0.25, 0.1, 0.11]
3.2.2.2 Function In Program
from tensorflow.keras.layers import Embedding
# 使x_train符合Embedding输入要求:[送入样本数, 循环核时间展开步数]
x_train = np.reshape(x_train, (len(x_train), 1))
y_train = np.array(y_train)
model = tf.keras.Sequential([
Embedding(5, 2),
SimpleRNN(3),
Dense(5, activation='softmax')
])
3.2.3 Program Architecture
- 模块加载
- (1)编辑字符串,(2)创建单词映射到数值 id 的词典。
- 制作训练集和标签。(本例训练时无验证集)
- random训练集和标签。
- reshape训练集,使之符合RNN数据输入标准。
- 六步法 + 断点续训 + 参数提取 + acc / loss 可视化。
- predict:手动输入验证次数及验证集进行预测。(验证集reshape到符合embedding输入的标准)
3.3 数据曲线
三种方法预测股票只是在调用函数不同,整体框架完全一样
- 模块加载。
- 读取csv文件。
- 数据归一化。
- 制作训练集、测试集。
- random训练集和标签。
- 使所有的训练集和测试集成为标准的 tf.constant()
- reshape() x 的训练集和测试集,使形状符合RNN函数要求。
- 六步法 + 断点续训 + 参数提取 + acc / loss 可视化
- predict
- predict曲线显示
- evaluate
3.3.1 evaluate
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math
# calculate MSE 均方误差 ---> E[(预测值-真实值)^2] (预测值减真实值求平方后求均值)
mse = mean_squared_error(predicted_stock_price, real_stock_price)
# calculate RMSE 均方根误差--->sqrt[MSE] (对均方误差开方)
rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))
# calculate MAE 平均绝对误差----->E[|预测值-真实值|](预测值减真实值求绝对值后求均值)
mae = mean_absolute_error(predicted_stock_price, real_stock_price)
print('均方误差: %.6f' % mse)
print('均方根误差: %.6f' % rmse)
print('平均绝对误差: %.6f' % mae)