用于温度时间序列预测的 LSTM 神经网络
Posted
技术标签:
【中文标题】用于温度时间序列预测的 LSTM 神经网络【英文标题】:LSTM Neural Network for temperature time series predictions 【发布时间】:2020-09-15 00:09:48 【问题描述】:我正在学习使用应用于时间序列的神经网络,因此我调整了 LSTM 示例,我发现该示例可以预测每日温度数据。但是,我发现结果非常差,如图所示。 (我只预测过去 92 天,以便暂时节省时间)。
这是我实现的代码。数据是 3 列数据框(最低、最高和平均每日温度),但我一次只使用其中一列。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tools.eval_measures import rmse
from sklearn.preprocessing import MinMaxScaler
from keras.preprocessing.sequence import TimeseriesGenerator
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
import warnings
warnings.filterwarnings("ignore")
input_file2 = "TemperaturasCampillos.txt"
seriesT = pd.read_csv(input_file2,sep = "\t", decimal = ".", names = ["Minimas","Maximas","Medias"])
seriesT[seriesT==-999]=np.nan
date1 = '2010-01-01'
date2 = '2010-09-01'
date3 = '2020-05-17'
date4 = '2020-12-31'
mydates = pd.date_range(date2, date3).tolist()
seriesT['Fecha'] = mydates
seriesT.set_index('Fecha',inplace=True) # Para que los índices sean fechas y así se ponen en el eje x de forma predeterminada
seriesT.index = seriesT.index.to_pydatetime()
df = seriesT.drop(seriesT.columns[[1, 2]], axis=1) # df.columns is zero-based pd.Index
n_input = 92
train, test = df[:-n_input], df[-n_input:]
scaler = MinMaxScaler()
scaler.fit(train)
train = scaler.transform(train)
test = scaler.transform(test)
#n_input = 365
n_features = 1
generator = TimeseriesGenerator(train, train, length=n_input, batch_size=1)
model = Sequential()
model.add(LSTM(200, activation='relu', input_shape=(n_input, n_features)))
model.add(Dropout(0.15))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
model.fit_generator(generator,epochs=150)
#create an empty list for each of our 12 predictions
#create the batch that our model will predict off of
#save the prediction to our list
#add the prediction to the end of the batch to be used in the next prediction
pred_list = []
batch = train[-n_input:].reshape((1, n_input, n_features))
for i in range(n_input):
pred_list.append(model.predict(batch)[0])
batch = np.append(batch[:,1:,:],[[pred_list[i]]],axis=1)
df_predict = pd.DataFrame(scaler.inverse_transform(pred_list),
index=df[-n_input:].index, columns=['Prediction'])
df_test = pd.concat([df,df_predict], axis=1)
plt.figure(figsize=(20, 5))
plt.plot(df_test.index, df_test['Minimas'])
plt.plot(df_test.index, df_test['Prediction'], color='r')
plt.legend(loc='best', fontsize='xx-large')
plt.xticks(fontsize=18)
plt.yticks(fontsize=16)
plt.show()
如果您单击图片链接,您会看到,我得到的预测过于平滑,很高兴看到季节性,但不是我所期待的。 此外,我尝试向所示的神经网络添加更多层,因此网络看起来像:
#n_input = 365
n_features = 1
generator = TimeseriesGenerator(train, train, length=n_input, batch_size=1)
model = Sequential()
model.add(LSTM(200, activation='relu', input_shape=(n_input, n_features)))
model.add(LSTM(128, activation='relu'))
model.add(LSTM(256, activation='relu'))
model.add(LSTM(128, activation='relu'))
model.add(LSTM(64, activation='relu'))
model.add(LSTM(n_features, activation='relu'))
model.add(Dropout(0.15))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
model.fit_generator(generator,epochs=100)
但我收到此错误:
ValueError:输入 0 与层 lstm_86 不兼容:预期 ndim=3,发现 ndim=2
当然,由于模型性能不佳,我无法保证样本外预测是准确的。 为什么我不能在网络上实现更多层?我怎样才能提高性能?
【问题讨论】:
【参考方案1】:您缺少一个参数:return_sequences。
当你有多个 LSTM 层时,你应该将它设置为 TRUE。因为,否则,该层将只输出最后一个隐藏状态。将其添加到每个 LSTM 层。
model.add(LSTM(128, activation='relu', return_sequences=True))
关于性能不佳:我猜这是因为您的此应用程序的数据量很少(数据似乎很嘈杂),添加层不会有太大帮助。
【讨论】:
其实这个数据序列比较长,2010年以后的数据(每天4000个数据少一点),所以我觉得加层可能会有帮助。 我尝试添加 return_sequences 参数,但它似乎不起作用,我有同样的错误。在这一点上我很迷茫 4000 每天的数据不是很多。除了最后一层之外,您是否在所有 lstm 层中都放置了返回序列?我现在不能,但是如果需要,明天我会尝试重现您的代码 我发现了一个错误,我忘记将返回序列放在第一层...现在它可以工作了,正如您所说的那样,添加更多层并不会以任何实质性方式改善结果.是因为数据不够?还是LSTM不是这个预测问题的最佳解决方案? 我的猜测是,这里的问题不能仅仅用历史数据来解决......看看你的图表,数据看起来很随机......也许你需要其他变量来预测温度。要单独使用 lstm 进行这项工作,您可能需要大量具有大学习窗口的数据,而训练它变得不切实际以上是关于用于温度时间序列预测的 LSTM 神经网络的主要内容,如果未能解决你的问题,请参考以下文章
技术 | 如何在Python下生成用于时间序列预测的LSTM状态