深度学习LSTM之预测股票价格

在本文中,我们将分析两个使用深度学习模型的代码示例。第一个代码用于训练LSTM模型来预测股票价格,第二个代码使用训练好的模型进行预测并可视化结果。我们将详细介绍每段代码的功能,所用到的深度学习模型及其原理,并扩展介绍激活函数的使用。


代码一:训练LSTM模型

代码逐段分析
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from sklearn.preprocessing import MinMaxScaler

首先,导入了必要的库:numpy用于数值计算,matplotlib用于绘图,pandas用于数据处理,tensorflow.keras用于构建和训练神经网络模型,sklearn.preprocessing用于数据归一化。

数据预处理
# Part 1 - Data Preprocessing
# Importing the libraries
dataset_train = pd.read_csv('data/NSE-TATAGLOBAL.csv')
dataset_train = dataset_train[::-1]  # 反序
training_set = dataset_train.iloc[:, [1]].values

读取训练数据,并将数据反转,使得数据按时间顺序排列。training_set提取了开盘价数据。

# Feature Scaling
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(training_set)

使用MinMaxScaler对数据进行归一化,将数据缩放到[0, 1]范围内。

# Creating a data structure with 60 timesteps and 1 output
X_train = []
y_train = []
for i in range(60, 2035):
    X_train.append(training_set_scaled[i - 60:i, 0])
    y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)

将数据转换为时间序列结构,即使用前60个时间步的数据预测下一个时间步的输出。X_trainy_train分别存储输入和输出的训练数据。

# Reshaping
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))

将训练数据重塑为LSTM层所需的三维输入格式。

构建和训练LSTM模型
# Part 2 - Building the RNN
# Initialising the RNN
model = tf.keras.Sequential()

初始化一个顺序模型。

# Adding the first LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1)))
model.add(layers.Dropout(0.2))
# Adding a second LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50, return_sequences=True))
model.add(layers.Dropout(0.2))
# Adding a third LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50, return_sequences=True))
model.add(layers.Dropout(0.2))
# Adding a fourth LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50))
model.add(layers.Dropout(0.2))

添加四层LSTM层,每层包含50个单元,前三层设置return_sequences=True以返回每个时间步的输出。每层LSTM后添加Dropout层以防止过拟合。

# Adding the output layer
model.add(layers.Dense(units=1))

添加一个全连接层作为输出层,输出单个预测值。

# Compiling the RNN
model.compile(optimizer='adam', loss='mean_squared_error')

使用Adam优化器和均方误差(MSE)损失函数编译模型。

# Fitting the RNN to the Training set
model.fit(X_train, y_train, epochs=100, batch_size=32)
model.save("data/stockLSTM.h5")

训练模型100个周期,每批次处理32个样本。训练完成后,将模型保存到文件中。


代码二:使用训练好的LSTM模型进行预测

代码逐段分析
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from sklearn.preprocessing import MinMaxScaler

model = tf.keras.models.load_model("data/stockLSTM.h5")

导入必要的库,并加载之前训练好的LSTM模型。

数据预处理
dataset_train = pd.read_csv('data/NSE-TATAGLOBAL.csv')
dataset_train = dataset_train[::-1]  # 反序
training_set = dataset_train.iloc[:, [1]].values
# Feature Scaling
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(training_set)

读取训练数据并进行归一化处理,与代码一中的处理方式相同。

# Making the predictions and visualising the results
# Getting the real stock price of 2017
dataset_test = pd.read_csv('data/stocktest.csv')
dataset_test = dataset_test[::-1]  # 反序
real_stock_price = dataset_test.iloc[:, [1]].values

读取测试数据并反转,获取2017年的真实股票价格。

# Getting the predicted stock price of 2017
dataset_total = pd.concat((dataset_train['Open'], dataset_test['Open']), axis=0)
inputs = dataset_total[len(dataset_total) - len(dataset_test) - 60:].values
inputs = inputs.reshape(-1, 1)
inputs = sc.transform(inputs)

将训练数据和测试数据合并,获取用于预测的输入数据,并进行归一化处理。

X_test = []
for i in range(60, 76):
    X_test.append(inputs[i - 60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))

将测试数据转换为时间序列结构,以便输入到LSTM模型中。

模型预测和结果可视化
predicted_stock_price = model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)

使用训练好的LSTM模型对测试数据进行预测,并将预测值反归一化。

# Visualising the results
plt.plot(real_stock_price, color='red', label='Real TATA Stock Price')
plt.plot(predicted_stock_price, color='blue', label='Predicted TAT Stock Price')
plt.title('TATA Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('TATA Stock Price')
plt.legend()
plt.show()

print(abs(real_stock_price - predicted_stock_price).sum()/len(real_stock_price))

绘制真实值与预测值的对比图,以红色表示真实股票价格,蓝色表示预测股票价格。计算并输出预测误差的平均绝对值。

深度学习模型:LSTM

第一个代码使用的是长短期记忆(LSTM)网络,这是循环神经网络(RNN)的一种变体。LSTM通过引入三个门控机制(输入门、遗忘门和输出门),解决了标准RNN中的长期依赖问题。

LSTM的工作原理
  • 输入门:控制输入到当前时刻的信息有多少会被存储到细胞状态。
  • 遗忘门:控制细胞状态中有多少信息会被保留。
  • 输出门:控制有多少细胞状态的信息会被输出到下一层。

激活函数

在深度学习模型中,激活函数是非常重要的一部分。它们引入了非线性,使得神经网络能够学习和表示复杂的模式。

常见的激活函数
  1. Sigmoid
    [
    \sigma(x) = \frac{1}{1 + e^{-x}}
    ]
    输出值在0和1之间。常用于输出层进行二分类问题。

  2. Tanh
    [
    \tanh(x) = \frac{e^x - e{-x}}{ex + e^{-x}}
    ]
    输出值在-1和1之间,常用于隐藏层,效果通常优于Sigmoid。

  3. ReLU(Rectified Linear Unit):
    [
    \text{ReLU}(x) = \max(0, x)
    ]
    是目前最流行的激活函数,因其计算简单且能有效缓解梯度消失问题。

  4. Leaky ReLU
    [
    \text{Leaky ReLU}(x) = \begin{cases}
    x & \text{if } x \ge 0 \
    \alpha x & \text{if } x < 0
    \end{cases}
    ]
    是ReLU的变体,允许小部分负值通过,有效解决ReLU的“死亡”问题。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from sklearn.preprocessing import MinMaxScaler

# Part 1 - Data Preprocessing
# Importing the libraries
dataset_train = pd.read_csv('data/NSE-TATAGLOBAL.csv')
dataset_train = dataset_train[::-1]  #反序
training_set = dataset_train.iloc[:, [1]].values
# print(dataset_train.head())
# Feature Scaling
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(training_set)
# Creating a data structure with 60 timesteps and 1 output
X_train = []
y_train = []
for i in range(60, 2035):
    X_train.append(training_set_scaled[i - 60:i, 0])
    y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
# Reshaping
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))

# Part 2 - Building the RNN
# Initialising the RNN
model = tf.keras.Sequential()
# Adding the first LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1)))
model.add(layers.Dropout(0.2))
# Adding a second LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50, return_sequences=True))
model.add(layers.Dropout(0.2))
# Adding a third LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50, return_sequences=True))
model.add(layers.Dropout(0.2))
# Adding a fourth LSTM layer and some Dropout regularisation
model.add(layers.LSTM(units=50))
model.add(layers.Dropout(0.2))
# Adding the output layer
model.add(layers.Dense(units=1))
# Compiling the RNN
model.compile(optimizer='adam', loss='mean_squared_error')
# Fitting the RNN to the Training set
model.fit(X_train, y_train, epochs=100, batch_size=32)

model.save("data/stockLSTM.h5")
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from sklearn.preprocessing import MinMaxScaler

model = tf.keras.models.load_model("data/stockLSTM.h5")

dataset_train = pd.read_csv('data/NSE-TATAGLOBAL.csv')
dataset_train = dataset_train[::-1]  #反序
training_set = dataset_train.iloc[:, [1]].values
# Feature Scaling
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(training_set)
# Making the predictions and visualising the results
# Getting the real stock price of 2017
dataset_test = pd.read_csv('data/stocktest.csv')
dataset_test = dataset_test[::-1]  #反序
real_stock_price = dataset_test.iloc[:, [1]].values
# Getting the predicted stock price of 2017
dataset_total = pd.concat((dataset_train['Open'], dataset_test['Open']), axis=0)
inputs = dataset_total[len(dataset_total) - len(dataset_test) - 60:].values
inputs = inputs.reshape(-1, 1)
inputs = sc.transform(inputs)
X_test = []
for i in range(60, 76):
    X_test.append(inputs[i - 60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
predicted_stock_price = model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)

# Visualising the results
plt.plot(real_stock_price, color='red', label='Real TATA Stock Price')
plt.plot(predicted_stock_price, color='blue', label='Predicted TAT Stock Price')
plt.title('TATA Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('TATA Stock Price')
plt.legend()
plt.show()

print(abs(real_stock_price - predicted_stock_price).sum()/len(real_stock_price))

在这里插入图片描述

结论

以上两个代码示例,我们了解了如何使用LSTM模型进行时间序列数据的预测,并深入探讨了LSTM模型的工作原理和激活函数的作用。希望这篇博客能帮助你更好地理解和应用深度学习模型。

  • 35
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Network_Engineer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值