提问者:小点点

如何使用Keras RNN模型预测未来日期或事件?


以下是我训练完整模型并保存它之前的代码:

num_units = 2
activation_function = 'sigmoid'
optimizer = 'adam'
loss_function = 'mean_squared_error'
batch_size = 10
num_epochs = 100

# Initialize the RNN
regressor = Sequential()

# Adding the input layer and the LSTM layer
regressor.add(LSTM(units = num_units, activation = activation_function, input_shape=(None, 1)))

# Adding the output layer
regressor.add(Dense(units = 1))

# Compiling the RNN
regressor.compile(optimizer = optimizer, loss = loss_function)

# Using the training set to train the model
regressor.fit(x_train, y_train, batch_size = batch_size, epochs = num_epochs)
regressor.save('model.h5')

在那之后,我看到大多数时候,人们建议我们使用测试数据集来检查预测,我也尝试过,并得到了很好的结果。

但问题在于我创建的模型的使用。我想预测未来30天或每分钟。现在我有了训练过的模型,但我不知道我能做什么,也不知道我用什么代码来使用模型和预测未来30天或一分钟的价格。

请告诉我出去的路。我一个星期以来一直在解决这个问题,没能做出任何成功的尝试。

这里是存储库的链接,您可以在其中找到完整的可运行代码、模型和数据集:MyRepository链接


共3个答案

匿名用户

好的,您需要一个stateful=True模型,这样您就可以一个接一个地向它提供预测,以获得下一个,并使模型认为每个输入不是一个新序列,而是前一个序列的续集。

修正代码和培训

我在代码中看到,有人试图使您的y成为shiftex(预测下一步的一个很好的选项)。但是这里的预处理也有一个很大的问题:

training_set = df_train.values
training_set = min_max_scaler.fit_transform(training_set)

x_train = training_set[0:len(training_set)-1]
y_train = training_set[1:len(training_set)]
x_train = np.reshape(x_train, (len(x_train), 1, 1))

LSTM层的数据必须成形为(序列的数量、步骤的数量、特征)

因此,很明显,您只创建了一个步骤的序列,这意味着您的LSTM根本没有学习序列。(没有只包含一个步骤的序列)。

假设您的数据是一个具有1个特征的单一唯一序列,它肯定应该被塑造成(1,len(x_train),1)

自然,y_train也应该具有相同的形状。

反过来,这将要求您的LSTM层是return_sequences=True-使y具有步骤长度的唯一方法。此外,为了有一个好的预测,你可能需要一个更复杂的模型(因为现在它将是真正的学习)。

完成后,您将训练您的模型,直到获得满意的结果。

预测未来

为了预测未来,您需要stateful=TrueLSTM层。

在任何事情之前,您重置模型的状态:model.reset_states()-每次将新序列输入到有状态模型时都是必要的。

然后,首先预测整个X_序列(这是模型理解序列的哪一点所必需的,用技术术语来说:创建状态)。

predictions = model.predict(`X_train`) #this creates states

最后创建一个循环,从上一个预测的最后一步开始:

future = []
currentStep = predictions[:,-1:,:] #last step from the previous prediction

for i in range(future_pred_count):
    currentStep = model.predict(currentStep) #get the next step
    future.append(currentStep) #store the future steps    

#after processing a sequence, reset the states for safety
model.reset_states()

实例

这段代码使用2个特征序列、一个移位的未来步骤预测和一个与这个答案有点不同的方法来实现这一点,但基于相同的原则。

我创建了两个模型(一个是stateful=False,用于训练而无需每次重置状态-在开始新序列时不要忘记重置状态-另一个是stateful=True,复制训练模型的权重,用于预测未来)

https://github.com/danmoller/TestRepo/blob/master/TestBookLSTM.ipynb

匿名用户

为了用RNN预测未来的值,您需要做的是以序列的形式提供数据。像这样的东西:

[0 1 2] --> [3]
[1 2 3] --> [4]
[2 3 4] --> [5]
[3 4 5] --> [6]
[4 5 6] --> [7]

RNN学习序列的结构,因此需要唯一的输入形状:

(n_samples, time_steps, n_features)

例如,如果你使用上周的每一天,时间步长可能是7。

  1. tf。克拉斯。预处理。timeseries\u数据集\u来自\u数组

您需要做的是为这个函数提供a)现值和b)未来值。这里,seq_length是使用的时间步数。

import tensorflow as tf

seq_length = 3

x = tf.range(25)[:-seq_length]

y = tf.range(25)[seq_length:]

ds = tf.keras.preprocessing.timeseries_dataset_from_array(x, y,
                                                          sequence_length=seq_length,
                                                          batch_size=1)

for present_values, next_value in ds.take(5):
    print(tf.squeeze(present_values).numpy(), '-->', next_value.numpy())
[0 1 2] --> [3]
[1 2 3] --> [4]
[2 3 4] --> [5]
[3 4 5] --> [6]
[4 5 6] --> [7]

您也可以对多个变量执行相同的操作:

import tensorflow as tf

seq_length = 3

x = tf.concat([
    tf.reshape(tf.range(25, dtype=tf.float32)[:-seq_length], (-1, 1)),
    tf.reshape(tf.linspace(0., .24, 25)      [:-seq_length], (-1, 1))], axis=-1)

y = tf.concat([
    tf.reshape(tf.range(25, dtype=tf.float32)[seq_length:], (-1, 1)),
    tf.reshape(tf.linspace(0., .24, 25)      [seq_length:], (-1, 1))], axis=-1)

ds = tf.keras.preprocessing.timeseries_dataset_from_array(x, y,
                                                          sequence_length=seq_length,
                                                          batch_size=1)

for present_values, next_value in ds.take(5):
    print(tf.squeeze(present_values).numpy(), '-->', tf.squeeze(next_value).numpy())
    
model = tf.keras.Sequential([
    tf.keras.layers.LSTM(8),
    tf.keras.layers.Dense(8, activation='relu'),
    tf.keras.layers.Dense(2)
])

model.compile(loss='mae', optimizer='adam')

history = model.fit(ds)
[[0.   0.  ]
 [1.   0.01]
 [2.   0.02]] --> [3.   0.03]
[[1.   0.01]
 [2.   0.02]
 [3.   0.03]] --> [4.   0.04]
[[2.   0.02]
 [3.   0.03]
 [4.   0.04]] --> [5.   0.05]
[[3.   0.03]
 [4.   0.04]
 [5.   0.05]] --> [6.   0.06]
[[4.   0.04]
 [5.   0.05]
 [6.   0.06]] --> [7.   0.07]
import tensorflow as tf
import numpy as np

x = np.arange(25)

def univariate_data(dataset, start_index, end_index, history_size, target_size):
    data, labels = [], []

    start_index = start_index + history_size
    if end_index is None:
        end_index = len(dataset) - target_size

    for i in range(start_index, end_index):
        indices = np.arange(i-history_size, i)
        data.append(np.reshape(dataset[indices], (history_size, 1)))
        labels.append(dataset[i:i+target_size])
    return np.array(data), np.array(labels)

present_values, future_values = univariate_data(x, 0, 9, 3, 3)

for present, next_val in zip(present_values, future_values):
    print(tf.squeeze(present).numpy(), '-->', tf.squeeze(next_val).numpy())
[0 1 2] --> [3 4]
[1 2 3] --> [4 5]
[2 3 4] --> [5 6]
[3 4 5] --> [6 7]
[4 5 6] --> [7 8]
[5 6 7] --> [8 9]

现在对于多个变量:

import tensorflow as tf
import numpy as np

history_size = 3

x = np.concatenate([np.expand_dims(np.arange(25), 1)[:-history_size],
                    np.expand_dims(np.linspace(0., .24, 25), 1)[:-history_size]], axis=1)

y = np.concatenate([np.expand_dims(np.arange(25), 1)[history_size:],
                    np.expand_dims(np.linspace(0., .24, 25), 1)[history_size:]], axis=1)


def multivariate_data(dataset, target, start_index, end_index, history_size,
                      target_size, step, single_step=False):
  data = []
  labels = []
  start_index = start_index + history_size
  if end_index is None:
    end_index = len(dataset) - target_size
  for i in range(start_index, end_index):
    indices = range(i-history_size, i, step)
    data.append(dataset[indices])
    if single_step:
      labels.append(target[i+target_size])
    else:
      labels.append(target[i:i+target_size])

  return np.array(data), np.array(labels)

present_values, future_values = multivariate_data(x, y, 0, 8, history_size, 1, 1)

for present, next_val in zip(present_values, future_values):
    print(tf.squeeze(present).numpy(), '-->', tf.squeeze(next_val).numpy())
[[0.   0.  ]
 [1.   0.01]
 [2.   0.02]] --> [6.   0.06]
[[1.   0.01]
 [2.   0.02]
 [3.   0.03]] --> [7.   0.07]
[[2.   0.02]
 [3.   0.03]
 [4.   0.04]] --> [8.   0.08]
[[3.   0.03]
 [4.   0.04]
 [5.   0.05]] --> [9.   0.09]
[[4.   0.04]
 [5.   0.05]
 [6.   0.06]] --> [10.   0.1]
import tensorflow as tf
import numpy as np

history_size = 3
lookahead = 2

x = tf.range(8)

ds = tf.data.Dataset.from_tensor_slices(x)
ds = ds.window(history_size + lookahead, shift=1, drop_remainder=True)
ds = ds.flat_map(lambda window: window.batch(history_size + lookahead))
ds = ds.map(lambda window: (window[:-lookahead], window[-lookahead:]))

for present_values, next_value in ds:
    print(present_values.numpy(), '-->', next_value.numpy())
[0 1 2] --> [3 4]
[1 2 3] --> [4 5]
[2 3 4] --> [5 6]
[3 4 5] --> [6 7]

具有多个变量:

import tensorflow as tf
import numpy as np

history_size = 3
lookahead = 2

x = tf.concat([
    tf.reshape(tf.range(20, dtype=tf.float32), (-1, 1)),
    tf.reshape(tf.linspace(0., .19, 20), (-1, 1))], axis=-1)

ds = tf.data.Dataset.from_tensor_slices(x)
ds = ds.window(history_size + lookahead, shift=1, drop_remainder=True)
ds = ds.flat_map(lambda window: window.batch(history_size + lookahead))
ds = ds.map(lambda window: (window[:-lookahead], window[-lookahead:]))

for present_values, next_value in ds.take(8):
    print(tf.squeeze(np.round(present_values, 2)).numpy(), '-->',
          tf.squeeze(np.round(next_value, 2)).numpy())
    print()
[[0.   0.  ]
 [1.   0.01]
 [2.   0.02]] --> [[3.   0.03]
                   [4.   0.04]]
[[1.   0.01]
 [2.   0.02]
 [3.   0.03]] --> [[4.   0.04]
                   [5.   0.05]]
[[2.   0.02]
 [3.   0.03]
 [4.   0.04]] --> [[5.   0.05]
                   [6.   0.06]]
[[3.   0.03]
 [4.   0.04]
 [5.   0.05]] --> [[6.   0.06]
                   [7.   0.07]]
[[4.   0.04]
 [5.   0.05]
 [6.   0.06]] --> [[7.   0.07]
                   [8.   0.08]]
[[5.   0.05]
 [6.   0.06]
 [7.   0.07]] --> [[8.   0.08]
                   [9.   0.09]]

匿名用户

在我的案例中,我使用了下面的代码,但没有做什么修改。它很好用。谢谢

future_pred_count=10
future = []
currentStep = np.array([187, 196, 210])

for i in range(future_pred_count):
    prediction = model.predict(currentStep[np.newaxis, :, np.newaxis]) # set dimentions
    future.append(prediction[0][0]) 
    currentStep = np.append(currentStep[1:], prediction[0][0], axis=None ) #store the future steps
    
print(future)