赞
踩
时间序列数据,也称为时间戳数据,是按时间顺序索引的数据点序列。
这些数据点通常由同一来源在固定时间间隔内进行的连续测量组成,用于跟踪随时间的变化。
长短期记忆 (LSTM) 是一种深度学习的顺序神经网络,可以让信息持续存在。它是一种特殊类型的循环神经网络,能够学习序列预测问题中的顺序依赖性。 LSTM 旨在解决传统 RNN 模型面临的梯度消失问题。
下次我们将详细介绍 LSTM 及其架构和工作原理。在这篇文章中,我们将重点讨论使用 LSTM 来解决时间序列预测问题。
LSTM 是一种循环神经网络,其中神经元能够学习序列数据中的模式并预测序列中的下一项。
由于时间序列数据已经是连续测量的序列,按时间顺序索引,即数据是确定的、连续的和周期性的,非常适合 LSTM 网络学习并为时间顺序中的未来连续趋势提供预测。
在这篇文章中,我们将讨论单变量时间序列预测的 LSTM 实现。我将在下一篇文章中讨论多元时间序列预测的实现。
耶拿气候是德国耶拿马克斯普朗克生物地球化学研究所气象站记录的天气时间序列数据集。该数据集由 14 个不同的量(例如气温、大气压、湿度、风向等)组成,这些量在几年内每 10 分钟记录一次。该数据集涵盖2009年1月1日至2016年12月31日的数据。
我们需要使用此数据中的温度记录来预测未来 10 天的温度。
首先让我们加载必要的库。
- import pandas as pd
- import numpy as np
- import seaborn as sns
- import matplotlib.pyplot as plt
- import warnings
- warnings.simplefilter(action='ignore', category=FutureWarning)
- from datetime import date
接下来我们读取数据
clim = pd.read_csv('DataRepository/jena_climate_2009_2016.csv', index_col = 0)
您可以从以下链接找到数据(最后给出的Github链接):
我们正在实施 LSTM 模型来查找给定数据中的温度预测。这就是单变量时间序列预测。
取第 6 条记录,因为我们只需要每小时的数据,因此忽略其他所有记录(在 10 分钟级别)
如果这是业务需求,我们还可以取连续 6 条记录的平均值/中位数,但现在还不是。
- df = clim[['Date Time','T (degC)']].rename(columns = {'T (degC)':'T','Date Time':'datetime'})
- df['datetime'] = pd.to_datetime(df['datetime'])
-
-
- df_hour_lvl = df[5::6].reset_index().drop('index', axis=1)
df.plot(figsize = (15,5))
- plt.figure(figsize = (14,5))
- sns.distplot(df_hour_lvl['T'])
如果您的数据不是正态分布的,您可以在下面的链接中查看该问题的解决方案:
时间序列 LSTM(或任何 RNN)模型所需的输入数据不是简单的具有少量行和列的 pandas 或 pyspark 数据框。输入数据需要拆分为X和y,其中X是二维numpy数组(记录数,输入序列数),而y是一维numpy数组(记录数)。
n_input 是用于预测未来时间序列的历史输入的数量。
def Sequential_Input_LSTM(df, input_sequence): df_np = df.to_numpy() X = [] y = [] for i in range(len(df_np) - input_sequence): row = [a for a in df_np[i:i + input_sequence]] X.append(row) label = df_np[i + input_sequence] y.append(label) return np.array(X), np.array(y) n_input = 10 df_min_model_data = df_hour_lvl['T'] X, y = Sequential_Input_LSTM(df_min_model_data, n_input)
您完全可以选择用于训练、验证和测试模型的记录数量。对下面的代码进行相应的更改。
- # Training data
- X_train, y_train = X[:60000], y[:60000]
-
- # Validation data
- X_val, y_val = X[60000:65000], y[60000:65000]
-
- # Test data
- X_test, y_test = X[65000:], y[65000:]
- from tensorflow.keras.models import Sequential, save_model, load_model
- from tensorflow.keras.layers import *
- from tensorflow.keras.callbacks import EarlyStopping
- from tensorflow.keras.losses import MeanSquaredError
- from tensorflow.keras.metrics import RootMeanSquaredError
- from tensorflow.keras.optimizers import Adam
- n_features = 1
-
- model1 = Sequential()
-
- model1.add(InputLayer((n_input,n_features)))
- model1.add(LSTM(100, return_sequences = True))
- model1.add(LSTM(100, return_sequences = True))
- model1.add(LSTM(50))
- model1.add(Dense(8, activation = 'relu'))
- model1.add(Dense(1, activation = 'linear'))
-
- model1.summary()
总共 151,817 个参数用于训练这个深度神经网络
需要注意的一些要点:
- early_stop = EarlyStopping(monitor = 'val_loss', patience = 2)
-
- model1.compile(loss = MeanSquaredError(),
- optimizer = Adam(learning_rate = 0.0001),
- metrics = RootMeanSquaredError())
-
- model1.fit(X_train, y_train,
- validation_data = (X_val, y_val),
- epochs = 50,
- callbacks = [early_stop])
- losses_df1 = pd.DataFrame(model1.history.history)
-
- losses_df1.plot(figsize = (10,6))
我们可以观察到,每次迭代或 epoch 的损失都会减少,有趣的是,我们的模型只经历了 8 个 epoch,即使我们要求模型运行 50 个 epoch。这是由于使用了早期停止回调,模型在第 8 个 epoch 后停止,因为损失已降至最小值。
如果模型不能提供良好的预测,我们需要尝试一些不同的方法,例如数据缩放、数据转换、使用更多 LSTM 或密集层或调整其他超参数。
- # save the model
- save_model(model1, "LSTM_Models/lstm_univariate.h5")
-
- # load the model
- model1 = load_model('LSTM_Models/lstm_univariate.h5')
- test_predictions1 = model1.predict(X_test).flatten()
-
-
- X_test_list = []
- for i in range(len(X_test)):
- X_test_list.append(X_test[i][0])
-
-
- test_predictions_df1 = pd.DataFrame({'X_test':list(X_test_list),
- 'LSTM Prediction':list(test_predictions1)})
test_predictions_df1.plot(figsize = (15,6))
test_predictions_df1[(len(X_test) - 720):].plot(figsize = (15,5))
def futureForecast(df, col, n_input, n_features, forecast_timeperiod, model): x_input = np.array(df[len(df)-n_input:][col]) temp_input=list(x_input) lst_output=[] i=0 while(i < forecast_timeperiod): if(len(temp_input) > n_input): x_input = np.array(temp_input[1:]) x_input = x_input.reshape((1, n_input, n_features)) yhat = model.predict(x_input, verbose=0) temp_input.append(yhat[0][0]) temp_input = temp_input[1:] lst_output.append(yhat[0][0]) i=i+1 else: x_input = x_input.reshape((1, n_input, n_features)) yhat = model.predict(x_input, verbose=0) #print(yhat[0]) temp_input.append(yhat[0][0]) lst_output.append(yhat[0][0]) i=i+1 return lst_output
- n_input = 10
- n_features = 1
- forecast_timeperiod = 240 # next 10 days
- model = model1
-
- forecast_output = futureForecast(df_hour_lvl,
- 'T',
- n_input,
- n_features,
- forecast_timeperiod,
- model)
- last_10_days = df_hour_lvl['T'][len(df_hour_lvl) - 240:].tolist()
-
- next_10_days = pd.DataFrame(forecast_output, columns = ['FutureForecast'])
- plt.figure(figsize = (15,5))p
-
- hist_axis = len(last_10_days)
- forecast_axis = hist_axis + len(next_10_days)
-
- plt.plot(np.arange(0,hist_axis),last_10_days, color = 'blue')
- plt.plot(np.arange(hist_axis,forecast_axis),next_10_days['FutureForecast'].tolist(), color = 'orange')
-
- plt.title('LSTM Forecast for Next 10 Days')
- plt.xlabel('Hours')
- plt.ylabel('Temperature')
-
- # save the figure
- plt.savefig('Pics_Models/lstm_univariate_forecast_pic.png')
- plt.savefig('Pics_Models/lstm_univariate_forecast_pdf.pdf')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。