当前位置:   article > 正文

使用 Tensorflow LSTM 进行时间序列预测_lstm模型跟踪

lstm模型跟踪

时间序列数据

时间序列数据,也称为时间戳数据,是按时间顺序索引的数据点序列。

这些数据点通常由同一来源在固定时间间隔内进行的连续测量组成,用于跟踪随时间的变化。

什么是 LSTM?

长短期记忆 (LSTM) 是一种深度学习的顺序神经网络,可以让信息持续存在。它是一种特殊类型的循环神经网络,能够学习序列预测问题中的顺序依赖性。 LSTM 旨在解决传统 RNN 模型面临的梯度消失问题。

下次我们将详细介绍 LSTM 及其架构和工作原理。在这篇文章中,我们将重点讨论使用 LSTM 来解决时间序列预测问题。

为什么使用 LSTM 进行时间序列预测?

LSTM 是一种循环神经网络,其中神经元能够学习序列数据中的模式并预测序列中的下一项。

由于时间序列数据已经是连续测量的序列,按时间顺序索引,即数据是确定的、连续的和周期性的,非常适合 LSTM 网络学习并为时间顺序中的未来连续趋势提供预测。

时间序列预测的类型

  1. 单变量时间序列预测(除时间戳特征外还有 1 个输入特征)
  2. 多元时间序列预测(除时间戳特征外超过 1 个输入特征)

在这篇文章中,我们将讨论单变量时间序列预测的 LSTM 实现。我将在下一篇文章中讨论多元时间序列预测的实现。

问题背景

耶拿气候是德国耶拿马克斯普朗克生物地球化学研究所气象站记录的天气时间序列数据集。该数据集由 14 个不同的量(例如气温、大气压、湿度、风向等)组成,这些量在几年内每 10 分钟记录一次。该数据集涵盖2009年1月1日至2016年12月31日的数据。

我们需要使用此数据中的温度记录来预测未来 10 天的温度。

首先让我们加载必要的库。

  1. import pandas as pd
  2. import numpy as np
  3. import seaborn as sns
  4. import matplotlib.pyplot as plt
  5. import warnings
  6. warnings.simplefilter(action='ignore', category=FutureWarning)
  7. from datetime import date

接下来我们读取数据

clim = pd.read_csv('DataRepository/jena_climate_2009_2016.csv', index_col = 0)

您可以从以下链接找到数据(最后给出的Github链接):

我们正在实施 LSTM 模型来查找给定数据中的温度预测。这就是单变量时间序列预测。

取第 6 条记录,因为我们只需要每小时的数据,因此忽略其他所有记录(在 10 分钟级别)

如果这是业务需求,我们还可以取连续 6 条记录的平均值/中位数,但现在还不是。

  1. df = clim[['Date Time','T (degC)']].rename(columns = {'T (degC)':'T','Date Time':'datetime'})
  2. df['datetime'] = pd.to_datetime(df['datetime'])
  3. df_hour_lvl = df[5::6].reset_index().drop('index', axis=1)

检查数据图和数据分布

df.plot(figsize = (15,5))

  1. plt.figure(figsize = (14,5))
  2. sns.distplot(df_hour_lvl['T'])

该数据是一个非常好的正态分布数据。如果我们的数据不是正态分布的,那么我们必须使用数据变换(通常是 Box-Cox 变换)将其转换为正态数据。

如果您的数据不是正态分布的,您可以在下面的链接中查看该问题的解决方案:

为 LSTM 创建输入数据

时间序列 LSTM(或任何 RNN)模型所需的输入数据不是简单的具有少量行和列的 pandas 或 pyspark 数据框。输入数据需要拆分为X和y,其中X是二维numpy数组(记录数,输入序列数),而y是一维numpy数组(记录数)。

n_input 是用于预测未来时间序列的历史输入的数量。

  1. def Sequential_Input_LSTM(df, input_sequence):
  2. df_np = df.to_numpy()
  3. X = []
  4. y = []
  5. for i in range(len(df_np) - input_sequence):
  6. row = [a for a in df_np[i:i + input_sequence]]
  7. X.append(row)
  8. label = df_np[i + input_sequence]
  9. y.append(label)
  10. return np.array(X), np.array(y)
  11. n_input = 10
  12. df_min_model_data = df_hour_lvl['T']
  13. X, y = Sequential_Input_LSTM(df_min_model_data, n_input)

创建训练-测试分割

您完全可以选择用于训练、验证和测试模型的记录数量。对下面的代码进行相应的更改。

  1. # Training data
  2. X_train, y_train = X[:60000], y[:60000]
  3. # Validation data
  4. X_val, y_val = X[60000:65000], y[60000:65000]
  5. # Test data
  6. X_test, y_test = X[65000:], y[65000:]

创建 LSTM 模型

  1. from tensorflow.keras.models import Sequential, save_model, load_model
  2. from tensorflow.keras.layers import *
  3. from tensorflow.keras.callbacks import EarlyStopping
  4. from tensorflow.keras.losses import MeanSquaredError
  5. from tensorflow.keras.metrics import RootMeanSquaredError
  6. from tensorflow.keras.optimizers import Adam
  1. n_features = 1
  2. model1 = Sequential()
  3. model1.add(InputLayer((n_input,n_features)))
  4. model1.add(LSTM(100, return_sequences = True))
  5. model1.add(LSTM(100, return_sequences = True))
  6. model1.add(LSTM(50))
  7. model1.add(Dense(8, activation = 'relu'))
  8. model1.add(Dense(1, activation = 'linear'))
  9. model1.summary()

总共 151,817 个参数用于训练这个深度神经网络

需要注意的一些要点:

  • n_features是用于预测的输入变量的数量(这里只有1,即温度)
  • LSTM 网络使您能够将序列数据输入到网络中,并根据序列数据的各个时间步进行预测。因此,我们使用 LSTM 的equential() keras 模型。
  • 最后一个密集层中的神经元数量是我们想要的输出形状。对于时间序列,我们需要一维输出。因此,最后一个密集层中的神经元数量应该为 1。
  • 为了更好的预测,我们使用 3 层 LSTM(称为 Stacked/Deep LSTM)而不是仅 1 层 LSTM(称为 Simple LSTM)。
  • 如果使用多个 LSTM 层,请使用“return_sequences = True”,除了最后一个 LSTM 层(否则我们将面临维度不匹配错误)
  • 使用 EarlyStopping() 可以为我们节省大量时间,一旦它意识到在接下来的 epoch 中损失不会再减少,它就会停止模型训练,并且现在可以比所描述的 epoch 更早停止训练。
  • 我使用 RootMeanSquaredError() 作为模型性能评估、Adam 优化器和 relu/线性激活函数的指标。请随意尝试其他指标、优化器和激活函数并比较结果。
  1. early_stop = EarlyStopping(monitor = 'val_loss', patience = 2)
  2. model1.compile(loss = MeanSquaredError(),
  3. optimizer = Adam(learning_rate = 0.0001),
  4. metrics = RootMeanSquaredError())
  5. model1.fit(X_train, y_train,
  6. validation_data = (X_val, y_val),
  7. epochs = 50,
  8. callbacks = [early_stop])

检查模型性能

  1. losses_df1 = pd.DataFrame(model1.history.history)
  2. losses_df1.plot(figsize = (10,6))

我们可以观察到,每次迭代或 epoch 的损失都会减少,有趣的是,我们的模型只经历了 8 个 epoch,即使我们要求模型运行 50 个 epoch。这是由于使用了早期停止回调,模型在第 8 个 epoch 后停止,因为损失已降至最小值。

如果模型不能提供良好的预测,我们需要尝试一些不同的方法,例如数据缩放、数据转换、使用更多 LSTM 或密集层或调整其他超参数。

保存并重复使用模型

  1. # save the model
  2. save_model(model1, "LSTM_Models/lstm_univariate.h5")
  3. # load the model
  4. model1 = load_model('LSTM_Models/lstm_univariate.h5')

根据测试数据预测温度

  1. test_predictions1 = model1.predict(X_test).flatten()
  2. X_test_list = []
  3. for i in range(len(X_test)):
  4. X_test_list.append(X_test[i][0])
  5. test_predictions_df1 = pd.DataFrame({'X_test':list(X_test_list),
  6. 'LSTM Prediction':list(test_predictions1)})

基于完整测试数据的 LSTM 温度预测

test_predictions_df1.plot(figsize = (15,6))

测试数据中最近 1 个月的 LSTM 温度预测(720 小时)

test_predictions_df1[(len(X_test) - 720):].plot(figsize = (15,5))

现在让我们使用 LSTM 模型进行未来预测

  1. def futureForecast(df, col, n_input, n_features, forecast_timeperiod, model):
  2. x_input = np.array(df[len(df)-n_input:][col])
  3. temp_input=list(x_input)
  4. lst_output=[]
  5. i=0
  6. while(i < forecast_timeperiod):
  7. if(len(temp_input) > n_input):
  8. x_input = np.array(temp_input[1:])
  9. x_input = x_input.reshape((1, n_input, n_features))
  10. yhat = model.predict(x_input, verbose=0)
  11. temp_input.append(yhat[0][0])
  12. temp_input = temp_input[1:]
  13. lst_output.append(yhat[0][0])
  14. i=i+1
  15. else:
  16. x_input = x_input.reshape((1, n_input, n_features))
  17. yhat = model.predict(x_input, verbose=0)
  18. #print(yhat[0])
  19. temp_input.append(yhat[0][0])
  20. lst_output.append(yhat[0][0])
  21. i=i+1
  22. return lst_output
  1. n_input = 10
  2. n_features = 1
  3. forecast_timeperiod = 240 # next 10 days
  4. model = model1
  5. forecast_output = futureForecast(df_hour_lvl,
  6. 'T',
  7. n_input,
  8. n_features,
  9. forecast_timeperiod,
  10. model)
  1. last_10_days = df_hour_lvl['T'][len(df_hour_lvl) - 240:].tolist()
  2. next_10_days = pd.DataFrame(forecast_output, columns = ['FutureForecast'])
  1. plt.figure(figsize = (15,5))p
  2. hist_axis = len(last_10_days)
  3. forecast_axis = hist_axis + len(next_10_days)
  4. plt.plot(np.arange(0,hist_axis),last_10_days, color = 'blue')
  5. plt.plot(np.arange(hist_axis,forecast_axis),next_10_days['FutureForecast'].tolist(), color = 'orange')
  6. plt.title('LSTM Forecast for Next 10 Days')
  7. plt.xlabel('Hours')
  8. plt.ylabel('Temperature')
  9. # save the figure
  10. plt.savefig('Pics_Models/lstm_univariate_forecast_pic.png')
  11. plt.savefig('Pics_Models/lstm_univariate_forecast_pdf.pdf')

详细代码的 GitHub 链接:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/579637
推荐阅读
相关标签
  

闽ICP备14008679号