Python中的LSTM生成固定预测

时间:2019-05-07 12:08:57

标签: python keras time-series lstm

enter image description here enter image description here我拥有2017年7月至2018年12月的每日数据,这些数据本质上是不稳定的,我正尝试生成对未来六个月的预测,即从2019年1月到2019年7月。我尝试使用SARIMAX和LSTM,但是我得到的预报很稳定。这是我第一次使用LSTM,所以我尝试将RELU和Sigmoid都用作激活函数,但是预测是平稳的

SARIMA
SARIMAX
LSTM

以下是一个月的数据:

           values
X_Date  
2017-07-01  15006.17
2017-07-02  15125.35
2017-07-03  13553.20
2017-07-04  14090.07
2017-07-05  14341.84
2017-07-06  15037.23
2017-07-07  15588.56
2017-07-08  16592.55
2017-07-09  16851.91
2017-07-10  15630.53
2017-07-11  15501.26
2017-07-12  15852.34
2017-07-13  15020.60
2017-07-14  17115.26
2017-07-15  17668.73
2017-07-16  17604.95
2017-07-17  16686.89
2017-07-18  16523.80
2017-07-19  17642.11
2017-07-20  17803.65
2017-07-21  18756.53
2017-07-22  19220.46
2017-07-23  18876.94
2017-07-24  18103.97
2017-07-25  18034.74
2017-07-26  16650.10
2017-07-27  17247.02
2017-07-28  17620.62
2017-07-29  18210.39
2017-07-30  17015.64
scaler = MinMaxScaler()
train = daily_data.iloc[:365]
test = daily_data.iloc[365:]

scaler.fit(train)


scaled_train = scaler.transform(train)
scaled_test = scaler.transform(test)

from keras.preprocessing.sequence import TimeseriesGenerator

scaled_train
# define generator
n_input = 7
n_features = 1
generator = TimeseriesGenerator(scaled_train, scaled_train,    
length=n_input, batch_size=1)


from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM


# define model
model = Sequential()
model.add(LSTM(200, activation='sigmoid', input_shape=(n_input,     
n_features)))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')

model.summary()

# fit model
model.fit_generator(generator,epochs=25)

model.history.history.keys()

loss_per_epoch = model.history.history['loss']
plt.plot(range(len(loss_per_epoch)),loss_per_epoch)

first_eval_batch = scaled_train[-7:]
first_eval_batch = first_eval_batch.reshape((1,n_input,n_features))

model.predict(first_eval_batch)

test_predictions = []

first_eval_batch = scaled_train[-n_input:]
current_batch = first_eval_batch.reshape((1, n_input, n_features))


np.append(current_batch[:,1:,:],[[[99]]],axis=1)



test_predictions = []

first_eval_batch = scaled_train[-n_input:]
current_batch = first_eval_batch.reshape((1, n_input, n_features))

for i in range(len(test)):

 # get prediction 1 time stamp ahead ([0] is for grabbing just the  
 number instead of [array])
 current_pred = model.predict(current_batch)[0]

 # store prediction
 test_predictions.append(current_pred) 

 # update batch to now include prediction and drop first value
 current_batch = np.append(current_batch[:,1:,:],                        

 [[current_pred]],axis=1)

预测是一条平线。

3 个答案:

答案 0 :(得分:0)

我有类似的问题。尝试在第一层中将“ relu”设置为激活功能。 Here是指向优秀博客的链接。它包含许多非常有用的细节,尤其是如果您从机器学习开始。

以下是在我的旧模型中,时期数对结果的影响。 5000 epochs 25 epochs 我也有点担心您拥有的训练数据量。我对18,000条记录进行了模型训练,以预测接下来的24小时,但是我的模型分析了非常复杂的系统。我不知道是什么描述了您的数据,但是您必须考虑系统中可能存在的依赖关系的数量,以及训练数据可以为它们准备好模型的能力。 我是机器学习的新手,但了解到的是,模型准备的最大部分是反复试验方法。尤其是刚开始的时候。 我回答开始的博客形式对我有很大帮助,我建议您阅读它。

我记得在我的情况下,我几乎在所有地方都使用了错误的激活功能。

Here是有关过度拟合和过度拟合的帖子。

答案 1 :(得分:0)

一些问题:

  1. 用18个月的每日数据对于神经网络来建立对未来的准确预测可能并不重要。
  2. 您的模型只有1个LSTM层,请添加第二个LSTM层以受益于其“内存”:
from keras.layers import Dropout

# define model
model = Sequential()
model.add(LSTM(50, activation='relu', input_shape=(n_input,n_features), return_sequences=True))
model.add(Dropout(.4))
model.add(LSTM(100, activation='relu', return_sequences=False))
model.add(Dropout(.4))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')

如果您提供数据,我可以仔细看看。您是否尝试过使用n_input变量?这可能会影响您的模型。

答案 2 :(得分:0)

这是一个较旧的线程,但我有一个类似的问题,实际上它只是不合适。显然有很多原因,但是OP的脚本中有25个时期,这通常是不够的。我运行了30个纪元并在未缩放数据时获得了直线预测(我的计算机不是最好的,所以我认为我可以减少更少的纪元):

Underfit Prediction

在新纪元之后,我得到了更好的测试和训练结果。还有许多其他原因可以使预测像直线一样出现,但是希望提高纪元可以帮助您。