前情回顾
戳上方蓝字【阿力阿哩哩的炼丹日常】关注我~
今天继续给大家介绍第四章的内容
前面我们介绍了:
通俗易懂LSTM|RNN的变种结构 | LSTM长短期记忆网络
通俗易懂GRU|门控循环单元(gated recurrent unit, GRU)
4.7代码实践
4.7.6 LSTM预测stock trend
笔者将在本节给大家介绍如何用LSTM预测stock trend。闲言少叙,我们这就开始实验。
1. 数据集
Quandl是为投资专业人士提供金融,经济和替代数据的首选平台,拥有海量的经济和金融数据。为了使用quandl提供的免费数据集,我们首先得安装它的库。在命令行输入pip install quandl安装即可。
我们使用quandl提供的Google Stock数据集,该数据集中有多个变量。
* 日期(Date)
* 开盘价(Open)
* 最高价(High)
* 最低价(Low)
* 收盘价(Close)
* 总交易额(Volume)
其中,开盘价和收盘价代表股票在某一天交易的起始价和最终价。
最高价、最低价和最后交易价表示当天股票的最高价、最低价和最后交易价格。
交易总量是指当天买卖的股票数量,而营业额(Lacs)是指某一特定公司在某一特定日期的营业额。
损益的计算通常由股票当日的收盘价决定,因此我们将收盘价作为预测目标。
2. 模型结构
预测Stock Trend的模型结构就是LSTM多输入单输出的网络结构。
训练过程:取一定时间点的数据(如50个交易日的数据)作为输入,预测该段时间的下一个交易日的收盘价,不断缩小真实收盘价与预测收盘价的差值loss即可。
3. 实验流程
(1) 加载stock数据
(2) 构造训练数据
(3) LSTM建模
(4) 预测stock
(5) 查看stock trend拟合效果
4. 代码
4.1加载数据
start = date(2000,10,12)
end = date.today()
google_stock = pd.DataFrame(quandl.get("WIKI/GOOGL", start_date=start, end_date=end))
print(google_stock.shape)
google_stock.tail()
google_stock.head()
4.2绘制stock历史收盘价trend图
plt.figure(figsize=(16, 8))
plt.plot(google_stock['Close'])
plt.show()
4.3 构造训练集与验证集
# 时间点长度
time_stamp = 50
# 划分训练集与验证集
google_stock = google_stock[['Open', 'High', 'Low', 'Close', 'Volume']] # 'Volume'
train = google_stock[0:2800 + time_stamp]
valid = google_stock[2800 - time_stamp:]
# 归一化
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(train)
x_train, y_train = [], []
# 训练集
print(scaled_data.shape)
print(scaled_data[1, 3])
for i in range(time_stamp, len(train)):
x_train.append(scaled_data[i - time_stamp:i])
y_train.append(scaled_data[i, 3])
x_train, y_train = np.array(x_train), np.array(y_train)
# 验证集
scaled_data = scaler.fit_transform(valid)
x_valid, y_valid = [], []
for i in range(time_stamp, len(valid)):
x_valid.append(scaled_data[i - time_stamp:i])
y_valid.append(scaled_data[i, 3])
x_valid, y_valid = np.array(x_valid), np.array(y_valid)
print(x_train.shape)
print(x_valid.shape)
train.head()
4.4 创建并训练LSTM模型
# 超参数
epochs = 3
batch_size = 16
# LSTM 参数: return_sequences=True LSTM输出为一个序列。默认为False,输出一个值。
# input_dim:输入单个样本特征值的维度
# input_length:输入的时间点长度
model = Sequential()
model.add(LSTM(units=100, return_sequences=True, input_dim=x_train.shape[-1], input_length=x_train.shape[1]))
model.add(LSTM(units=50))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(x_train, y_train, epochs=epochs, batch_size=batch_size, verbose=1)
4.5预测stock价格
closing_price = model.predict(x_valid)
scaler.fit_transform(pd.DataFrame(valid['Close'].values))
# 反归一化
closing_price = scaler.inverse_transform(closing_price)
y_valid = scaler.inverse_transform([y_valid])
# print(y_valid)
# print(closing_price)
rms = np.sqrt(np.mean(np.power((y_valid - closing_price), 2)))
print(rms)
print(closing_price.shape)
print(y_valid.shape)
182.31521880433965
(624, 1)
(1, 624)
4.6 拟合stock trend
plt.figure(figsize=(16, 8))
dict_data = {
'Predictions': closing_price.reshape(1,-1)[0],
'Close': y_valid[0]
}
data_pd = pd.DataFrame(dict_data)
plt.plot(data_pd[['Close', 'Predictions']])
plt.show()
LSTM能够处理文本序列的位置信息,因此它能比CNN更好地处理文本,但是由于它无法和CNN那般并行化计算,导致其训练速度会比CNN慢很多。
所以,为了能够在处理文本过程中获取文本的序列信息,且能在训练过程中并行化计算,谷歌提出了self-attention layer,它几乎取代了RNN与LSTM。
最后,笔者在本小节介绍的LSTM实例只是一个小应用,后面有很多人基于LSTM提出了许多有趣的实验例如翻译机器人,但笔者并不打算给大家多做几个实验了,因为self-attention的出现,几乎取代了RNN与LSTM,所以大家知道怎么用LSTM即可。
我们需要将重心放在最新最强的网络结构上,加之笔者本身就是研究自然语言处理(NLP)方向的,因此笔者会在后续的章节给大家介绍这些新颖的结构。
4.8总结
本章的核心思想其实就是梯度下降。对于不同的任务,我们无非是换了不同的网络结构,用上了不同的loss,采用了不同的超参数设定去训练罢了,整体的思想始终不变。
与此同时,梯度下降的思想也是深度学习的核心思想,只有了解梯度下降的基本原理,才能更好地使用与创造适用于各种任务的网络结构。
关注我的微信公众号~不定期更新相关专业知识~
内容 |阿力阿哩哩
编辑 | 阿璃
点个“在看”,作者高产似那啥~