Python实战:长短期记忆网络(LSTM)

假设有某只股票一段时间内的每日收盘价如下表所示:

日期 收盘价(单位:元)
2024-01-01 100.0
2024-01-02 102.0
2024-01-03 105.0
2024-01-04 103.0
2024-01-05 108.0
2024-01-06 110.0
2024-01-07 109.0
2024-01-08 112.0
2024-01-09 115.0
2024-01-10 113.0

import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
from sklearn.preprocessing import MinMaxScaler
import pandas as pd

# 假设这里的data是上面示例中的股票收盘价数据,将其转换为numpy数组并调整形状为二维(符合模型输入要求)
data = np.array([100.0, 102.0, 105.0, 103.0, 108.0, 110.0, 109.0, 112.0, 115.0, 113.0]).reshape(-1, 1)

# 数据归一化,使用MinMaxScaler将数据归一化到0-1区间,这有助于模型训练
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(data)

# 划分训练集和测试集,这里简单按照前80%作为训练集,后20%作为测试集
train_size = int(len(scaled_data) * 0.8)
train_data = scaled_data[:train_size]
test_data = scaled_data[train_size:]

# 准备训练数据的序列,例如以过去10天的数据预测第11天的数据,这里窗口大小设为10(可调整)
def create_sequences(data, window_size):
    sequences = []
    targets = []
    for i in range(len(data) - window_size):
        seq = data[i:i + window_size]
        target = data[i + window_size]
        sequences.append(seq)
        targets.append(target)
    return np.array(sequences), np.array(targets)

window_size = 10
X_train, y_train = create_sequences(train_data, window_size)
X_test, y_test = create_sequences(test_data, window_size)

# 调整输入数据的形状,以适配LSTM层的输入要求(batch_size, timesteps, features)
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))

# 构建LSTM模型
model = Sequential()
# 添加LSTM层,这里设置50个单元,return_sequences=True表示返回每个时间步的输出(如果后续还有LSTM层需要这样设置)
model.add(LSTM(50, return_sequences=True, input_shape=(window_size, 1)))
model.add(LSTM(50))  # 第二层LSTM层,50个单元,默认只返回最后一个时间步的输出
model.add(Dense(1))  # 输出层,预测下一天的价格,输出维度为1

# 编译模型,指定优化器、损失函数和评估指标
model.compile(optimizer='adam', loss='mean_squared_error')

# 训练模型,指定训练轮数、批量大小等参数
epochs = 100
batch_size = 16
model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=(X_test, y_test), verbose=0)

# 使用训练好的模型进行预测
train_predict = model.predict(X_train)
test_predict = model.predict(X_test)

# 对预测结果进行反归一化,还原到原始价格数据的尺度
train_predict = scaler.inverse_transform(train_predict)
test_predict = scaler.inverse_transform(test_predict)
y_train = scaler.inverse_transform(y_train)
y_test = scaler.inverse_transform(y_test)

# 可视化展示,绘制实际价格和预测价格对比图(训练集和测试集)
plt.plot(y_train, label='实际训练价格')
plt.plot(train_predict, label='预测训练价格')
plt.plot(np.arange(len(y_train), len(y_train) + len(y_test)), y_test, label='实际测试价格')
plt.plot(np.arange(len(y_train), len(y_train) + len(y_test)), test_predict, label='预测测试价格')
plt.xlabel('时间')
plt.ylabel('股票收盘价(元)')
plt.title('LSTM模型预测股票价格结果')
plt.legend()
plt.show()

数据准备阶段:

首先将示例的股票收盘价数据转换为 numpy 数组,并调整为二维形状,以符合后续模型输入的基本格式要求。

接着使用 MinMaxScaler 对数据进行归一化处理,将价格数据归一化到 0 - 1 的区间,这样有助于提高模型训练的效率和稳定性,避免因原始数据数值大小差异等因素影响模型收敛。

然后按照一定比例(这里是前 80% 作为训练集,后 20% 作为测试集)划分训练集和测试集,并且定义了一个函数 create_sequences 来根据设定的窗口大小(例如以过去 10 天的数据预测第 11 天的数据)准备训练数据的序列以及对应的目标值,将时间序列数据处理成适合输入 LSTM 模型的格式。最后,还对输入数据的形状进行了调整,使其满足 LSTM 层对于输入维度(batch_size,timesteps,features)的要求,其中 batch_size 是每次训练的样本数量(在训练过程中由模型根据设置的 batch_size 参数自动划分),timesteps 就是时间序列的长度(这里是窗口大小),features 是每个时间步对应的特征数量(股票价格这里只有 1 个特征,即收盘价)。

模型构建阶段:

使用 Sequential 方式来顺序构建长短期记忆网络模型。先是添加了第一层 LSTM 层,设置了 50 个单元,并且通过 return_sequences=True 表示要返回每个时间步的输出(这是因为后续如果还添加 LSTM 层的话,需要传递每个时间步的输出信息),同时通过 input_shape 参数指定了输入数据的形状(窗口大小和特征数量)。接着添加了第二层 LSTM 层,同样有 50 个单元,但这里默认只返回最后一个时间步的输出,用于提取整个序列的特征表示,最后添加了一个全连接层(Dense),输出维度为 1,用于预测下一天的股票价格数值,因为这是一个回归任务,直接输出价格的预测值。

模型编译阶段:

使用 compile 方法来编译模型,指定了优化器为 adam(一种常用的自适应学习率优化器),损失函数选用 mean_squared_error(均方误差,适用于回归任务,衡量预测值与真实值之间的误差大小),用于在训练过程中监控模型的性能,引导模型朝着误差减小的方向进行权重更新。

模型训练阶段:

通过 fit 方法来训练模型,传入训练集的输入数据(X_train)和对应的目标数据(y_train),同时指定了训练的轮数(epochs)为 100,表示整个训练数据集将被迭代训练 100 次,以及每批数据的大小(batch_size)为 16(即将训练数据分成若干个大小为 16 的批次来进行训练)。还传入了验证集数据(X_test 和 y_test),这样在训练过程中可以同时观察模型在验证集上的性能表现,以便及时发现过拟合等问题,这里设置 verbose=0 表示训练过程中不打印详细的训练日志信息,使输出更简洁。

可视化阶段:

利用训练好的模型分别对训练集和测试集数据进行预测,得到预测结果 train_predict 和 test_predict,然后使用之前的 MinMaxScaler 对象的 inverse_transform 方法对预测结果进行反归一化操作,将其还原到原始股票价格数据的尺度,同样也对训练集和测试集的真实目标数据(y_train 和 y_test)进行反归一化处理。

最后使用 matplotlib 库绘制图表,将实际的股票价格(训练集和测试集)与预测的股票价格(训练集和测试集)分别用不同的线条绘制出来,通过对比可以直观地看到模型预测的效果,了解预测价格与实际价格的接近程度,分析模型在股票价格时间序列预测任务中的表现情况。

你可能感兴趣的:(深度学习,深度学习,python,lstm)