tip:本项目用到的数据和代码在https://pan.baidu.com/s/1Cw6OSSWJevSv7T1ouk4B6Q?pwd=z6w2
1. RNN : 预测股价
任务:基于zgpa_train.csv数据,建立RNN模型,预测股价
1.完成数据预处理,将序列数据转化为可用于RNN输入的数据
2.对新数据zgpa_test.csv进行预测,可视化结果
3.存储预测结果,并观察局部预测结果
备注:模型结构:单层RNN,输出有5个神经元,每次使用前8个数据预测第9个数据
1.1 数据准备
下面是一个预测股票的一个项目实战。
任务:基于zgpa_train.csv数据,建立RNN模型,预测股价
1.完成数据预处理,将序列数据转化为可用于RNN输入的数据
2.对新数据zgpa_test.csv进行预测,可视化结果
3.存储预测结果,并观察局部预测结果
备注:模型结构:单层RNN,输出有5个神经元,每次使用前8个数据预测第9个数据。
数据内容大致如下:
开始项目,代码如下:
import pandas as pd
import numpy as np
data = pd.read_csv('zgpa_train.csv')
data.head()
# 加载收盘价
price = data.loc[:, 'close']
price.head()
# 归一化处理
price_norm = price/max(price)
print(price_norm)
# 归一化之前的数据可视化
%matplotlib inline
from matplotlib import pyplot as plt
fig1 = plt.figure(figsize=(8,5))
plt.plot(price)
plt.title('close_price') # 归一化之前的数据
plt.xlabel('time')
plt.ylabel('price')
plt.show()
%matplotlib inline的作用:
%matplotlib inline
是一个 IPython 魔法命令,用于在 Jupyter Notebook 中将 matplotlib 绘图直接嵌入到输出单元中。这样可以使绘图在 Notebook 中显示,而无需调用 plt.show()
方法。此外,它可以确保每次执行绘图代码时,图形都能在相应的输出单元显示,而不是在外部窗口中弹出。
inline
:表示图像“在线”显示,意思是在 Jupyter Notebook 的输出单元中直接显示图像,而不是在单独的窗口中弹出。
# 对 X 与 y 进行赋值
# 定义方法去提取 X 与 y
def extract_data(data, time_step):
X = [] # list
y = [] # list
# 例如,10个样本;time_step=8;
# 第一组样本,0,1,2,...7
# 第二组样本,1,2,3,...8
# 第三组样本,2,3,4,...9
# 共有2组样本可供观测
for i in range(len(data)-time_step):
X.append([a for a in data[i:i+time_step]])
y.append(data[i+time_step])
X = np.array(X)
X = X.reshape(X.shape[0], X.shape[1], 1)
return X, y
上面是设计数组X、y的函数,即X是因,y是果,用X的一个数组得到y的一个对应值;这里把X处理成了最后一个维度只有一个元素的维度,即X.shape =(*,*,...,1)。
# 定义 X 与 y
time_step = 8
X, y = extract_data(price_norm, time_step)
print(X.shape) # 723个样本,每个样本有8个数据,每个样本对应1个单独数值,(723,8,1)
print(X[0, :, :]) # 第一个样本数据
这里使用刚才的函数,提供data和time_step,创建出X,y。
jupyter里可以不需要用那么多print,直接在单元格输入X.shape,X[0]就能得到相应的结果。
---------------------------------------------------------------------------------------------------------------------------
1.2 模型建立
下面是建立模型的主要代码,这段代码使用 Keras 构建了一个简单的 循环神经网络(RNN)模型,它适合用于 回归任务。以下是代码中各个步骤的解释::
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN # 引入层相关,输出层与 RNN 层
model = Sequential() # 创建实例
model.add(SimpleRNN(units=5, input_shape=(time_step, 1), activation='relu')) # RNN 层
model.add(Dense(units=1, activation='linear')) # 输出层,回归任务直接使用 linear 激活函数
model.compile(optimizer='adam', loss='mean_squared_error') # 回归使用mse评测
model.summary()
逐步解析代码:
1. 导入模块
from keras.models import Sequential
from keras.layers import Dense, SimpleRNN
Sequential
:用于构建 Keras 的顺序模型,可以按顺序堆叠各层。Dense
和SimpleRNN
:分别代表全连接层和简单循环神经网络(RNN)层。
2. 创建模型实例
model = Sequential()
使用 Sequential()
创建一个顺序模型实例 model
,可以层层堆叠神经网络层。
3. 添加 SimpleRNN 层
model.add(SimpleRNN(units=5, input_shape=(time_step, 1), activation='relu'))
- SimpleRNN:一种简单的循环神经网络层。
units=5
:表示 RNN 层有 5 个隐藏单元(Hidden Units)。input_shape=(time_step, 1)
:输入的形状。假设时间步为time_step
,每步有一个特征。activation='relu'
:使用 ReLU 激活函数。
1. 这一步就对应理论部分的由x到h,这里 units=5
表示 RNN 层有 5 个隐藏单元h,每个单元可以理解为负责捕捉某一方面的特征,这些单元共同作用,从输入数据中提取序列信息,并将提取到的特征传递到下一层或输出层。在这个RNN 模型中,每个时间步都会产生 5 个隐藏单元的输出。
隐藏单元越多,模型能够捕捉的特征就越多,模型也会更复杂,适合处理高维和复杂数据。
2. input_shape=(time_step, 1)
:说明输入序列的长度和每个时间步的特征数量,用来告诉模型输入数据的形状。这里的特征指的是,描述了每个时间步的输入信息量,比如传感器数据流中每个时间步可能有多个传感器特征(例如温度、湿度、压力等)。这个模型只用到了一个特征,即close收盘价,对应之前数据准备只取了那一列。
3. activation='relu'
:指定了隐藏状态计算中的激活函数,即计算由x到h的激活函数。
4. 添加 Dense 输出层
model.add(Dense(units=1, activation='linear'))
-
是在给模型添加一个 全连接层(Dense 层),该层有如下配置:
-
units=1:表示该层包含一个神经元,输出为一个值。对于回归任务(例如预测一个