目录
1. 简介
LSTM(Long Short-Term Memory)是一种特殊的循环神经网络(RNN),它可以捕捉时间序列中的长期依赖关系,并在时间序列预测任务中取得良好的效果。本文将介绍如何使用 LSTM 模型进行时间序列预测。
我们将使用一个气温数据集作为示例数据集,该数据集包含了日均气温的时间序列数据,数据集共有 365 条数据,每条数据对应一年中的一天。我们的任务是根据前一天的气温数据预测当天的气温数据。
2. 数据准备
在使用 LSTM 模型进行时间序列预测之前,我们需要先准备好数据。首先,我们加载气温数据集,并将数据拆分为训练集和测试集:·
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
# 加载气温数据集
df = pd.read_csv('temperature.csv')
# 将日期转换为时间戳,并将时间戳作为数据集的索引
df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.set_index('timestamp')
# 拆分数据集为训练集和测试集
train_data, test_data = train_test_split(df, test_size=0.2, shuffle=False)
在上述代码中,我们加载气温数据集,并将日期转换为时间戳,并将时间戳作为数据集的索引。接下来,我们将数据集拆分为训练集和测试集,其中训练集占 80%。
接下来,我们需要对数据进行归一化处理,将数据的取值范围缩放到 0 到 1 之间:
from sklearn.preprocessing import MinMaxScaler
# 对数据进行归一化处理
scaler = MinMaxScaler(feature_range=(0, 1))
train_data_normalized = scaler.fit_transform(train_data)
test_data_normalized = scaler.transform(test_data)
在上述代码中,我们使用 MinMaxScaler
对数据进行归一化处理。feature_range=(0, 1)
表示将数据的取值范围缩放到 0 到 1 之间。
接下来,我们需要将数据转换为 LSTM 输入格式。在时间序列预测任务中,我们使用前一天的气温数据作为输入,预测当天的气温数据。因此,在将数据转换为 LSTM 输入格式之前,我们需要先定义一个函数来将数据转换为带有前 N 天数据的时间序列数据格式:
def create_sequences(data, seq_length):
xs = []
ys = []
for i in range(seq_length, len(data)):
xs.append(data[i-seq_length:i])
ys.append(data[i])
return np.array(xs), np.array(ys)
在上述代码中,我们定义了一个 `create_sequences()函数,用于将数据转换为带有前 N 天数据的时间序列数据格式。该函数接受两个参数,分别是数据和序列长度
seq_length。函数将从第
seq_length天开始遍历数据,将前
seq_length天的数据作为输入序列,将当天的数据作为输出序列。函数最终返回输入序列
xs和输出序列
ys`。
接下来,我们使用上述函数将训练集和测试集转换为 LSTM 输入格式:
# 设置序列长度
SEQ_LENGTH = 30
# 将训练集和测试集转换为 LSTM 输入格式
train_X, train_y = create_sequences(train_data_normalized, SEQ_LENGTH)
test_X, test_y = create_sequences(test_data_normalized, SEQ_LENGTH)
在上述代码中,我们设置了序列长度为 30,即使用前 30 天的气温数据作为输入,预测当天的气温数据。然后,我们使用 create_sequences()
函数将训练集和测试集转换为 LSTM 输入格式。
3. 模型定义和训练
定义模型之前,我们需要先指定一些模型的超参数:
# 指定模型的超参数
NUM_EPOCHS = 100
BATCH_SIZE = 32
NUM_UNITS = 64
DROPOUT_RATE = 0.2
接下来,我们定义一个 LSTM 模型,并编译模型:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dropout, Dense
# 定义 LSTM 模型
model = Sequential()
model.add(LSTM(NUM_UNITS, input_shape=(SEQ_LENGTH, 1)))
model.add(Dropout(DROPOUT_RATE))
model.add(Dense(1))
# 编译模型
model.compile(loss='mse', optimizer='adam')
在上述代码中,我们使用 Sequential
类定义了一个 LSTM 模型,其中包含一个 LSTM 层、一个 Dropout 层和一个 Dense 层。LSTM 层的 NUM_UNITS
参数指定了 LSTM 层的神经元数目,input_shape
参数指定了输入数据的形状。Dropout 层的 DROPOUT_RATE
参数指定了 Dropout 层的丢失率。Dense 层的 1 个神经元用于输出当天的气温数据。
定义模型后,我们可以使用 fit()
函数进行模型训练:
# 训练模型
history = model.fit(
train_X,
train_y,
epochs=NUM_EPOCHS,
batch_size=BATCH_SIZE,
validation_data=(test_X, test_y),
verbose=2,
shuffle=False
)
在训练过程中,我们使用训练集对模型进行训练,并使用测试集进行模型验证。训练过程中,我们使用均方误差(Mean Squared Error,MSE)作为损失函数。
4. 实验结果
训练 100 个 epoch 后,我们得到如下的训练曲线
import matplotlib.pyplot as plt
# 绘制训练曲线
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Validation'], loc='upper right')
plt.show()
训练曲线显示模型在训练集和测试集上的均方误差损失逐渐降低,但是在 50 个 epoch 后,测试集上的损失开始上升,这可能是由于模型在训练集上过拟合导致的。
最后,我们可以使用训练好的 LSTM 模型对未来的气温数据进行预测:
# 对未来 30 天的气温进行预测
future_predictions = []
current_batch = train_X[-1].reshape(1, SEQ_LENGTH, 1)
for i in range(30):
current_pred = model.predict(current_batch)[0]
future_predictions.append(current_pred)
current_batch = np.append(current_batch[:, 1:, :], [[current_pred]], axis=1)
# 反归一化处理
future_predictions = scaler.inverse_transform(future_predictions)
# 打印预测结果
for i, prediction in enumerate(future_predictions):
print(f"Day {i+1}: {prediction[0]:.2f} degrees Celsius")
在上述代码中,我们使用训练好的 LSTM 模型对未来 30 天的气温数据进行预测。我们首先使用训练集中最后一个序列作为当前序列,然后预测下一天的气温数据,将预测结果添加到预测序列中。然后,我们将当前序列中的第一个元素删除,将预测结果添加到序列的末尾,继续进行预测,直到预测出未来 30 天的气温数据。
最后,我们对预测结果进行反归一化处理,将数据还原为原始数据的取值范围。预测结果如下所示:
Day 1: 13.72 degrees Celsius
Day 2: 12.47 degrees Celsius
Day 3: 11.31 degrees Celsius
Day 4: 10.30 degrees Celsius
Day 5: 9.41 degrees Celsius
Day 6: 8.61 degrees Celsius
Day 7: 7.88 degrees Celsius
Day 8: 7.21 degrees Celsius
Day 9: 6.60 degrees Celsius
Day 10: 6.03 degrees Celsius
Day 11: 5.50 degrees Celsius
Day 12: 5.02 degrees Celsius
Day 13: 4.56 degrees Celsius
Day 14: 4.14 degrees Celsius
Day 15: 3.74 degrees Celsius
Day 16: 3.37 degrees Celsius
Day 17: 3.02 degrees Celsius
Day 18: 2.70 degrees Celsius
Day 19: 2.40 degrees Celsius
Day 20: 2.11 degrees Celsius
Day 21: 1.85 degrees Celsius
Day 22: 1.61 degrees Celsius
Day 23: 1.38 degrees Celsius
Day 24: 1.18 degrees Celsius
Day 25: 0.99 degrees Celsius
Day 26: 0.82 degrees Celsius
Day 27: 0.66 degrees Celsius
Day 28: 0.51 degrees Celsius
Day 29: 0.38 degrees Celsius
Day 30: 0.26 degrees Celsius
预测结果显示未来 30 天的气温将持续下降,最后降至 0 度左右。
5. 总结
本文介绍了使用 LSTM 模型进行时间序列预测的方法,以预测未来 30 天的气温为例。我们首先对数据进行预处理,然后将数据转换为 LSTM 输入格式,并定义了 LSTM 模型进行训练和预测。
LSTM 模型是一种常用的时间序列预测模型,可以处理具有长期依赖性的序列数据。在实际应用中,可以根据需要调整模型的参数和结构,以获得更好的预测效果。