长短期记忆网络,简称 LSTM,可应用于 时间序列预测。
对于每种特定的时间序列预测问题,都可以使用许多类型的 LSTM 模型。
在本教程中,您将了解如何为一系列标准 时间序列预测问题 开发一套 LSTM 模型。
本教程的目标是为每种类型的时间序列问题提供每个模型的独立示例,作为您可以复制和改编以解决您的特定时间序列预测问题的模板。
完成本教程后,您将了解:
- 如何为单变量时间序列预测开发 LSTM 模型。
- 如何为多变量时间序列预测开发 LSTM 模型。
- 如何为多步时间序列预测开发 LSTM 模型。
这是一篇内容丰富且重要的文章;您可能需要将其加入书签以供将来参考。
开始您的项目,阅读我的新书《深度学习时间序列预测》,其中包括分步教程和所有示例的Python源代码文件。
让我们开始吧。

如何开发用于时间序列预测的 LSTM 模型
照片作者:N i c o l a,部分权利保留。
教程概述
在本教程中,我们将探讨如何为时间序列预测开发一套不同类型的 LSTM 模型。
这些模型在小型人为构造的时间序列问题上进行了演示,旨在展现所处理的时间序列问题的类型。模型的配置选择是任意的,并未针对每个问题进行优化;这并非目标。
本教程分为四个部分;它们是
- 单变量 LSTM 模型
- 数据准备
- 标准 LSTM
- 堆叠 LSTM
- 双向 LSTM
- CNN LSTM
- ConvLSTM
- 多变量 LSTM 模型
- 多输入序列。
- 多并行序列。
- 多步 LSTM 模型
- 数据准备
- 向量输出模型
- 编码器-解码器模型
- 多变量多步 LSTM 模型
- 多输入多步输出。
- 多并行输入和多步输出。
单变量 LSTM 模型
LSTM 可用于建模单变量时间序列预测问题。
这些问题由单个观测序列组成,需要模型从过去的观测序列中学习以预测序列中的下一个值。
我们将演示多种 LSTM 模型变体用于单变量时间序列预测。
本节分为六部分;它们是
- 数据准备
- 标准 LSTM
- 堆叠 LSTM
- 双向 LSTM
- CNN LSTM
- ConvLSTM
这些模型中的每一个都针对一步单变量时间序列预测进行了演示,但可以轻松改编并用作其他类型时间序列预测问题模型输入部分。
数据准备
在对单变量序列建模之前,必须对其进行准备。
LSTM 模型将学习一个函数,该函数将过去的观测序列作为输入映射到输出观测。因此,必须将观测序列转换为多个 LSTM 可以从中学习的示例。
考虑一个给定的单变量序列
1 |
[10, 20, 30, 40, 50, 60, 70, 80, 90] |
我们可以将序列分成多个输入/输出模式,称为样本,其中三个时间步用作输入,一个时间步用作输出,用于学习一步预测。
1 2 3 4 5 |
X, y 10, 20, 30 40 20, 30, 40 50 30, 40, 50 60 ... |
下面的 `split_sequence()` 函数实现了这种行为,它将给定的单变量序列分成多个样本,其中每个样本具有指定的时间步数,并且输出是一个时间步。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 将单变量序列分成样本 def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出序列 if end_ix > len(sequence)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) |
我们可以在上面小巧的人造数据集上演示这个函数。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 单变量数据准备 from numpy import array # 将单变量序列分成样本 def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出序列 if end_ix > len(sequence)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps = 3 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 汇总数据 for i in range(len(X)): print(X[i], y[i]) |
运行该示例将单变量序列分成六个样本,其中每个样本有三个输入时间步和一个输出时间步。
1 2 3 4 5 6 |
[10 20 30] 40 [20 30 40] 50 [30 40 50] 60 [40 50 60] 70 [50 60 70] 80 [60 70 80] 90 |
现在我们知道如何准备单变量序列以进行建模,让我们来看看开发可以学习输入到输出映射的 LSTM 模型,首先从标准 LSTM 开始。
时间序列深度学习需要帮助吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
标准 LSTM
标准 LSTM 是一个 LSTM 模型,它有一个 LSTM 单元的隐藏层和一个用于进行预测的输出层。
我们可以按如下方式定义一个用于单变量时间序列预测的标准 LSTM。
1 2 3 4 5 6 |
... # 定义模型 model = Sequential() model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') |
定义中的关键是输入的形状;即模型对每个样本期望的输入,就时间步数和特征数而言。
我们正在处理单变量序列,因此特征数为一,代表一个变量。
输入的时间步数是我们选择的在准备数据集时作为 `split_sequence()` 函数的参数。
每个样本的输入形状在第一个隐藏层的定义中的 `input_shape` 参数中指定。
我们几乎总是有多个样本,因此,模型将期望训练数据的输入组件具有维度或形状
1 |
[样本数, 时间步数, 特征数] |
我们上一节的 `split_sequence()` 函数输出的 X 的形状为 [样本, 时间步],因此我们可以轻松地将其重塑为一个额外的维度,用于一个特征。
1 2 3 4 |
... # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) |
在这种情况下,我们定义了一个在隐藏层中有 50 个 LSTM 单元的模型,以及一个预测单个数值的输出层。
该模型使用高效的 随机梯度下降的 Adam 版本 进行拟合,并使用均方误差或“mse”损失函数进行优化。
定义模型后,我们可以在训练数据集上对其进行拟合。
1 2 3 |
... # 拟合模型 model.fit(X, y, epochs=200, verbose=0) |
模型拟合后,我们可以使用它进行预测。
我们可以通过提供输入来预测序列中的下一个值
1 |
[70, 80, 90] |
并期望模型能预测出类似这样的结果
1 |
[100] |
模型期望的输入形状是三维的,即 [样本, 时间步, 特征],因此,在进行预测之前,我们必须重塑单个输入样本。
1 2 3 4 5 |
... # 演示预测 x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) |
我们可以将所有这些结合起来,并演示如何为单变量时间序列预测开发标准 LSTM 并进行单个预测。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# 单变量 LSTM 示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense # 将单变量序列分成样本 def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出序列 if end_ix > len(sequence)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps = 3 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) # 定义模型 model = Sequential() model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=200, verbose=0) # 演示预测 x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行该示例会准备数据、拟合模型并进行预测。
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
我们可以看到模型预测了序列中的下一个值。
1 |
[[102.09213]] |
堆叠 LSTM
多个隐藏 LSTM 层可以一个接一个地堆叠,这被称为堆叠 LSTM 模型。
LSTM 层需要三维输入,而 LSTM 默认会产生二维输出,作为对序列末端的解释。
我们可以通过在层上设置 `return_sequences=True` 参数来解决此问题,让 LSTM 为输入数据中的每个时间步输出一个值。这允许我们将隐藏 LSTM 层的 3D 输出作为下一个层的输入。
因此,我们可以按如下方式定义堆叠 LSTM。
1 2 3 4 5 6 7 |
... # 定义模型 model = Sequential() model.add(LSTM(50, activation='relu', return_sequences=True, input_shape=(n_steps, n_features))) model.add(LSTM(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') |
我们可以将这些结合起来;完整的代码示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# 单变量堆叠 LSTM 示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense # 分割单变量序列 def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出序列 if end_ix > len(sequence)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps = 3 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) # 定义模型 model = Sequential() model.add(LSTM(50, activation='relu', return_sequences=True, input_shape=(n_steps, n_features))) model.add(LSTM(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=200, verbose=0) # 演示预测 x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行示例可以预测序列中的下一个值,我们预期该值将是 100。
1 |
[[102.47341]] |
双向 LSTM
在某些序列预测问题上,允许 LSTM 模型同时学习输入序列的向前和向后方向并连接这两种解释可能是有益的。
这被称为 双向 LSTM。
我们可以通过将第一个隐藏层包装在称为 Bidirectional 的包装器层中来实现双向 LSTM,用于单变量时间序列预测。
以下是定义双向 LSTM 以同时读取输入序列向前和向后方向的示例。
1 2 3 4 5 6 |
... # 定义模型 model = Sequential() model.add(Bidirectional(LSTM(50, activation='relu'), input_shape=(n_steps, n_features))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') |
用于单变量时间序列预测的双向 LSTM 的完整示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# 单变量双向 LSTM 示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import Bidirectional # 分割单变量序列 def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出序列 if end_ix > len(sequence)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps = 3 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) # 定义模型 model = Sequential() model.add(Bidirectional(LSTM(50, activation='relu'), input_shape=(n_steps, n_features))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=200, verbose=0) # 演示预测 x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行示例可以预测序列中的下一个值,我们预期该值将是 100。
1 |
[[101.48093]] |
CNN LSTM
卷积神经网络,简称 CNN,是一种为处理二维图像数据而开发的神经网络类型。
CNN 在自动提取和学习一维序列数据(如单变量时间序列数据)的特征方面非常有效。
CNN 模型可以在混合模型中使用 LSTM 作为后端,其中 CNN 用于解释输入子序列,然后这些子序列一起作为输入提供给 LSTM 模型进行处理。 这种混合模型称为 CNN-LSTM。
第一步是将输入序列分割成可由 CNN 模型处理的子序列。例如,我们可以先将单变量时间序列数据分割成输入/输出样本,其中四个时间步作为输入,一个时间步作为输出。然后每个样本可以被分割成两个子样本,每个子样本包含两个时间步。CNN 可以解释每个包含两个时间步的子序列,并提供一个子序列解释的时间序列给 LSTM 模型作为输入进行处理。
我们可以参数化这一点,并将子序列的数量定义为 `n_seq`,每个子序列的时间步数定义为 `n_steps`。然后可以重塑输入数据以获得所需的结构
1 |
[样本, 子序列, 时间步, 特征] |
例如
1 2 3 4 5 6 7 8 9 10 |
... # 选择时间步数 n_steps = 4 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 从 [样本, 时间步] 重塑为 [样本, 子序列, 时间步, 特征] n_features = 1 n_seq = 2 n_steps = 2 X = X.reshape((X.shape[0], n_seq, n_steps, n_features)) |
我们希望在单独读取每个数据子序列时重用相同的 CNN 模型。
这可以通过将整个 CNN 模型包装在 TimeDistributed 包装器 中来实现,该包装器将对每个输入应用整个模型,在这种情况下,每个输入子序列应用一次。
CNN 模型首先有一个用于读取子序列的卷积层,这需要指定滤波器数量和卷积核大小。滤波器数量是输入序列的读取次数或解释次数。卷积核大小是输入序列每次“读取”操作包含的时间步数。
卷积层之后是一个最大池化层,它将滤波器图缩小到其大小的 1/2,其中包含最突出的特征。然后将这些结构展平为单个一维向量,用作 LSTM 层的单个输入时间步。
1 2 3 4 |
... model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation='relu'), input_shape=(None, n_steps, n_features))) model.add(TimeDistributed(MaxPooling1D(pool_size=2))) model.add(TimeDistributed(Flatten())) |
接下来,我们可以定义模型的 LSTM 部分,该部分解释 CNN 模型对输入序列的读取并进行预测。
1 2 3 |
... model.add(LSTM(50, activation='relu')) model.add(Dense(1)) |
我们可以将所有这些结合起来;用于单变量时间序列预测的 CNN-LSTM 的完整示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# 单变量 cnn lstm 示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import Flatten from keras.layers import TimeDistributed from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # 将单变量序列分成样本 def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出序列 if end_ix > len(sequence)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps = 4 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 从 [样本, 时间步] 重塑为 [样本, 子序列, 时间步, 特征] n_features = 1 n_seq = 2 n_steps = 2 X = X.reshape((X.shape[0], n_seq, n_steps, n_features)) # 定义模型 model = Sequential() model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation='relu'), input_shape=(None, n_steps, n_features))) model.add(TimeDistributed(MaxPooling1D(pool_size=2))) model.add(TimeDistributed(Flatten())) model.add(LSTM(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=500, verbose=0) # 演示预测 x_input = array([60, 70, 80, 90]) x_input = x_input.reshape((1, n_seq, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行示例可以预测序列中的下一个值,我们预期该值将是 100。
1 |
[[101.69263]] |
ConvLSTM
一种与 CNN-LSTM 相关的 LSTM 类型是 ConvLSTM,其中卷积读取输入直接内置到每个 LSTM 单元中。
ConvLSTM 是为读取二维时空数据而开发的,但可用于单变量时间序列预测。
该层期望输入是二维图像序列,因此输入数据的形状必须是
1 |
[样本, 时间步, 行, 列, 特征] |
为方便起见,我们可以将每个样本分割成子序列,其中时间步将成为子序列的数量,即 `n_seq`,而每个子序列的列数将是时间步数,即 `n_steps`。由于我们处理的是一维数据,行数固定为 1。
我们现在可以将准备好的样本重塑为所需的结构。
1 2 3 4 5 6 7 8 9 10 |
... # 选择时间步数 n_steps = 4 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 从 [样本, 时间步] 重塑为 [样本, 时间步, 行, 列, 特征] n_features = 1 n_seq = 2 n_steps = 2 X = X.reshape((X.shape[0], n_seq, 1, n_steps, n_features)) |
我们可以将 ConvLSTM 定义为一个层,指定滤波器数量和二维卷积核大小(行、列)。由于我们处理的是一维序列,在卷积核中行数始终固定为 1。
然后必须展平模型的输出,才能进行解释和预测。
1 2 3 |
... model.add(ConvLSTM2D(filters=64, kernel_size=(1,2), activation='relu', input_shape=(n_seq, 1, n_steps, n_features))) model.add(Flatten()) |
用于一步单变量时间序列预测的 ConvLSTM 的完整示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# 单变量 convlstm 示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import Flatten from keras.layers import ConvLSTM2D # 将单变量序列分成样本 def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出序列 if end_ix > len(sequence)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps = 4 # 分割成样本 X, y = split_sequence(raw_seq, n_steps) # 从 [样本, 时间步] 重塑为 [样本, 时间步, 行, 列, 特征] n_features = 1 n_seq = 2 n_steps = 2 X = X.reshape((X.shape[0], n_seq, 1, n_steps, n_features)) # 定义模型 model = Sequential() model.add(ConvLSTM2D(filters=64, kernel_size=(1,2), activation='relu', input_shape=(n_seq, 1, n_steps, n_features))) model.add(Flatten()) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=500, verbose=0) # 演示预测 x_input = array([60, 70, 80, 90]) x_input = x_input.reshape((1, n_seq, 1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行示例可以预测序列中的下一个值,我们预期该值将是 100。
1 |
[[103.68166]] |
在查看了单变量数据 LSTM 模型后,现在我们转向多变量数据。
多变量 LSTM 模型
多变量时间序列数据是指每个时间步有多个观测值的数据。
对于多变量时间序列数据,我们可能需要两种主要模型;它们是
- 多输入序列。
- 多并行序列。
让我们依次看看每一个。
多输入序列
一个问题可能有两个或多个并行输入时间序列和一个依赖于输入时间序列的输出时间序列。
输入时间序列是并行的,因为每个序列在相同的时间步都有一个观测值。
我们可以用一个简单的例子来演示,其中有两个并行的输入时间序列,输出序列是输入序列的简单相加。
1 2 3 4 5 |
... # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) |
我们可以将这三个数据数组重塑为单个数据集,其中每一行是一个时间步,每一列是一个单独的时间序列。这是在 CSV 文件中存储并行时间序列的标准方法。
1 2 3 4 5 6 7 |
... # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) |
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 多变量数据准备 from numpy import array from numpy import hstack # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) print(dataset) |
运行该示例会打印数据集,其中每行是一个时间步,每个两输入一输出并行时间序列的列。
1 2 3 4 5 6 7 8 9 |
[[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] |
与单变量时间序列一样,我们必须将这些数据结构化为具有输入和输出元素的样本。
LSTM 模型需要足够的上下文来学习从输入序列到输出值的映射。LSTM 可以将并行输入时间序列作为单独的变量或特征来支持。因此,我们需要将数据分割成样本,保持两个输入序列的观测顺序。
如果我们选择三个输入时间步,那么第一个样本将如下所示
输入
1 2 3 |
10, 15 20, 25 30, 35 |
输出
1 |
65 |
也就是说,每个并行序列的前三个时间步作为模型的输入,模型将其与第三个时间步的输出序列中的值相关联,在本例中是 65。
我们可以看到,在将时间序列转换为输入/输出样本以训练模型时,我们必须从输出时间序列中丢弃一些值,这些值在先前的输入时间序列中没有对应的值。反过来,输入时间步数大小的选择将对训练数据的用量产生重要影响。
我们可以定义一个名为 `split_sequences()` 的函数,它将接收我们定义的以时间步为行、并行序列为列的数据集,并返回输入/输出样本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 将多变量序列分割成样本 def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出数据集 if end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) |
我们可以使用每个输入时间序列的三个时间步作为输入,在我们的数据集上测试这个函数。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# 多变量数据准备 from numpy import array from numpy import hstack # 将多变量序列分割成样本 def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出数据集 if end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps = 3 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps) print(X.shape, y.shape) # 汇总数据 for i in range(len(X)): print(X[i], y[i]) |
运行示例首先打印 X 和 y 组件的形状。
我们可以看到 X 组件具有三维结构。
第一个维度是样本数,在本例中为 7。第二个维度是每个样本的时间步数,在本例中为 3,这是指定给函数的参数。最后,最后一个维度指定了并行时间序列的数量或变量的数量,在本例中为 2 个并行序列。
这是 LSTM 作为输入所期望的精确三维结构。数据无需进一步重塑即可使用。
然后,我们可以看到打印了每个样本的输入和输出,显示了每个两个输入序列的三个时间步以及每个样本的相关输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
(7, 3, 2) (7,) [[10 15] [20 25] [30 35]] 65 [[20 25] [30 35] [40 45]] 85 [[30 35] [40 45] [50 55]] 105 [[40 45] [50 55] [60 65]] 125 [[50 55] [60 65] [70 75]] 145 [[60 65] [70 75] [80 85]] 165 [[70 75] [80 85] [90 95]] 185 |
我们现在可以开始在该数据上拟合 LSTM 模型。
上一节中介绍的任何一种 LSTM(如标准 LSTM、堆叠 LSTM、双向 LSTM、CNN LSTM 或 ConvLSTM)都可以使用。
我们将使用标准 LSTM,其中时间步数和并行序列(特征)通过 `input_shape` 参数为输入层指定。
1 2 3 4 5 6 |
... # 定义模型 model = Sequential() model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') |
进行预测时,模型需要两个输入时间序列的三个时间步。
我们通过提供以下输入值来预测序列中的下一个值:
1 2 3 |
80, 85 90, 95 100, 105 |
具有三个时间步和两个变量的单个样本的形状必须是 [1, 3, 2]。
我们预期序列中的下一个值将是 100 + 105,即 205。
1 2 3 4 5 |
... # 演示预测 x_input = array([[80, 85], [90, 95], [100, 105]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) |
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# 多变量 LSTM 示例 from numpy import array from numpy import hstack from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense # 将多变量序列分割成样本 def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出数据集 if end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps = 3 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps) # 数据集知道特征的数量,例如 2 n_features = X.shape[2] # 定义模型 model = Sequential() model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=200, verbose=0) # 演示预测 x_input = array([[80, 85], [90, 95], [100, 105]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行该示例会准备数据、拟合模型并进行预测。
1 |
[[208.13531]] |
多并行序列
另一种时间序列问题是存在多个并行时间序列,并且必须为每个序列预测一个值。
例如,给定上一节中的数据
1 2 3 4 5 6 7 8 9 |
[[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] |
我们可能希望预测下一个时间步的三个时间序列中的每一个的值。
这可以被称为多变量预测。
同样,必须将数据拆分为输入/输出样本才能训练模型。
该数据集的第一个样本将如下所示
输入
1 2 3 |
10, 15, 25 20, 25, 45 30, 35, 65 |
输出
1 |
40, 45, 85 |
下面的 `split_sequences()` 函数将把以时间步为行、每列一个序列的多个并行时间序列分割成所需的输入/输出形状。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 将多变量序列分割成样本 def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出数据集 if end_ix > len(sequences)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) |
我们可以在人造问题上演示这一点;完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# 多变量输出数据准备 from numpy import array from numpy import hstack # 将多变量序列分割成样本 def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出数据集 if end_ix > len(sequences)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps = 3 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps) print(X.shape, y.shape) # 汇总数据 for i in range(len(X)): print(X[i], y[i]) |
运行示例首先打印准备好的 X 和 y 组件的形状。
X 的形状是三维的,包括样本数(6),每个样本的时间步数(3),以及并行时间序列的数量或特征数(3)。
y 的形状是二维的,正如我们对样本数(6)和每个样本需要预测的时间变量数(3)的预期一样。
数据已准备好在 LSTM 模型中使用,该模型期望 X 和 y 组件的输入和输出形状分别为三维和二维。
然后,打印每个样本,显示每个样本的输入和输出组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
(6, 3, 3) (6, 3) [[10 15 25] [20 25 45] [30 35 65]] [40 45 85] [[20 25 45] [30 35 65] [40 45 85]] [ 50 55 105] [[ 30 35 65] [ 40 45 85] [ 50 55 105]] [ 60 65 125] [[ 40 45 85] [ 50 55 105] [ 60 65 125]] [ 70 75 145] [[ 50 55 105] [ 60 65 125] [ 70 75 145]] [ 80 85 165] [[ 60 65 125] [ 70 75 145] [ 80 85 165]] [ 90 95 185] |
我们现在可以开始在该数据上拟合 LSTM 模型。
上一节中介绍的任何一种 LSTM(如标准 LSTM、堆叠 LSTM、双向 LSTM、CNN LSTM 或 ConvLSTM)都可以使用。
我们将使用堆叠 LSTM,其中时间步数和并行序列(特征)通过 `input_shape` 参数为输入层指定。并行序列的数量也用于指定模型在输出层中需要预测的值的数量;这仍然是三个。
1 2 3 4 5 6 7 |
... # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(n_steps, n_features))) model.add(LSTM(100, activation='relu')) model.add(Dense(n_features)) model.compile(optimizer='adam', loss='mse') |
我们可以通过提供每个序列的三个时间步作为输入,预测三个并行序列中的每个序列的下一个值。
1 2 3 |
70, 75, 145 80, 85, 165 90, 95, 185 |
进行单个预测时,输入样本的形状必须是 [1, 3, 3],即 1 个样本,3 个输入时间步,以及 3 个特征。
1 2 3 4 5 |
... # 演示预测 x_input = array([[70,75,145], [80,85,165], [90,95,185]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) |
我们预期向量输出为
1 |
[100, 105, 205] |
我们可以将所有这些结合起来,并在下面演示用于多变量输出时间序列预测的堆叠 LSTM。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# 多变量输出堆叠 LSTM 示例 from numpy import array from numpy import hstack from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense # 将多变量序列分割成样本 def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps # 检查是否超出数据集 if end_ix > len(sequences)-1: break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps = 3 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps) # 数据集知道特征的数量,例如 2 n_features = X.shape[2] # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(n_steps, n_features))) model.add(LSTM(100, activation='relu')) model.add(Dense(n_features)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=400, verbose=0) # 演示预测 x_input = array([[70,75,145], [80,85,165], [90,95,185]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行该示例会准备数据、拟合模型并进行预测。
1 |
[[101.76599 108.730484 206.63577 ]] |
多步 LSTM 模型
需要预测未来多个时间步的时间序列预测问题可以称为多步时间序列预测。
具体来说,这些问题是指预测范围或间隔大于一个时间步的问题。
有两种主要的 LSTM 模型可用于多步预测;它们是
- 向量输出模型
- 编码器-解码器模型
在研究这些模型之前,让我们先看看多步预测的数据准备。
数据准备
与一步预测一样,用于多步时间序列预测的时间序列必须分解为包含输入和输出组件的样本。
输入和输出组件都将由多个时间步组成,并且可能具有或不具有相同数量的步。
例如,给定单变量时间序列
1 |
[10, 20, 30, 40, 50, 60, 70, 80, 90] |
我们可以使用最后三个时间步作为输入,并预测接下来的两个时间步。
第一个样本将如下所示
输入
1 |
[10, 20, 30] |
输出
1 |
[40, 50] |
下面的 `split_sequence()` 函数实现了这种行为,它将给定的单变量时间序列分割成具有指定数量的输入和输出时间步的样本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 将单变量序列分成样本 def split_sequence(sequence, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # 检查是否超出序列 if out_end_ix > len(sequence): break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) |
我们可以在这个小巧的人造数据集上演示这个函数。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# 多步数据准备 from numpy import array # 将单变量序列分成样本 def split_sequence(sequence, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # 检查是否超出序列 if out_end_ix > len(sequence): break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps_in, n_steps_out = 3, 2 # 分割成样本 X, y = split_sequence(raw_seq, n_steps_in, n_steps_out) # 汇总数据 for i in range(len(X)): print(X[i], y[i]) |
运行示例将单变量序列分割成输入和输出时间步,并打印每个时间步的输入和输出组件。
1 2 3 4 5 |
[10 20 30] [40 50] [20 30 40] [50 60] [30 40 50] [60 70] [40 50 60] [70 80] [50 60 70] [80 90] |
现在我们知道如何准备多步预测的数据,让我们看看可以学习这种映射的一些 LSTM 模型。
向量输出模型
与其他类型的神经网络模型一样,LSTM 可以直接输出一个向量,该向量可以被解释为多步预测。
这种方法在上一节中已经出现,其中每个输出时间序列的一个时间步被预测为一个向量。
与先前部分中的单变量数据 LSTM 一样,准备好的样本必须先重塑。LSTM 期望数据具有 [样本, 时间步, 特征] 的三维结构,在这种情况下,我们只有一个特征,因此重塑非常简单。
1 2 3 4 |
... # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) |
在 `n_steps_in` 和 `n_steps_out` 变量中指定了输入和输出步数后,我们可以定义一个多步时间序列预测模型。
前面介绍的任何一种 LSTM 模型类型都可以使用,例如标准 LSTM、堆叠 LSTM、双向 LSTM、CNN-LSTM 或 ConvLSTM。下面定义了一个用于多步预测的堆叠 LSTM。
1 2 3 4 5 6 7 |
... # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(n_steps_in, n_features))) model.add(LSTM(100, activation='relu')) model.add(Dense(n_steps_out)) model.compile(optimizer='adam', loss='mse') |
该模型可以对单个样本进行预测。我们可以通过提供输入来预测数据集末尾之后的两个步骤
1 |
[70, 80, 90] |
我们预期预测输出为
1 |
[100, 110] |
正如模型所预期的,进行预测时单个输入数据的形状必须是 [1, 3, 1],对应于 1 个样本、3 个输入时间步和 1 个特征。
1 2 3 4 5 |
... # 演示预测 x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) |
将所有这些结合起来,用于多步预测的堆叠 LSTM 如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# 单变量多步向量输出堆叠 LSTM 示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense # 将单变量序列分成样本 def split_sequence(sequence, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # 检查是否超出序列 if out_end_ix > len(sequence): break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps_in, n_steps_out = 3, 2 # 分割成样本 X, y = split_sequence(raw_seq, n_steps_in, n_steps_out) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(n_steps_in, n_features))) model.add(LSTM(100, activation='relu')) model.add(Dense(n_steps_out)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=50, verbose=0) # 演示预测 x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行示例预测并打印序列中的接下来的两个时间步。
1 |
[[100.98096 113.28924]] |
编码器-解码器模型
一个专门为预测可变长度输出序列而开发的模型称为 编码器-解码器 LSTM。
该模型是为输入和输出序列都存在的预测问题设计的,即所谓的序列到序列,或 seq2seq 问题,例如将文本从一种语言翻译成另一种语言。
此模型可用于多步时间序列预测。
顾名思义,该模型由两个子模型组成:编码器和解码器。
编码器是负责读取和解释输入序列的模型。编码器的输出是一个固定长度的向量,代表模型对序列的解释。编码器通常是一个标准 LSTM 模型,尽管也可以使用其他编码器模型,如堆叠 LSTM、双向 LSTM 和 CNN 模型。
1 2 |
... model.add(LSTM(100, activation='relu', input_shape=(n_steps_in, n_features))) |
解码器使用编码器的输出来作为输入。
首先,对编码器的固定长度输出进行重复,每次重复一个输出序列所需的时间步数。
1 2 |
... model.add(RepeatVector(n_steps_out)) |
然后将此序列提供给 LSTM 解码器模型。该模型必须为输出时间步中的每个值输出一个值,该值可以由单个输出模型进行解释。
1 2 |
... model.add(LSTM(100, activation='relu', return_sequences=True)) |
我们可以使用相同的输出层或层来使输出序列中的每个一步预测。这可以通过将模型输出部分包装在 TimeDistributed 包装器 中来实现。
1 2 |
.... model.add(TimeDistributed(Dense(1))) |
用于多步时间序列预测的编码器-解码器模型的完整定义如下。
1 2 3 4 5 6 7 8 |
... # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', input_shape=(n_steps_in, n_features))) model.add(RepeatVector(n_steps_out)) model.add(LSTM(100, activation='relu', return_sequences=True)) model.add(TimeDistributed(Dense(1))) model.compile(optimizer='adam', loss='mse') |
与其他 LSTM 模型一样,输入数据必须重塑为所需的三维形状 [样本, 时间步, 特征]。
1 2 |
... X = X.reshape((X.shape[0], X.shape[1], n_features)) |
对于编码器-解码器模型,训练数据集的输出(或 y 部分)也必须具有此形状。这是因为模型将为每个输入样本预测给定数量的时间步和给定数量的特征。
1 2 |
... y = y.reshape((y.shape[0], y.shape[1], n_features)) |
用于多步时间序列预测的编码器-解码器 LSTM 的完整示例列在下面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# 单变量多步编码器-解码器 LSTM 示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import RepeatVector from keras.layers import TimeDistributed # 将单变量序列分成样本 def split_sequence(sequence, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequence)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # 检查是否超出序列 if out_end_ix > len(sequence): break # 收集模式的输入和输出部分 seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # 选择时间步数 n_steps_in, n_steps_out = 3, 2 # 分割成样本 X, y = split_sequence(raw_seq, n_steps_in, n_steps_out) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) y = y.reshape((y.shape[0], y.shape[1], n_features)) # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', input_shape=(n_steps_in, n_features))) model.add(RepeatVector(n_steps_out)) model.add(LSTM(100, activation='relu', return_sequences=True)) model.add(TimeDistributed(Dense(1))) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=100, verbose=0) # 演示预测 x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
运行示例预测并打印序列中的接下来的两个时间步。
1 2 |
[[[101.9736 [116.213615]]] |
多变量多步 LSTM 模型
在前面的章节中,我们研究了单变量、多变量和多步时间序列预测。
可以将到目前为止介绍的各种 LSTM 模型类型进行混合搭配,以用于不同的问题。这也适用于涉及多变量和多步预测的时间序列预测问题,但这可能更具挑战性。
在本节中,我们将提供多变量多步时间序列预测的数据准备和建模的简短示例,作为一种模板来缓解这一挑战,具体来说是
- 多输入多步输出。
- 多并行输入和多步输出。
也许最大的绊脚石在于数据准备,所以这是我们将重点关注的地方。
多输入多步输出
有些多变量时间序列预测问题中,输出序列是独立的,但依赖于输入时间序列,并且输出序列需要多个时间步。
例如,考虑我们之前章节中的多变量时间序列
1 2 3 4 5 6 7 8 9 |
[[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] |
我们可以使用两个输入时间序列中的每个序列的三个先前时间步来预测输出时间序列的两个时间步。
输入
1 2 3 |
10, 15 20, 25 30, 35 |
输出
1 2 |
65 85 |
下面的 split_sequences() 函数实现了此行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 将多变量序列分割成样本 def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out-1 # 检查是否超出数据集 if out_end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) |
我们可以用我们的人工数据集来演示这一点。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# 多变量多步数据准备 from numpy import array from numpy import hstack # 将多变量序列分割成样本 def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out-1 # 检查是否超出数据集 if out_end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps_in, n_steps_out = 3, 2 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps_in, n_steps_out) print(X.shape, y.shape) # 汇总数据 for i in range(len(X)): print(X[i], y[i]) |
运行示例首先打印已准备好的训练数据的形状。
我们可以看到,样本的输入部分的形状是三维的,由六个样本、三个时间步以及用于 2 个输入时间序列的两个变量组成。
样本的输出部分是二维的,用于六个样本和每个样本要预测的两个时间步长。
然后打印已准备好的样本,以确认数据已按我们指定的方式准备。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
(6, 3, 2) (6, 2) [[10 15] [20 25] [30 35]] [65 85] [[20 25] [30 35] [40 45]] [ 85 105] [[30 35] [40 45] [50 55]] [105 125] [[40 45] [50 55] [60 65]] [125 145] [[50 55] [60 65] [70 75]] [145 165] [[60 65] [70 75] [80 85]] [165 185] |
我们现在可以开发一个用于多步预测的 LSTM 模型。
可以使用向量输出或编码器-解码器模型。在这种情况下,我们将演示使用堆叠 LSTM 进行向量输出。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# 多变量多步堆叠 LSTM 示例 from numpy import array from numpy import hstack from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense # 将多变量序列分割成样本 def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out-1 # 检查是否超出数据集 if out_end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps_in, n_steps_out = 3, 2 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps_in, n_steps_out) # 数据集知道特征的数量,例如 2 n_features = X.shape[2] # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(n_steps_in, n_features))) model.add(LSTM(100, activation='relu')) model.add(Dense(n_steps_out)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=200, verbose=0) # 演示预测 x_input = array([[70, 75], [80, 85], [90, 95]]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行示例会拟合模型并预测数据集之外的输出序列的接下来两个时间步。
我们预期接下来的两步是:[185, 205]
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
这是一个具有很少数据的具有挑战性的问题框架,并且模型是任意配置的,但结果很接近。
1 |
[[188.70619 210.16513]] |
多个并行输入和多步输出
并行时间序列问题可能需要预测每个时间序列的多个时间步。
例如,考虑我们之前章节中的多变量时间序列
1 2 3 4 5 6 7 8 9 |
[[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] |
我们可以使用每个时间序列的最后三个时间步作为模型的输入,并预测每个时间序列的下一个时间步作为输出。
训练数据集中的第一个样本如下。
输入
1 2 3 |
10, 15, 25 20, 25, 45 30, 35, 65 |
输出
1 2 |
40, 45, 85 50, 55, 105 |
下面的 split_sequences() 函数实现了此行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 将多变量序列分割成样本 def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # 检查是否超出数据集 if out_end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) |
我们可以在这个小巧的人造数据集上演示这个函数。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# 多变量多步数据准备 from numpy import array from numpy import hstack from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import RepeatVector from keras.layers import TimeDistributed # 将多变量序列分割成样本 def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # 检查是否超出数据集 if out_end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps_in, n_steps_out = 3, 2 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps_in, n_steps_out) print(X.shape, y.shape) # 汇总数据 for i in range(len(X)): print(X[i], y[i]) |
运行示例首先打印已准备好的训练数据集的形状。
我们可以看到,数据集的输入(X)和输出(Y)部分都是三维的,分别代表样本数、时间步数和变量或并行时间序列的数量。
然后并排打印每个序列的输入和输出元素,以便我们可以确认数据已按预期准备。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(5, 3, 3) (5, 2, 3) [[10 15 25] [20 25 45] [30 35 65]] [[ 40 45 85] [ 50 55 105]] [[20 25 45] [30 35 65] [40 45 85]] [[ 50 55 105] [ 60 65 125]] [[ 30 35 65] [ 40 45 85] [ 50 55 105]] [[ 60 65 125] [ 70 75 145]] [[ 40 45 85] [ 50 55 105] [ 60 65 125]] [[ 70 75 145] [ 80 85 165]] [[ 50 55 105] [ 60 65 125] [ 70 75 145]] [[ 80 85 165] [ 90 95 185]] |
我们可以使用向量输出或编码器-解码器 LSTM 来建模这个问题。在这种情况下,我们将使用编码器-解码器模型。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# 多变量多步编码器-解码器 LSTM 示例 from numpy import array from numpy import hstack from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import RepeatVector from keras.layers import TimeDistributed # 将多变量序列分割成样本 def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # 找到此模式的末尾 end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # 检查是否超出数据集 if out_end_ix > len(sequences): break # 收集模式的输入和输出部分 seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # 定义输入序列 in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # 转换为 [行, 列] 结构 in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # 水平堆叠列 dataset = hstack((in_seq1, in_seq2, out_seq)) # 选择时间步数 n_steps_in, n_steps_out = 3, 2 # 转换为输入/输出 X, y = split_sequences(dataset, n_steps_in, n_steps_out) # 数据集知道特征的数量,例如 2 n_features = X.shape[2] # 定义模型 model = Sequential() model.add(LSTM(200, activation='relu', input_shape=(n_steps_in, n_features))) model.add(RepeatVector(n_steps_out)) model.add(LSTM(200, activation='relu', return_sequences=True)) model.add(TimeDistributed(Dense(n_features))) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=300, verbose=0) # 演示预测 x_input = array([[60, 65, 125], [70, 75, 145], [80, 85, 165]]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行示例会拟合模型并预测数据集末尾之外的接下来两个时间步的三个时间步中的每个时间步的值。
我们期望这些序列和时间步的值如下
1 2 |
90, 95, 185 100, 105, 205 |
注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑多次运行示例并比较平均结果。
我们可以看到模型预测非常接近预期值。
1 2 |
[[[ 91.86044 97.77231 189.66768 ] [103.299355 109.18123 212.6863 ]]] |
进一步阅读
- 长短期记忆, Wikipedia。
- 时间序列预测深度学习 (我的书)
总结
在本教程中,您学习了如何为一系列标准时间序列预测问题开发一套 LSTM 模型。
具体来说,你学到了:
- 如何为单变量时间序列预测开发 LSTM 模型。
- 如何为多变量时间序列预测开发 LSTM 模型。
- 如何为多步时间序列预测开发 LSTM 模型。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
这个教程对我帮助很大。非常感谢!
如果数据集被分成批次,在实际项目中会更有帮助。希望您将来能提到这一点。
Keras 会将数据集分成批次。
我认为这篇博文(https://machinelearning.org.cn/use-different-batch-sizes-training-predicting-python-keras/)可能回答了我的问题。我会做更多研究。非常感谢。
太棒了!
谢谢你
嗨!
我想引用您的书“深度学习时间序列预测:使用 MLP、CNN 和 LSTM 进行 Python 预测”。是否有合适的格式?
《深度学习时间序列预测:使用 MLP、CNN 和 LSTM 进行 Python 预测》。是否有合适的格式?
是的,请看这里
https://machinelearning.org.cn/faq/single-faq/how-do-i-reference-or-cite-a-book-or-blog-post
嗨,Jason,
我想要一个基于滑动窗口的支持向量回归的预测示例。
您有这个例子吗?
非常感谢
感谢您的建议。
Jason,这个教程很棒
我有一个问题
在多并行输入中,LSTM编码器-解码器模型的输出将是3D的,如何将其转换回2D?我之所以这样问,是因为我对数据进行了 minmaxscaler() 缩放,它期望输入是2D数组。
为了将预测值与原始值进行比较,我需要执行反向缩放,但我被卡在如何重塑3D输入和输出以使其回到2D而不会丢失任何数据。
您可能需要编写自定义代码来在反向缩放每个变量的值之前收集它们。
你好 Jason,
非常非常感谢您的博文,它非常有帮助。对于多时间步输出的 LSTM 模型,我想知道模型 1 和模型 2 的性能差异是什么?模型 1 是您的多时间步输出 LSTM 模型,例如,我们输入过去 7 天的数据特征,输出是未来 5 天的价格。模型 2 是简单的 1 时间步输出 LSTM 模型,其中输入是过去 7 天的数据特征,输出是第二天的价格。然后我们使用预测的价格作为新输入来预测未来的价格,直到我们预测出所有未来 5 天的价格。
我想知道这两种预测未来 5 天价格的策略之间的关键区别是什么?这两种 LSTM 模型各有什么优缺点?
谢谢你,
好问题,这两种方法的差异很大程度上取决于模型的选择和数据集的复杂性。
这篇博文比较了不同的方法
https://machinelearning.org.cn/multi-step-time-series-forecasting/
嗨,Jason,
感谢您的博文。它们真的很有帮助,我从 machinelearningmastery 学到了很多。
这篇关于 LSTM 的博文信息量很大,但我想问一个问题
我有一组幅度扫描,我想预测下一个扫描(多对一问题)。所以我的数据是 (6,590),结果应该是 (1,590)。590 是扫描中的幅度值。
A. LSTM 能解决这个问题吗?
B. 即使可能,考虑到它预测的时间步长和特征数量,您认为系统的性能如何?
谢谢
不客气。
试试看。这个框架会有帮助
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
annemarieke-de.haan@unilever.com
感谢 Jason 提供这个精彩的教程。我有一个问题。当我们有两个不同的时间序列,1 和 2。时间序列 1 会影响时间序列 2,我们的目标是预测时间序列 2 的未来值。如何为此类情况使用 LSTM?
我称之为依赖时间序列问题。我在这篇博文中给出了如何建模的示例
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
链接是当前页面的链接,您是这个意思吗?
是的,我在上面给出了一个示例。
感谢 Jason 提供这个精彩的教程,我阅读您的教程很久了,我有一个问题。如何使用 LSTM 模型预测多站点多元时间序列,例如 EMC 数据科学全球黑客马拉松数据集,非常感谢!
我在多站点预测方面有一些建议,请看这里
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
感谢分享。我发现使用 LSTM 进行时间序列预测的结果与原始序列滞后一步的结果相似。您怎么看?
听起来模型已经学会了一个持续性模型,可能没有技能。
我有一些问题?
如果我有一个 LSTM 模型,我想知道新预测的准确百分比。
如何为新预测获得准确百分比?
谢谢你
如果您的模型正在预测类别标签,您可以在 compile() 调用中将准确度指定为指标,然后使用 model.evaluate() 来计算准确度。
您可以在这篇博文中了解 MLP 如何做到这一点,这对于 LSTM 也是一样的
https://machinelearning.org.cn/tutorial-first-neural-network-python-keras/
非常感谢!我长期以来一直在阅读您的网站!
我有一个问题,在“使用 Keras 的 Python LSTM 循环神经网络进行时间序列预测”中,您提到
“LSTM 对输入数据的尺度很敏感,特别是当使用 sigmoid(默认)或 tanh 激活函数时。将数据重新缩放到 0-1 范围,也称为归一化,是一个好习惯。”
那为什么这里不归一化输入呢?
是因为您使用了 relu 吗?是因为数据是递增的(所以我们无法归一化未来的输入)?还是因为您只是给我们举个例子?
您建议在这里进行归一化吗?
使用归一化或类似方法预处理数据是一个好主意。
我选择不这样做,因为它似乎比有帮助更能让读者感到困惑。另外,ReLU 的选择确实使模型对未缩放的数据更加健壮。
感谢您的精彩文章。小错误或混淆
对于多变量序列中的多输入情况,如果我们使用三个时间步长和
10,15
20,25
30,35
作为我们的输入,那么输出(用于训练的预测值)应该是
85
而不是 65?
在所选问题的框架中,我们希望预测时间 t 的输出,而不是 t+1,给定直到且包括 t 的输入。
如果您愿意,您可以选择不同的问题框架。这是任意的。
您还可以参考“Multiple Parallel …”
所以您可以在函数 `split_sequences` 中找到差异
如果您想预测 85,您可以将代码更改为
if end_ix > len(sequences)-1
break
seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix, -1]
注意 `len(sequences)-1` 和 `sequences[end_ix, -1]`
非常非常感谢 Jason。
它帮助了我很多。
很高兴听到这个消息。
嗨,Jason,
感谢这篇很棒的博文!我是时间序列 LSTM 的新手,我需要您的帮助。
网上大部分信息是针对单个时间序列和下一步预测的。我想为 100 个不同的时间序列生成 6 个月以上的预测,每个时间序列的长度为 15 个月。所以,如果我们使用滑动窗口,每个时间序列有 34 个窗口。因此,我的初始 X_train 的形状是 (3400,15)。然后,我将 X_train [samples, timesteps, features] 重塑为:(3400, 15, 1)。这个重塑正确吗?一般来说,在多输入多步预测中,我们如何选择“timesteps”和“features”参数?
同样,我该如何选择“batch_size”和“units”?由于我想要 6 个月以上的预测,我的输出应该是一个维度为 (100,6) 的矩阵。我选择了 units=6,batch_size=1。这些数字正确吗?
Jason Brownlee 2018年12月12日 下午2:14 #
谢谢你的帮助!
看起来不错。
批次大小和单元数——同样,取决于您的问题。测试。6 个单元太少了。从 100 开始,尝试 500、1000 等。批次大小为 1 似乎太小了,也许也可以尝试 32、64 等。
John 2018年12月13日 上午2:06 #
告诉我进展如何。
嗨,Jason,
谢谢你的回复。
Jason Brownlee 2018年12月13日 上午7:55 #
然后通过增加 LSTM 单元的数量来极大地提高模型的容量。
Ravi Varma Injeti 2019年12月18日 上午12:55 #
Jason Brownlee 2019年12月18日 上午6:08 #
也许从这里开始
https://machinelearning.org.cn/start-here/#deep_learning_time_series
Jason Brownlee 2018年12月16日 上午5:23 #
Jenna Ma 2018年12月16日 下午4:24 #
你可以在这里了解更多
https://machinelearning.org.cn/develop-bidirectional-lstm-sequence-classification-python-keras/
model.add(LSTM(200, activation=’relu’, input_shape=(n_steps_in, n_features_in)))
model = Sequential()
model.add(RepeatVector(n_steps_out))
model.add(TimeDistributed(Dense(n_features_out)))
model.add(LSTM(200, activation=’relu’, return_sequences=True))
Jason Brownlee 2018年12月17日 上午6:19 #
model.compile(optimizer=’adam’, loss=’mse’)
Jenna Ma 2018年12月18日 下午1:50 #
在您教程的最后一部分,您举了一个类似这样的例子
然后,您介绍了编码器-解码器 LSTM 来建模这个问题。
[[10 15 25]
[20 25 45]
[30 35 65]]
[[ 40 45 85]
[ 50 55 105]]
如果我想将三个时间序列中的每个时间序列的最后三个时间步作为输入到模型,并预测第三个时间序列的未来两个时间步作为输出。也就是说,我的输入和输出元素如下。输入和输出的形状分别为 (5, 3, 3) 和 (5, 2, 1)。
在定义编码器-解码器 LSTM 模型时,代码将如下所示
[[10 15 25]
[20 25 45]
[30 35 65]]
[[85]
[105]]
model.add(LSTM(200, activation=’relu’, input_shape=(3,3)))
model = Sequential()
model.add(RepeatVector(2))
Jason Brownlee 2018年12月18日 下午2:36 #
model.add(LSTM(200, activation=’relu’, return_sequences=True))
model.add(TimeDistributed(Dense(1)))
model.compile(optimizer=’adam’, loss=’mse’)
这样对吗?
非常感谢!
Jenna Ma 2018年12月18日 下午6:05 #
谢谢!
我假设输入序列
in_seq1 = np.arange(10,1000,10)
in_seq2 = np.arange(15,1005,10)
定义预测输入
x_input = np.array([[960, 965, 1925], [970, 975, 1945], [980, 985, 1965]])
我期望的输出值如下
模型预测为:[ [1997.1425] [2026.6136] ]
[ [1985] [2005] ]
我认为这意味着模型可以工作。
Jason Brownlee 2018年12月19日 上午6:31 #
dani 2018年12月19日 下午12:55 #
Jason Brownlee 2018年12月19日 下午2:30 #
mk 2018年12月20日 下午7:13 #
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
Jason Brownlee 2018年12月21日 上午5:27 #
Lionel 2018年12月21日 下午6:16 #
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
我已构建了一个 LSTM 来预测下一个小时的能见度,仅基于能见度观测。(基本上,网络学会了持续性是一个好的算法。)
我的下一步是包含天气模型对湿度的预测。
因此,我作为输入有
机场的能见度观测(过去和现在)
未来 120 小时的湿度预测。
我难以结合这两种信息。
您有什么建议吗?
Jason Brownlee 2018年12月22日 上午6:03 #
Lionel 2018年12月22日 下午7:21 #
输入:过去 120 小时的测量能见度
未来 120 小时的天气预报
输出:未来 120 小时的能见度预测
每小时对未来 120 小时进行能见度预测
实现
我很难理解 LSTM 如何每小时更新其状态,因为它只会获得过去一小时的测量能见度作为新信息,而不是关于完整的 120 小时预测。
我必须说我是一名 ML 新手。
Jason Brownlee 2018年12月23日 上午6:04 #
Potofski 2018年12月22日 上午3:48 #
假设我有一个相关的时间序列(供暖成本和温度),我想预测相关的(供暖成本),我该如何将温度预测(来自其他天气预报)纳入我的模型中以预测供暖成本?
您知道任何常用方法吗?或者任何关于如何处理外部预测作为自变量的论文?
Jason Brownlee 2018年12月22日 上午6:07 #
Jenna Ma 2019年1月4日 下午9:35 #
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
嗨,Jason,
根据您的经验,‘relu’ 通常比 ‘tanh’ 工作得更好,是真的吗?如果您有任何关于激活函数的文章,请给我标题或 URL。
Jason Brownlee 2019年1月5日 上午6:55 #
非常感谢!
Jenna Ma 2019年1月7日 上午12:50 #
Jason Brownlee 2019年1月7日 上午6:37 #
Matt 2019年1月9日 上午3:21 #
您网站上的所有内容都很棒,我真的很感激。谢谢您。
Jason Brownlee 2019年1月9日 上午8:47 #
谢谢!
嗨,Jason,
1 个问题:您能否解释一下“多并行输入”示例中 `out_seq` 系列的用途?
Jason Brownlee 2019年1月10日 上午7:57 #
非常感谢,
安德鲁
Andrei 2020年2月20日 上午2:59 #
Jason Brownlee 2020年2月20日 上午6:19 #
sophia 2019年1月22日 上午8:29 #
也许我没有理解你的问题?
我将非常感谢您关于如何开发一个能够预测消费者‘购买什么’和‘何时购买’的 LSTM 模型的建议;
根据您的文章,选择正确的模型似乎是“多并行输入和多步输出”。您同意吗,还是您认为我应该选择不同的模型?任何指针或相关文章的链接都会有帮助!
Jason Brownlee 2019年1月22日 上午11:42 #
谢谢,
Raman 2019年1月22日 下午3:17 #
NameError: name ‘to_list’ is not defined
您能帮忙吗?我不确定我错过了什么。
Jason Brownlee 2019年1月23日 上午8:43 #
谢谢你的帮助
Raman 2019年1月23日 下午4:09 #
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
嗨,Jason,
已完成检查-
我遇到了一个错误,然后我按照 stack overflow 的建议将 keras 降级到了版本:2.1.5
我搜索了 stack overflow 和相关问题,甚至在那里发布了我的问题。
Jason Brownlee 2019年1月24日 上午6:38 #
感谢您的帮助。
Sarra 2019年1月30日 上午3:02 #
我试过了,但它不起作用
trainX, trainy = split_sequence(train, n_steps_in, n_steps_out)
# 分割成样本
testX, testy = split_sequence(test, n_steps_in, n_steps_out)
trainX = trainX.reshape((trainX.shape[0], trainX.shape[1], n_features))
# 重塑
testX = testX.reshape((testX.shape[0], testX.shape[1], n_features))
model.fit(trainX, trainy, epochs=5, verbose=2)
....
# 拟合模型
Jason Brownlee 2019年1月30日 上午8:14 #
# 进行预测
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# 计算均方根误差
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
print(‘训练得分: %.2f RMSE’ % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
print(‘测试得分: %.2f RMSE’ % (testScore))
非常感谢
Gunay 2019年2月6日 上午2:43 #
嗨,Jason,
Jason Brownlee 2019年2月6日 上午7:51 #
此致,
古奈
对于多变量多步,普通的或双向的 LSTM 并不适合。您可以强制使用它,但在输出中您将需要 n x m 个节点来表示 n 个时间步长和 m 个时间序列。在这个结构中,每个序列的时间步长将被展平。您必须在训练和预测过程中一致地将每个输出解释为特定序列的特定时间步长。
我没有示例,这不是一个理想的方法。
Gunay 2019年2月6日 下午7:27 #
谢谢!
Jason Brownlee 2019年2月7日 上午6:37 #
Tian 2019年2月10日 下午5:29 #
Jason Brownlee 2019年2月11日 上午7:56 #
Gunay 2019年2月15日 上午8:56 #
嗨,Jason,
Jason Brownlee 2019年2月15日 下午2:20 #
函数式 API 将帮助您设计此类模型。
Anirban 2019年2月15日 下午4:08 #
https://machinelearning.org.cn/keras-functional-api-deep-learning/
Jason Brownlee 2019年2月16日 上午6:13 #
这被称为多步预测,有很多示例,也许从这里开始
Aaron 2019年3月6日 下午2:47 #
https://machinelearning.org.cn/start-here/#deep_learning_time_series
我仍然难以理解的是如何真正塑造输入数据并使用 Tensorflow / Keras 获取序列输出。我希望预测未来 T 至 T+12 小时的序列,使用 T-1 至 T-48 小时的数据。所以,是从过去 48 小时预测未来 12 小时,以 1 小时为增量。每小时的数据在每个时间步都有十几个特征。根据我目前对您的了解,似乎每个过去的 48 个时间步都应该被视为时间步 T 的特征来预测未来 12 小时的序列 – 我的意思是,这看起来对吗?我也不太确定我应该使用什么模型……它将是一个多步、多输入的网络……只是对术语有些困惑,也许这就是为什么我难以弄清楚我需要做什么。
我还在看您的一些书,但我不确定哪本能最好地指导我完成这样的项目。
Aaron
谢谢,
Jason Brownlee 2019年3月6日 下午2:49 #
也许这会有帮助。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
然而,关于输出,查看 Keras 文档 https://keras.org.cn/layers/recurrent/,我试图获得一个返回序列。我应该使用 3D 张量吗?(batch_size, timesteps, units),其中它看起来像 (20, 12, 1)?因为我想为 20 个样本在每个时间步找到 1 个值。
Jason Brownlee 2019年3月7日 上午6:52 #
再次感谢!
Jason Brownlee 2019年3月6日 下午2:49 #
Aaron 2019年3月7日 上午10:05 #
https://machinelearning.org.cn/start-here/#lstm
model.add(LSTM(…, input_shape=(…)))
model = Sequential()
model.add(RepeatVector(…))
model.add(LSTM(…, return_sequences=True))
model.add(TimeDistributed(Dense(…)))
Jason Brownlee 2019年3月7日 下午2:32 #
最好使用更多的 LSTM 或 Dense 层来解释这些激活或最终激活,并使用单独的模型输出相同或不同长度的序列。
Gideon 2019年5月2日 上午6:10 #
你好,
我试图在我的最终层使用 Dense 层,正如您建议的那样,将 `n_steps_out` 作为参数传递。我正在预测 3 个变量,而 `n_steps_out` 是 10。
Keras 抱怨它期望 Dense 层有 2 个维度,但我传递给它的是形状为 (n_samples,n_steps_out,n_features) 的数组。
您能帮我理解一下吗?
Jason Brownlee 2019年5月2日 上午8:09 #
谢谢你
Abderrahim 2019年3月15日 下午5:20 #
嗨,Jason,
我训练了一个 LSTM 到 CNN 模型,该模型作用于有序图像,以预测时间序列。在测试集中,我拥有按时间顺序排列的有序图像集。我认为这里没有预测范围的概念,我该如何改进我的模型,以及在这种情况下预测测试集的起点是什么?
Jason Brownlee 2019年3月16日 上午7:48 #
非常感谢。
Tayson 2019年3月26日 上午12:06 #
你好 Jason,
我尝试复制“多并行输入和多步输出”的代码并完全相同地运行,没有任何更改,但我得到了与您不同的结果。
有什么原因吗?
[ [
[147.56306 167.8626 312.92883]
[185.38152 205.36024 385.96536] ] ]
Tayson
此致,
Jason Brownlee 2019年3月26日 上午8:08 #
Chris 2019年3月26日 上午1:27 #
https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code
嗨,Jason,
看起来这个模型假定了规律的时间间隔。
您可以将“缺失”的日期用零填充,或者用最后 3 个值的平均值来填充,但我想知道如何在不填充/插补时间序列数据的情况下制作 LSTM 模型。您会如何处理这个问题?
谢谢,课程很棒。
Jason Brownlee 2019年3月26日 上午8:10 #
– 按原样建模
– 用填充物规范化间隔
– 上采样/下采样到新间隔
neb 2019年8月21日 上午7:17 #
– 等等。
保持特征数量恒定
上述各种模型的组合能否应对每个样本的时间步长可变的情况?
或者底层模型的假设会以某种方式失效?
Jason Brownlee 2019年8月21日 下午1:57 #
Ron 2019年3月27日 上午1:06 #
Jason Brownlee 2019年3月27日 上午9:05 #
对于给定的数据集,会有一个最佳点。
Ron 2019年3月27日 下午1:16 #
Jason Brownlee 2019年3月27日 下午2:07 #
Peter 2019年3月28日 上午5:57 #
嗨,Jason,
所以基本上输出向量是 [y_high, y_low],模型工作得非常好,但它有时会输出 `y_low` > `y_high`,这当然没有意义,有没有办法强制模型使 `y_high` >= `y_low` 的条件始终满足?
model.add(Dense(2, activation=’linear’))
Jason Brownlee 2019年3月28日 上午8:24 #
Peter 2019年3月29日 上午3:00 #
Jason Brownlee 2019年3月29日 上午8:42 #
Joe 2019年3月29日 上午2:43 #
https://towardsdatascience.com/interpretable-machine-learning-with-xgboost-9ec80d148d27
令人着迷的是,Scott L. 在此处展示了 SHAP 值在 LSTM 模型中的应用
https://slundberg.github.io/shap/notebooks/deep_explainer/Keras%20LSTM%20for%20IMDB%20Sentiment%20Classification.html
但那使用的是文本输入(IMDB 数据集的情感分类),它在 LSTM 层之前有一个 Embedding 层。对于非文本问题,如时间序列预测,我们将排除 Embedding 层。但这会破坏代码。
您是否有任何关于如何在 LSTM 模型用于时间序列预测(非文本处理)的上下文中使用的 SHAP 值的建议?如果没有,您是否有该上下文中的特征选择建议?
Jason Brownlee 2019年3月29日 上午8:42 #
谢谢!
Sam 2020年4月14日 下午6:31 #
Hsin 2019年3月29日 下午5:26 #
嗨,Jason,
我对于在将其分割为
x(data_length, n_step, feature)
之后如何进行反向缩放感到困惑
因为 scaler 只能在 2D 条件下使用。
我想评估预测值和真实值之间的rmse,所以必须
反转数据转换。您能告诉我如何处理这个问题吗?
是的,我在这里展示了如何操作
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
嗨,Jason,
首先,我必须说您有很多关于ML/DL的出色文章。感谢您对广大社区的帮助。
说到LSTM,我被一个问题困扰了好几天。情况如下——
我有三列,分别是customer id、basket_index和timestamp。对于每个客户,每一行代表一个时间戳。假设有3个客户,时间戳各不相同。第一个有30个时间戳,第二个有25个,第三个有50个。因此,总行数为105。现在对于basket_index列,每一行表示在特定时间戳上任何客户购买的产品密钥列表。这是数据集的快照——
CustomerID basket_index timestamp predicted_basket
111 [1,2,3] 1 [4,5]
111 [4,5] 2 [9,7]
111 [9,7] 3 [3,5,6,1]
.
.
222 [6,2,3] 1 [1,0,2,5]
222 [1,0,2,5] 2 [7,5]
.
.
333
.
. 以此类推..
现在,由于每个客户都有不同的时间序列,
1) 如何将所有内容传递到一个网络中?
2) 在这种情况下,我是否必须构建多个LSTM模型(每个客户一个)?
3) 另外,我正在为客户和产品密钥(取每个购物篮的平均值)创建嵌入层。在这种情况下,如何指定每个时间序列回溯多少步?
4) 在这种情况下,我应该如何指定批量大小?
您的帮助将不胜感激。谢谢!
好问题,我这里有一些建议可能会有帮助
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
总的来说,我鼓励您尝试跨客户学习。
谢谢Jason的精彩文章。
一个问题希望得到您的指导:对于LSTM工作,我们不能止步于说模型很好,但最重要的是如何使用好的模型结果。
例如,患者是否有流感。现在我想预测未来半年(2019年6月至2019年12月)的流感,但我拥有的是历史数据(过去4年的流感数据,模型目标是2018年6月1日至2018年12月31日)。
如何将历史LSTM结果应用于未来预测?
我能否从历史模型中获取重要特征列表并附带一些值(例如权重),然后将其应用于我的未来数据?
或者我能否从一个拟合良好的LSTM模型中获取重要特征列表,并且这些特征比其他特征更重要?
感谢您的指导!
这是我在这里回答的一个常见问题
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
嗨,Jason,
太棒了!感谢分享您的知识,这个教程非常有帮助。
我是ML/DL新手,我正在尝试使用LSTM来预测公司未来六个月的销售额。但我有一个问题,我不确定如何仅使用一个x向量作为输入来从您的代码中获得超过1个的下一步。我使用的是月度时间步长
您能否帮助我更好地理解如何实现它?
有很多多步预测的例子,包括上面教程中的例子。
这里也有更多例子
https://machinelearning.org.cn/start-here/#deep_learning_time_series
尊敬的先生,
感谢您的分享示例。我收集了交通信息,如(道路属性、天气、日期时间、相邻道路速度、目标道路速度等)来预测道路速度。目前,我已准备好使用Vanilla LSTM模型进行单步和多步预测的代码。您能否为我建议以下哪个模型最适合道路速度预测并具有更高的准确性?
模型是
数据准备
标准 LSTM
堆叠 LSTM
双向 LSTM
CNN LSTM
ConvLSTM
我正在等待您的回复。
谢谢,
阿扎德
我建议测试一系列模型类型和模型配置,以发现最适合您特定数据集的方法,您可以了解更多信息
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
您好Jason,我正在使用vanilla LSTM进行预测,并希望使用此代码预测未来10天
# Forecast real future
# Number of desired forecast in the future
L=10
#creat inputs and output empty matrices for future forecasting
Future_input=np.zeros((L,3))
Future=np.zeros((L,1))
#add last 3 forecast as input for forecasting next day (tommorow)
Future_input[0,:]=[predict[-3],predict[-2],predict[-1]]
#create 3 dimension input for LSTM inputs
Future_input= np.reshape(Future_input,(Future_input.shape[0],1,Future_input.shape[1]))
#predict tommorrow value
Future[0,0]=model.predict(np.expand_dims(Future_input[0],axis=0))
#Loop to predict next 9 days values
for i in range (0,9)
Future_input[i+1,0,:]=np.roll(Future_input[i,0,:], -1, axis=0)
Future_input[i+1,0,2]=Future[i,0]
Future[i+1,0]=model.predict(np.expand_dims(Future_input[i],axis=0))
#print 10 day ahead values
print(Future)
可以这样吗?
抱歉,我无法调试您的代码。
如果您需要更多关于多步预测的帮助,请参阅此
https://machinelearning.org.cn/faq/single-faq/how-do-you-use-lstms-for-multi-step-time-series-forecasting
您好,您是否有关于将单变量ConvLSTM应用于二维时空数据的技巧?我正在尝试输入55x55图像的10个时间步长来进行单步时间序列预测。
出现以下错误代码
“ValueError: Error when checking target: expected dense_10 to have 2 dimensions, but got array with shape (10, 55, 55)”
抱歉,我没有关于该主题的教程。
尊敬的先生,
我有一个包含1247个数据点的序列,我想预测接下来的30个,那么数据将是1277个。
我遵循了这个教程,但它只能预测1或2次。然后我遵循了这个教程
https://machinelearning.org.cn/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/
但我有些困惑。您对我有什么建议吗?
这实际上是股票价格数据。
股价是不可预测的
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
精彩的教程,谢谢。
我有一个问题,是否存在一种模型,其输出可以相互影响?
也就是说,您拥有多个独立的序列,但它们可以相互影响?
谢谢你
谢谢。
是的,编码器-解码器模型可能是一种方法,它能够协同输出每个序列的时间步。
太棒了。一如既往的出色解释。我一直对输入Keras模型的数据形状感到沮丧和困惑。所以,我依靠您的教程来弄清楚。
总之,我使用了您的例子来演示LSTM在预测简单二维弹道计算中的应用。我使用了您的代码来帮助我完成这项工作。
https://github.com/JulesVerny/BallisticsRNNPredictions
Pygame需要用来制作动画模拟
做得好,您的项目非常酷!
尊敬的教授,
想象一下,我有一个只包含单词“N1,N2,N3,………….,N1000”的原始文本,格式是打乱的,也就是说,有100万个单词,每个单词都可能属于这1000个单词中的任何一个。
我想选择时间步数=5,然后预测下一个单词。
例如:输入[N1,N6,N5,N88,N32]后面会跟着“N73”。
现在,假设我已经将所有1000个可能的单词都标记化为数字。
这是一个有1000个可能输出类别的场景。
那么我应该用`model.add(Dense(1000,activation='softmax'))`替换`model.add(Dense(1))`吗?
如果不是,与您的单变量堆叠LSTM代码相比,主要变化是什么?
如果单词被打乱了,那么模型就没有结构可供学习了。
亲爱的 Jason!
我正在尝试为这个问题使用堆叠LSTM——多并行输入和多步输出。
但是我不确定最后的Dense层应该是什么样子。您能给我一些提示吗?
也许可以从上面文章中的示例开始,然后添加一个额外的LSTM层?
您指的是哪个示例?我找不到任何关于多并行输入和多步输出LSTM的示例,它使用的是堆叠LSTM层而不是编码器-解码器。
是的,在“多变量多步LSTM模型”部分。
特别是“多并行输入和多步输出”子部分。
示例可以适应使用您想要的任何模型。
感谢Jason的详细解释。
您能否告诉我如何在LSTM编译或拟合方法中添加用于调整“遗忘门”、“输入门”和“输出门”的超参数,或者它是内部完成的,我们无法控制这些门?
它们没有被调整。
如何预测多个此类输入,x_input = array([[70,75,145], [80,85,165], [90,95,185],…,[200,205,405]]),期望下一个输出,[210,215,425],
请看文章中的输入,x_input = array([[70,75,145], [80,85,165], [90,95,185]]),预测结果,[[101.76599 108.730484 206.63577 ]],但它似乎与您需要输入这样的序列无关。in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]),in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95])
谢谢
我相信上面列出的几个多时间步模型将为您提供一个良好的起点。
嗨,Jason,
感谢这篇文章。
我一直在研究您的代码,并计划在我的工作中实施它,但我注意到了一种不同的行为。如果我编译并运行代码几次,每次都会得到不同的结果,尽管我没有更改您的代码中的任何内容。我用您的示例数据试运行了几次,每次都得到了不同的结果。我用我自己的数据集试过了,结果也是一样。
现在我对在我的工作中实现LSTM感到困惑。
您能澄清一下这种行为吗?
是的,这是预料之中的。您可以在这里了解更多信息
https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code
你好 jason,
假设我们有3个变量(X)和1个因变量(Y)。
X中2个变量的关系是3个滞后,而1个变量是30个滞后。
在这种情况下,您有什么建模建议?
我有许多示例,包括上面的一些示例。
我还有一个教程可能有助于作为起点
https://machinelearning.org.cn/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/
嗨,Jason,
感谢您提供如此信息丰富的教程。您能否更详细地说明如何为预测值提供置信区间?
您是指预测区间而不是置信区间吗?
也许从这里开始
https://machinelearning.org.cn/prediction-intervals-for-machine-learning/
嗨 Jason
感谢您的有用教程
您能否告诉我如何预测我们没有其可用数据值的未来?
例如,我最终确定了我的LSTM模型,我该如何预测2050年的值?
是的,我在这篇文章中展示了如何做
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
感谢文章。但是,我有一个问题,就是每次预测结果都不同,例如多个并行序列。第一次是[[101.25582 106.49429 207.8928 ]],第二次变成了[[101.82945 107.527626 209.8016 ]]。为什么会这样?
谢谢
这是我在这里回答的一个常见问题
https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code
我建议您尝试运行示例几次。
我想重申我的问题……
假设我们正在模拟一个水桶,顶部有一个开放的进水口,侧面有两个出水口,一个靠近顶部,一个靠近底部。
这将意味着顶部的出水口可以在水非常好的时候释放……
靠近底部的出水口的释放是其上方水量的指数函数。
现在,假设这些系统是并行的(一个在另一个之上,例如2个)和串联的(例如2个,每个并行系列的最终出水口连接到最终输出)。 (总共4个水桶)。
这可以用LSTM建模吗?
我已经用解析方法做过了……结果还可以。
正在尝试使用LSTM来完成这项工作……
也许可以。
您可以使用此框架来探索您问题的不同表述。
https://machinelearning.org.cn/how-to-define-your-machine-learning-problem/
你好 Jason,
到步骤
# 定义输入序列
in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95])
我想问一下如何从数据集中加载一整列。
我不想插入每个值,因为我有超过2200万行。之后,我想将其拆分为200-400个时间步的序列。
到步骤
out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
我没有正确的数学方程。我想在不知道输入信号之间关系的情况下预测输出。
希望您能帮助我。
诚挚的问候
阿里
我有很多例子,也许可以从这里开始
https://machinelearning.org.cn/start-here/#deep_learning_time_series
嗨,Jason,
感谢这些解释和示例代码!
我对您提供的多变量LSTM示例很感兴趣。您提供了一个简单的加法案例示例。如何将其扩展到有多个输入但输入之间没有确切关系,尽管已知输入是相关的?非常感谢您的指导!
模型将学习关系,加法只是为了演示。
谢谢Jason!太好了。
那样的话,“out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])”这句话应该替换成什么,因为我们不知道变量之间的确切关系?再次感谢!
多个输入时间序列的观测值根据其观测时间与时间步长对齐。
也许这会使事情更清楚
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
谢谢Jason。我将阅读该链接上的内容。
祝好,
Sree。
你好,再次感谢。我认为我之前的问题可以更清楚一些。
我想使用向量输出方法来实现MIMO LSTM,进行多步未来预测,类似于您的编码器/解码器示例。
我尝试使用编码器/解码器示例中的split_sequences方法与向量输出示例,但维度不匹配。我最终得到一个值错误。
ValueError: Error when checking target: expected dense_2 to have 2 dimensions, but got array with shape (5, 2, 3)
我非常感谢您的帮助,我为此苦苦挣扎了很久。我想输出应该是一个矩阵(特征数X预测范围),所以我认为我有一些概念上的东西没有理解。
谢谢,也感谢您提供的所有精彩教程
Gideon
也许可以从您想要使用的代码示例开始,然后慢慢根据您的需求进行更改。
如果数据大小与模型的期望不匹配,则需要更改数据形状或更改模型的期望。
我会再努力一下,但我想确保有可能为多并行输入和多步输出LSTM在Keras中使用密集层/向量输出方法。
再次感谢您的时间。
Gideon
可以使用Dense进行多步多元输出,而无需解码器或TimeDistributed包装层,只是有点丑陋。
例如,输出将是一个n x m个节点的向量,其中n是变量数,m是步数。
我已经解决了,而且一点也不丑陋,而且正是我所需要的。我不知道Keras中的Reshape层。
from keras.layers import Reshape
…
model.add(Dense(n_steps_out*n_features))
model.add(Reshape((n_steps_out,n_features)))
再次感谢您的帮助。我现在就买您的书。
谢谢
Gideon
干得不错。
你好Gideon,
我一直在为类似的事情挣扎,并应用了您的解决方案,解决了所有问题!您是否有更多关于此的文档?
你好 Jason,
很棒的文章,非常有帮助。我想使用LSTM预测未来12小时的太阳辐照度,使用过去24小时的8个特征(包括太阳辐照度)作为输入。因此,这将是一个多变量多步LSTM,输出是一个12个时间步长的序列。我有8年的数据,我想用前6年进行训练,后2年进行测试。我有一些问题。
1) 我应该重叠输入序列吗?
2) 我应该使用向量输出模型还是编码器-解码器模型?
我建议测试这两种方法,并使用数据来做决定,例如,选择结果最好的模型。
你好杰森,
这篇文章非常有帮助。
您能否告诉我,如果我的数据集中有两列,我应该采取哪种方法。
一个是ddmmyyyy格式的时间,另一个是股票价格。
我有过去12个月的数据。
我想预测未来4个月的股票价格。
我该怎么做。
还有一个疑问是,如果时间列之间的时间间隔不一致,那么我是否应该为预测未来4个月的股票价格做些什么或考虑什么?
如果所有观测值都具有一致的间隔,则可以删除日期列。
股价是不可预测的
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
无论如何,我建议使用此过程
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
因此,在删除日期列后,我认为我必须选择一个单变量多步LSTM模型。对吗?
当季节性出现时,应该怎么做?
另外一个疑问是,当我预测未来四个月时,模型在预测第四个月时会考虑第三个月的预测值,还是模型在预测第三个月时会考虑第二个月的预测值,以此类推?
尝试一系列模型,并与线性模型或朴素模型进行比较,以确认它们是否具有技能。
如果您有季节性,请尝试对其进行建模和不进行季节性建模,并比较性能。
尝试多种多步预测方法,例如直接预测、递归预测等。
https://machinelearning.org.cn/multi-step-time-series-forecasting/
如果您有季节性,请尝试对其进行建模和不进行季节性建模,并比较性能。
这是什么意思?我没明白
如果我的原始数据集有季节性,我的训练数据将包含季节性,对吗?
我将如何创建一个没有季节性的模型?
LSTM是否有用于季节性的额外参数或特征?
您可以通过季节性差分从数据集中删除季节性。
https://machinelearning.org.cn/remove-trends-seasonality-difference-transform-python/
在多个输入系列中,
(7, 3, 2) (7,)
[[10 15]
[20 25]
[30 35]] 65
[[20 25]
[30 35]
[40 45]] 85
[[30 35]
[40 45]
[50 55]] 105
[[40 45]
[50 55]
[60 65]] 125
[[50 55]
[60 65]
[70 75]] 145
[[60 65]
[70 75]
[80 85]] 165
[[70 75]
[80 85]
[90 95]] 185
1.此示例(x=7)中有多少个LSTM块?
如果批量大小=3,那么LSTM块的数量是否等于批次中x的数量?
还是时间步长?
2.时间步长、神经元和批量大小都是超参数吗?我们如何优化它们?
不,第一隐藏层的块数与输入序列的长度无关。
看这里
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
谢谢……
那么LSTM块的总数是多少?
对于每个 epoch,权重是否会重新初始化,状态是否会被重置?
LSTM单元的数量在每个隐藏的LSTM层中指定。
LSTM状态在每个批次结束时重置。
抱歉,我没明白
在model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features)))中
这里的input_shape等于每个LSTM节点的输入,对吗?
这里的50是什么意思……h(隐藏层)是一个50*1的向量,对吗?
我的问题是,单个LSTM节点(块)的数量是否等于批次中的样本数量?
是的,形状定义了每个输入样本的形状(时间步长和特征)。
是的,50是指第一个隐藏层的单元数。
单元数和样本形状都与批量大小无关。除非您使用的是有状态LSTM,在这种情况下,输入形状还必须指定批量大小。
这有帮助吗?
是的……还有一个后续问题
[10 15]
[20 25]
[30 35]] 65
这里是多对一吗?
这是否作为xt(单个输入)输入?
在这种情况下,权值的大小是多少?
是的,多元多步输入到一个输出。
这个输入是如何与隐藏层连接的……我无法可视化这一点。
我以为输入是一个向量[n*1]
隐藏层中的每个节点都会获得完整的输入序列。
非常感谢你……
[10 15]
[20 25]
[30 35]] 65
那么在这种情况下……xt和权重矩阵的大小是多少?
您可以根据网络中的节点数进行计算。
谢谢Jason……您真好心和乐于助人……
单元的数量等于固定时间步的数量。
博客是这样说的。我对单元数量以及控制它的因素感到非常困惑。
https://stackoverflow.com/questions/37901047/what-is-num-units-in-tensorflow-basiclstmcell#39440218
抱歉打扰您了
在Keras实现中不是。
亲爱的 Jason,
感谢您撰写所有这些很棒的教程!
我的问题
据我理解,LSTM网络通过反向传播来学习时间序列中的信息,反向传播的长度是LSTM单元在训练期间展开的特定长度。
因此,在训练期间,有必要定义训练数据中提供的时间步数。但是,(训练好的)网络在使用任意数量的输入时间步长进行预测时,不应该能够做到这一点吗(因为LSTM单元的工作方式是递归的)?
我从一开始就有什么地方理解错了?
感谢您的提示
Philipp
亲爱的 Jason,
我目前正在研究疾病爆发预测模型。我有4年的数据,有100多个输入变量,每年的数据点有365个。我想创建一个LSTM模型,能够根据给定的输入变量来预测未来的爆发(是否会爆发-1或不爆发-0)。例如,给定7天的数据点,我想预测第8天的爆发情况(0或1)。
但是,我不确定哪种LSTM模型最适合我的情况。“多输入多步输出”是否是最佳方法?非常感谢您的指导。
谢谢你
也许您可以将其建模为时间序列分类问题。
这里的教程将帮助您入门
https://machinelearning.org.cn/start-here/#deep_learning_time_series
嗨,Jason,
您能否提供一些有助于我们在模型拟合期间最小化步长损失的提示……
谢谢
是的,这里有一些建议
https://machinelearning.org.cn/start-here/#better
亲爱的 Jason,
感谢您的教程。它们对我们非常有用。
我有一个关于LSTM的问题。我有不同的时间序列(例如100个)。我需要用100个不同的时间序列训练网络,并测试10个不同的时间序列。我应该使用哪种方法?
感谢您的帮助。
我推荐这个过程
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
嗨,Jason,
感谢分享。我想知道是否有一种方法可以设置时间步长> 1而不进行子序列采样,就像您在数据准备中所做的那样,例如将一个9x1的时间序列转换为一个6x3的数据集。转换后,3个特征的数据集不再依赖于时间。您可以使用任何ML模型(如OLS)来预测y。那么为什么是LSTM呢?LSTM是否应该能够在没有这种转换的情况下选择(遗忘)先前的信息?
LSTM的优点在于它可以跨样本记忆。
这可能有用,也可能没用,而且对于简单的自回归模型来说通常没用。
感谢您的快速回复。在您的示例中,如果我进行子序列采样并转换
[10, 20, 30, 40, 50, 60, 70, 80, 90]为
[[10, 20, 30],
[40, 50, 60],
[70, 80, 90]](每个子序列之间无替换)
并运行LSTM(input_shape=(3,1)),这是否与我在原始时间序列(9x1)上运行LSTM(batch_input_shape=(3,1,1), stateful=True)相同?
不,因为每个“样本”都会导致模型输出,例如,1个样本有3个时间步长,而3个样本有1个时间步长。
关于样本与时间步长的更多信息
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
谢谢你,Jason!
不客气。
对于分类LSTM,使用Seed我每次运行都能得到相同的分类矩阵。但是,当我改变model.predict中的批量大小时,我得到以下结果。
Prediction Batch Sizes
32 = 每次重复都有不同的分类矩阵
预测中的批量大小仅仅是为了内存管理。对吗?如果是,Jason博士您认为是什么原因导致了这些不规则性?
不,批量大小会影响学习算法。
https://machinelearning.org.cn/how-to-control-the-speed-and-stability-of-training-neural-networks-with-gradient-descent-batch-size/
嗨,Jason,
抱歉,我解释得不够清楚。我指的是“model.predict i.e. predicting”中的批量大小参数,而不是训练时的。我同意训练时的批量大小会产生影响。在预测时,默认大小是keras定义的32,但当我将其更改为非32的任何值时,即使使用种子,我也会得到不同的分类矩阵。当我保留默认的批量大小时,我的种子能够产生相同的结果。
请记住,对于LSTM,状态在每个批次结束时重置。这解释了为什么您在相同的模型上使用不同的推理批量大小会得到不同的结果。
嗨,Jason,
谢谢您的教程。
我想将此示例应用于实际案例。
我必须预测一个ATM组每天将提取多少钱。
目前我为每个ATM使用一个时间序列。(100个ATM = 100个时间序列)。
您认为本教程中的哪种方法可能更好?
我需要使用历史信息和外部信息,如节假日、星期几等。
提前感谢。
我建议遵循此框架。
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
您好Jason,我想使用某种机器学习方法来证明两支篮球队的比分差距与体育场外出租车需求之间存在关系。
我有一个体育场附近出租车接载的时间序列。我有一个两支篮球队之间的比分差距时间序列。
我想实现的是训练一个机器学习模型,该模型可以告诉我,根据时间t的出租车接载量,预测时间t+1的出租车接载量。
我还想看看,如果我有时间t的比分差距,我是否可以提高时间t+1接载量的预测准确性。
我应该使用哪种机器学习模型?
非常感谢!
为什么不直接测量观测值之间的统计相关性呢?
https://machinelearning.org.cn/how-to-use-correlation-to-understand-the-relationship-between-variables/
非常感谢您的回复!
是的,这可以用来寻找关系。
但是,如果我想预测t+1时的接载量,LSTM或ARIMA可以完成这项工作吗?
是的,但也许可以测试一系列方法,并发现最适合您特定数据集的方法。
嗨,Jason,
谢谢您的教程。
假设我有几条时间序列显示了去年不同火车的累计预订量。我不想预测,只想对这些时间序列进行分类,看看其中一些是否具有相似的模式。我能否将所有这些序列包含到一个LSTM模型中?这样做有什么风险吗?
提前感谢。
当然,这意味着您正在跨预订学习/建模。听起来很合理。
谢谢 Jason!
那么这是否与多变量LSTM相同?抱歉,我还是模型新手,所以仍然觉得有些东西很令人困惑。
可能不是,每个示例都是模型学习的独立样本或输入-输出对。
嗨,Jason,
感谢您的精彩教程!
我有一个数据集,其中包含3000个单变量时间序列(即3000个样本),每个样本有4000个时间步长。当我使用[samples, time steps, features]=[3000, 4000, 1]时,代码运行极其缓慢且性能很差。
另一方面,如果我使用[3000, 1, 4000]而不是[3000, 4000, 1],代码运行速度非常快,并且性能很好。
但是,reshape [3000, 1, 4000]是否正确?我的意思是,根据规则[samples, time steps, features],并且考虑到我的每个样本有4000个时间步长,并且每个时间步长有一个特征,正确的应该是[3000, 4000, 1]。
那么[3000, 1, 4000]是正确的吗?如果不是(逻辑上不是),为什么它的效果比[3000, 4000, 1]好得多?
提前感谢
我建议每个样本使用不超过200到400个时间步长。也许您可以截断数据?
我也做了一个实验,我截断了我的数据并使用了输入[samples, time steps, features]=[3000, 400, 1]。它更快,但我的平均准确率是42%(在10次随机分割中)。
正如我在上一篇文章中告诉您的,当我交换时间步长和特征时,也就是说,当我使用[3000, 1, 4000]时,我的准确率是90%。
但是提供1个时间步长意味着我没有利用LSTM的内存特性?
我对我是否应该使用[3000, 1, 4000],它非常快并且结果非常好,但可能不太正确?或者它是正确的,就像我使用[3000, 400, 1](如果我将数据截断到400)一样正确?
默认情况下,LSTM的状态在每个批次结束时重置,因此您可以获得一些跨样本内存。
我建议测试一系列不同的配置,看看哪种最适合您的特定数据集。我不知道什么会起作用,您必须自己发现答案。
你好 Jason,
我对ML和LSTM相当陌生。我有一个场景,我打算使用我的每小时传感器值来训练模型。例如:
12-1-2019 12:00:00 12
12-1-2019 13:00:00 16
…
12-5-2019 12:00:00 14
完成训练后,我打算每小时预测一次值,并将这些值与实时传感器值进行比较……我正计划使用LSTM,您推荐哪种方法?
我推荐这个框架
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
Jason,这非常有帮助。我正在尝试对IT事件做一些预测。根据历史数据,我想预测下个月/下周/明天的事件类型。您是否做过类似的事情,如果有,请分享?
也许您可以将其建模为时间序列分类,例如,预测此时间间隔内的事件。
这里的教程可能有助于作为起点。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
嗨,Jason,
感谢您在我的其他教程中回答我的问题。我有一个小疑问,假设我的数据包含连续时间序列(非平稳)以及其他分类变量(已编码)。在这种情况下,差分数据有什么最佳方法?因为分类数据不能差分,但必须在训练模型时使用它们。
上面写的函数会对所有变量进行差分,而不管它们是连续的还是分类的。如果您能帮助我,那将是很好的。
仅对实值进行差分,并且仅在它们非平稳时进行。
嗨,Jason,
我复制并粘贴了您在“多步LSTM模型”部分中的第一个示例,即输出为两个值且输入为一个值的向量输出。
您报告的输出值为
input [[70 80 90]]
output [[100.98096 113.28924]]
但是使用这些参数,我得到的结果不能接近
input [[70 80 90]]
output [[122.678955 139.9465 ]]
您是否使用了您报告的参数?这是否如此依赖于架构?
结果取决于模型、模型配置和数据,性能也是随机的,受随机方差的影响。
您好,感谢您的回复。
我明白了,所以我要问的是,
我使用相同的模型、相同的模型配置、相同的数据,并且随机性应该对称分布(?)。那么我认为您报告的结果不是来自代码示例中的参数。
我的数据是非平稳的,并且每7天有季节性(正如ADF检验和ETS图所示),并且一阶差分使其平稳。
我完全明白我只能对实值进行差分,这也是我一直以来的目标。但是,我问这个问题是因为一旦我对实值进行差分,它就会移动一位,所以如果原始数据有100个观测值,那么差分数据将有99个观测值(通过一阶差分)。但是不能差分的分类数据保持不变,仍然是100个。我该如何处理这个问题?
您丢弃第一个观测值,并且差值将对应于同一时间步长的分类值。
我认为我已经解决了这个问题,感谢Jason解决了我的疑问。
很高兴听到这个消息。
在向量输出模型部分,
我复制了您的代码并尝试了,但实际答案不正确,与预期的[100, 110]不同,它们实际上是[110, 120]。
也许可以尝试多次运行示例?由于学习算法的随机性,它可能会有所不同。
我尝试了很多次,但从未得到接近[100, 110]的结果。结果总是接近[110, 120],但略有不同。
不开玩笑🙂您可以尝试那部分代码。输出看起来很荒谬。
有意思。
Keras/TensorFlow/Python是否已更新?
你好Jason,我正在做一个电力需求预测,并试图建立一个模型,该模型可以根据过去90小时的数据预测未来24小时的需求。我已经实现了两种类型:一种是24步预测,另一种是递归定义的预测,它预测下一小时,然后使用前89个真实值和新预测值来预测下一个值,依此类推。我想知道你认为哪种方法最好(如果适用的话),以及有没有什么改进模型的建议,因为根据一年中的不同时间,预测的准确性可能会有很大差异。目前,我为两种情况都使用了连接到Dense(20)的LSTM(50),最后连接到输出Dense(1)。
任何帮助都将不胜感激。谢谢。Matthew
干得好,非常棒!
我建议测试每种方法,并使用误差最低的方法。
另外,发挥创意,测试一套其他的配置。确保你的测试框架坚固可靠,这样你才能信任你所做的决定。
你好,这个例子很容易遵循,而且比其他LSTM例子简单一些,因为它没有预处理转换(归一化、标准化、使数据平稳等)。但是,我一般应该为时间序列预测执行这些预处理转换吗?即使数据集很简单,我也应该为这类例子这样做吗?
是的,测试一下数据准备是否能提高模型性能。
为了简洁起见,我没有在示例中包含它。
#在多个并行序列中
我定义了输入如下
# 定义输入序列
in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95])
x_input = array([[70,75,1,4], [80,85,165,5], [90,95,185,6]])
n_steps=4
n_features=X.shape[2]
输入是如何循环以获得如下输出的:[[ 72.74373 106.51455 251.78499]]?
你能否清楚地解释一下n_steps=4, n_features=X.shape[2]到底是什么意思以及它是如何工作的?
是的,也许这会帮助你理解输入形状
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
请问,有没有一种方法可以找到ANN模型(LSTM、MLP)的正确参数(隐藏层数量、激活函数、损失函数等)?
当我的训练和验证损失曲线平行时,训练得分和测试得分都很小时,这是什么意思?
有没有一种方法可以优化所有这些结果?
是的,请看这篇文章
https://machinelearning.org.cn/faq/single-faq/how-many-layers-and-nodes-do-i-need-in-my-neural-network
感谢您的教程。我已将多步、多变量逻辑应用于我自己的数据集。特别是,我有12个look-back,12个look-ahead和41个特征(所有特征都具有与主要感兴趣变量完全相同的look-back)。尝试TimeDistributed代码片段导致我的RMSE逐渐增加。这是由于我的时间序列的性质,还是模型构建过程中出现的错误的迹象?您可能很难判断,但也许您可以分享您对此问题的看法。谢谢。
两者都有可能。
也许可以尝试减少特征数量并评估影响?
也许可以尝试不同的模型并评估影响?
我尝试了编码器-解码器和堆叠LSTM。两者都给我进一步预测未来时RMSE增加。对于编码器-解码器来说这是可以理解的,因为它使用输出作为输入(因此相关的误差也随预测而来并随着时间累积),但不确定为什么我看到堆叠LSTM也有同样的情况。总之,再次感谢您的回复和博文!
另外,一个快速的相关问题。您在多步未来多变量split_sequence模型中使用“-1”(例如n_steps_out-1等)。这与上面分享的其他multistep split_sequence代码相比,将结果特征的数量减少了一个。我不确定,但我们应该拥有相同数量的特征吗?谢谢。
谢谢。
恭喜取得进步!
先生,请!推荐我一些关于我的项目(使用LSTM预测碳排放)的学习资源。
从这里开始
https://machinelearning.org.cn/start-here/#deep_learning_time_series
感谢您提供的精彩教程。能否请您提供预测的概率(百分比)或第二个最佳预测?谢谢)
是的,model.predict()将在分类任务上返回概率。
更多细节在此
https://machinelearning.org.cn/how-to-make-classification-and-regression-predictions-for-deep-learning-models-in-keras/
嗨,Jason
您的教程对我帮助很大,非常感谢!
我有一个问题,如何在您上面提到的CNN-LSTM代码中调整LSTM网络的学习率。
期待您的回复,谢谢!
(我在https://machinelearning.org.cn/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/?unapproved=494293&moderation-hash=2b6d045a4e1ff047d0720753b2b1e418#comment-494293留的回复放错了位置,抱歉)
你可以在这里了解更多关于如何调整学习率(一般而言)
https://machinelearning.org.cn/understand-the-dynamics-of-learning-rate-on-deep-learning-neural-networks/
这太棒了。我喜欢这个博客
谢谢Luis。
感谢这个精彩的解释。
我在为多输出架构重塑数据时遇到了一个问题。
架构是
outputs=[]
main_input = Input(shape= (seq_length,feature_cnt), name=’main_input’)
lstm = LSTM(32,return_sequences=True)(main_input)
for _ in range((5))
prediction = LSTM(8,return_sequences=False)(lstm)
out = Dense(1)(prediction)
outputs.append(out)
model = Model(inputs=main_input, outputs=outputs)
model.compile(optimizer=’rmsprop’,loss=’mse’)
并且在使用以下方法重塑y时
y=y.reshape((len(y),5,1))
我得到了一个重塑错误
ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 5 array(s), but instead got the following list of 1 arrays: [array([[0.35128802, 0.01439778, 0.60109704, 0.52722118, 0.25493708],
你能帮忙吗?
也许定义你想要的输出形状,例如n个样本和m个时间步长,然后确认你的数据的形状是否如此,或者如果不是,则设置该形状?
您使用“model.add(TimeDistributed(MaxPooling1D(pool_size=2)))”并写“最大池化层将滤波图映射缩小到其大小的1/4”。这是一个笔误,还是有其他原因解释了使用2而不是4?
很抱歉造成困惑。
如果映射是8×8,我们应用一个2×2的池化层,那么我们会得到一个4×4的输出,例如面积缩小了1/4(从64到16)。
对于时间序列,如果我们有1×8并应用1×2的池化,我们得到1×4,你说得对。大小缩小了1/2,而不是像图像数据那样缩小1/4。
已修正。谢谢!
嗨,Jason,
首先,非常感谢您对LSTM模型进行如此精彩的介绍。
我只有一件事不太明白。
在“Multiple Input Series”部分,您使用了以下示例
[[ 10 15 25]
[ 20 25 45]
[ 30 35 65]
[ 40 45 85]
[ 50 55 105]
[ 60 65 125]
[ 70 75 145]
[ 80 85 165]
[ 90 95 185]]
正如您所提到的,数组中的前两个条目指的是两个时间序列,最后一个条目指的是相应的目标变量。为了训练LSTM,您将数据分割成输入和输出样本,如下所示
[[10 15]
[20 25]
[30 35]] 65
为什么我删除前两个目标条目(25和45)?难道我的网络没有损失这些信息来训练吗?为什么我们不使用每个(单个)样本,如x = [10 15] y[25],来训练时间序列呢?如果我有每个时间步的目标,学习序列不是更容易吗?
好问题。
我们必须创建输入和输出样本。
数据集开头的一些输入没有足够的前期数据来重新创建输入,因此必须删除。
工作做得很好,但是,为了方便初学者,您应该提供库导入。
所有库导入都在博文中列出的“完整示例”中提供。
很抱歉造成困惑。
你好,先生,我对您的讲解非常满意,我在如何根据您的演示进行预测方面遇到了问题。我很乐意收到您的电子邮件。
你好,Jason,我需要预测像这样的10万个序列[10, 20, 30, 40, 50, 60, 70, 80, 90],我该如何做到?是分周期一个一个来,还是分周期来?感觉会花费更长时间。
如果模型是只读的,并且您不依赖于样本之间的状态,那么您可以在不同的机器上并行运行模型,并为每个模型准备样本批次进行预测。
你好,我很高兴能有这个LSTM示例来练习。
我有一个问题如下
我有300个Excel工作簿,每个Excel工作簿有3个值……
这3个值将是这种格式[1.02,2.20,1.0]; [2.9,3.5,3.3];……这样的300组。
现在我想用这300个Excel工作簿中的数据作为输入来训练和测试我的模型,模型需要根据以前值的序列来预测第301组,例如:[5,3.3,2.4]。
注意:输出不应该是来自300组的概率集,输出应该是一个新集。
你能给我一些解决这个问题的方法吗?
也许你可以使用一些自定义代码将所有Excel文件中的数据提取到一个csv文件中,为建模做好准备?
如何构建三个并行的LSTM,然后串联一个DNN。
你可以使用一个带有3个变量的LSTM,或者3个LSTM并将它们的输出连接起来。
请参阅函数式API
https://machinelearning.org.cn/keras-functional-api-deep-learning/
嗨,Jason,
感谢您这篇精彩的文章。我一直在(比喻上)消化LSTM,但有一个方面还不清楚。我知道LSTM的一般结构,但我很难理解
model.add(LSTM(50, activation=’relu’, input_shape=(n_steps, n_features)))
当ReLU被设置为激活函数,但不在输出层时,幕后到底发生了什么?为了说清楚,我知道门和它们各自的激活函数:sigmoid和tanh。但如果我们像上面那样设置ReLU,这是否意味着每个单元/LSTM单元输出一个隐藏状态 -> 传递给一个ReLu -> 传递给下一个单元/LSTM单元?
谢谢!
是的,这是正确的。它控制输出门,而不是由sigmoid控制的内部门。
你好Jason Brownlee先生,请将我的数据集以矩阵形式呈现,我想将其转换为适合GRU或LSTM序列模型,
如果你的矩阵代表一个序列,你可以为你的模型重塑它。这会有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
如果不是,RNN可能不合适。
嗨,Jason,
我的脑海中有一个问题,如果可能的话,我想听听你的意见。
同时使用lstm和gru层在模型中会发生什么?有意义吗?
例如这个架构
model=Sequential()
model.add(GRU(256 , input_shape = (x.shape[1], x.shape[2]) , return_sequences=True))
model.add(LSTM(256))
model.add(Dense(64))
model.add(Dense(1))
因为我使用了这个模型,并且与单独使用其中一个模型相比,我取得了很好的结果。
你可以这样做,但为什么要这样做?
你好Jason和社区,
我有一个问题。我的数据集有27个特征。我想使用其中26个作为输入,最后一个作为输出(这个特征也是我数据集中最后一列)。我使用了上面的多输入多步输出代码。在使用函数“def split_sequences(sequences, n_steps_in, n_steps_out)”之后,我将数据集分割成训练集和测试集,并为n_steps_in和n_steps_out选择时间步长。在将2D转换为3D(“split_sequences(train, n_steps_in, n_steps_out)”)之后,我打印了train_X、train_y、test_X和test_y的形状。结果是
(14476887, 25, 26) (14476887, 20) (7130386, 25, 26) (7130386, 20)
我的三个问题是
1.) Python是从0开始计数还是从1开始计数?0是我的第一个特征吗?
2.) Python是从左到右工作的吗?csv文件中的第一个特征是我的第一个特征,依此类推?
3.) 形状(7130386, 20)等于(7130386, 20, 1)还是为什么它是2D的?
我希望我能充分解释我的问题和问题。
提前非常感谢。
阿里
是的,数组索引从0开始。
是的,数组是从左到右运行的。
是的,你可以直接将(7130386, 20)转换为(7130386, 20, 1)。它们是相同的。
你好 Jason,
非常感谢您的回答。我有另外两个问题
我使用了“split a multivariate sequence into samples”代码
def split_sequences(sequences, n_steps_in, n_steps_out)
X, y = list(), list()
for i in range(len(sequences))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out-1
# 检查我们是否超出了数据集
if out_end_ix > len(sequences)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
之后,我将数据集分割成训练集和测试集
train_size = int(len(values) * 0.67)
test_size = len(values) – train_size
train, test = values[0:train_size,:], values[train_size:len(values),:]
print(len(train), len(test))
结果是
14476930 7130429
下一步是定义时间步长
n_steps_in, n_steps_out = 25, 20
train_X, train_y = split_sequences(train, n_steps_in, n_steps_out)
test_X, test_y = split_sequences(test, n_steps_in, n_steps_out)
print(train_X, train_y, test_X and test_y)
结果是
(14476887, 25, 26) (14476887, 20) (7130386, 25, 26) (7130386, 20)
最后一步是创建和拟合LSTM网络
n_features = 26
model = Sequential()
model.add(LSTM(50, input_shape=(n_steps_in, n_features)))
有很多代码,很抱歉。现在是简短的问题
我想预测我的csv文件中的最后一列(第27列)。前26列是输入特征(列)。
1.) 上面的代码中,我在哪里明确定义了我的输入特征和输出特征?
2.) 我是否必须在代码“model.add(LSTM(50, input_shape=(n_steps_in, n_features)))”中使用n_features?我的目标是使用输入特征和输出特征来训练模型,并仅使用测试数据(不含输出特征)进行测试。输出特征应该被预测。
我案例中的n_features = 26的代码是否是错误的?
很抱歉打扰您这些琐碎的问题,但我经验不足。
提前非常感谢。
阿里
我不确定是否理解,抱歉。
也许从这里开始对特征有扎实的理解
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨,Jason,
感谢您的帖子。
我想使用像这样的网络架构
cnn = Sequential([
Conv1D(filters=16, kernel_size=4, strides=2, activation=’relu’, input_shape=(n_steps, n_features)),
BatchNormalization(),
MaxPooling1D(pool_size=2)
])
model = Sequential()
model.add(cnn)
model.add(LSTM(50, activation=’relu’))
model.add(Dense(1))
原因是,当真实模型是路径依赖的时,应该使用更长的回溯期,但对于处理大量时间步长的LSTM来说效率不高,所以我使用CNN来减少时间步长并编码一些预测信息。
你觉得这个有道理吗?
您认为预训练在堆叠网络结构中会有贡献吗?
Joe
不要太在意我的猜测,也许可以试试看?
亲爱的 Jason,
感谢您的精彩教程。我只是有一个问题
据我从您的解释中理解,对于双向神经网络,我们需要过去的和未来的输入数据来预测当前的时间步长。因此,在单变量LSTM的情况下,当我们预测当前时间(例如)的能源使用时,我们需要知道未来的能源使用情况吗?这让我有点困惑。你能否解释一下。
谢谢你
不,未来是从过去预测的。
或者你可以根据自己的意愿来构建你的预测问题。
感谢您的回答。您能否再解释一下,使其更清晰?因为我刚刚检查了双向RNN的数学公式,我看到它有一个来自下一个时间步长的隐藏状态作为输入:( x(t), h(t-1) 和 h(t+1) 用于计算y(t))。
因此,当输入来自下一个时间步长的隐藏状态时,如何才能仅在单变量双向RNN中使用过去的数据呢?
感谢您的指导。
也许这会有帮助。
https://machinelearning.org.cn/develop-bidirectional-lstm-sequence-classification-python-keras/
实际上,我应用了双向层,但我的误差比典型的LSTM网络高得多。这可能吗,还是我做错了?
当我写50个神经元时,这意味着每个双向层有50个神经元,还是两个层的总和?
双向可能需要更多的训练。
每个方向有50个。
您好,我有一个关于数据归一化的问题(将值缩放到特定数字之间,例如[0,1])。我应该在将其转换为监督形式(如本例所示)之前进行归一化,还是在监督形式之后进行?
我注意到,如果我在之后进行归一化,列看起来会略有不同,因为归一化是通过列进行的。下面是之后进行归一化的示例输出
t-1 t t+1
-1.000000 -1.000000 -0.870529
-1.000000 -0.869976 -0.895359
-0.869976 -0.894799 -0.897133
-0.894799 -0.896572 -0.901271
这会是LSTM预测的问题吗?
是的,缩放应该先进行。
你好,Jason。
很棒的教程。我的电子健康记录数据具有多变量时间序列输入。对于预测,使用普通的LSTM还是双向LSTM更好?
谢谢
我鼓励您测试一系列模型,包括线性、ML、MLP、CNN和LSTM,并找出最适合您特定数据集的模型。
这会有帮助
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
嗨,Jason,
我正在尝试训练我的模型来预测144个数据点(1天)(每10分钟一个值(家庭负荷预测)),基于5天(=144*5个值)(我有更多数据,但至今尚未获得良好结果,因此我使用较少的数据进行训练……这需要很长时间)。
每天都有季节性。所以,我选择n_input为144。
我将批量大小从1到6进行变化,并将epoch从25到150进行变化,
但我的问题是:每次我得到一个结果时,我都会遇到以下问题之一:
1-值收敛到一个常数(我认为可能是欠拟合)……所以我尝试减小批量大小并增加epoch。
2-当我这样做时……我总是得到一个值为n.a.n的损失,然后我从模型中得不到任何预测……
你能推荐些什么吗?
非常感谢您!!!!
我很感激!
您可以发现如何诊断模型性能并在此处改进性能。
https://machinelearning.org.cn/start-here/#better
谢谢你
但我的意思是,不是损失值……而是预测值,它们收敛到一个常数,当我增加epoch的数量时……结果会更好,但很多时候,从epoch n. 150左右开始……损失是n.a.n……而且没有预测……
我明白了。
我搜索了一下……我想我可能遇到了梯度爆炸问题……
我明白了,这可能有帮助
https://machinelearning.org.cn/how-to-avoid-exploding-gradients-in-neural-networks-with-gradient-clipping/
你好 Jason,
我还有一个问题
一次性通过dense(144)预测144个值是不是更好?
或者
就像我现在做的那样,我只预测1个值,然后将历史记录附加到它上面
history.append(yhat_sequence)
…
add.dense(1)
非常感谢!!!
也许可以比较几种方法,看看哪种最适合您的数据集。
你好 Jason,
感谢您提供的精彩教程和对LSTM的深入介绍。
对于“Multiple Parallel Input and Multi-Step Output”,您也提到可以使用LSTM的向量版本。我无法理解那个模型应该是什么样子。
model = Sequential()
model.add(LSTM(100, activation=’relu’, return_sequences=True, input_shape=(n_steps_in, n_features)))
model.add(LSTM(100, activation=’relu’, return_sequences=True))
#这里需要什么???维度到n_steps_out
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer=’adam’, loss=’mse’)
上面的架构不是我想要的。最终应该有一个输出维度为(batch_size, n_steps_out, n_features),但我得到的是(batch_size, 100, n_feautres)或一个错误。那么如何在不使用您代码片段的编码器-解码器版本的情况下使上述架构工作呢?
非常感谢您的所有辛勤工作。
也许你可以以博文中的示例作为起点?
嗨,Jason,
非常有趣的文章!!
实际上我有一个疑问,我目前正在尝试根据折扣促销来预测业务销售额。所以,未来的因变量值通常是固定的,是否有处理此类问题的代码?
谢谢和问候
也许你可以改编这里的其中一个示例。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
亲爱的 Jason,
我有一个关于多变量LSTM模型的问题。
在“Multiple Input Series”中,您的输入是
80, 85
90, 95
100, 105
您试图预测205的输出。
在“Multiple Parallel Series”中,您的输入是
70, 75, 145
80, 85, 165
90, 95, 185
您试图预测
[100, 105, 205]
我的问题是,在第一个模型中,您对输出的过去有更多信息,但您没有传递给模型。
所以,实际输入应该是
80, 85, 165
90, 95, 185
100, 105, X
其中我们试图预测X。
同样,在第二个模型中,让我们假设您知道前两个字段100和105,而您只想预测205。
70, 75, 145
80, 85, 165
90, 95, 185
100, 105, X
同样,我们不必要地试图预测一些已知的值。
是否有模型可以让我使用过去时间序列的所有可用信息来尝试预测X?
我从这篇博文中获益良多,而上述问题是我正在尝试回答的。非常感谢您分享您的知识。它对我们帮助很大。
是的,你可以根据自己的意愿来构建问题。
在您提出的框架中,您可以使用一个新标记来表示缺失,然后使用Masking输入层。
或者一个多输入模型,其中包含一个用于因变量的单独输入和一个用于您正在预测的单变量序列的单独输入。
也许可以进行实验,看看您更喜欢哪种模型,哪种最适合您的特定数据集。
谢谢Jason。您能否指出任何解释了上述内容的参考模型?
很好的问题。
我目前没有。我可能需要创建一个。
您能否提供一个处理缺失数据和使用Masking层的示例代码?
我试图在多变量(多个序列)的情况下,排除那些即使只有1个点缺失的样本的训练。
是的,请参阅本教程
https://machinelearning.org.cn/handle-missing-timesteps-sequence-prediction-problems-python/
嗨,Jason,
我正在为LSTM Encoder-Decoder模型实现交叉验证,我想问您,是在每个步骤中重新创建类更好,还是可以使用旧类调用fit方法。
谢谢和问候
通常,交叉验证对于序列预测是无效的,您必须使用前向验证。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
嗨,Jason,
如果我必须以这样的方式训练我的模型,即
输入是两列,即温度和压力,即前25%的数据,输出也是两列温度和压力,即剩余的75%的数据。
我的目标是通过提供少量输入并接收更大的输出到LSTM来一起预测温度和压力。
如果我通过输入[x,y]训练我的模型,我能预测[x,y]吗,但我不想提供时间戳。我应该遵循哪种方法?
我已经按照您的博文准备好了数据,我现在很困惑如何训练模型而不使用时间步长。
我建议遵循此框架。
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
这里的教程将是一个有用的起点。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
嗨,Jason,
为什么您在LSTM模型中训练输入序列时没有使用MinMax Scaler?
好问题,我省略了缩放,以便让示例更简单——例如,为了简洁。
非常感谢,我还有一个问题。如果我有200,000个数据点,我需要为它们制作时间步长,也许将数据分成5个时间步长,并在每个时间步长中提供40,000个点给LSTM进行训练,这会是好的训练吗?或者您有什么建议?以便我能正确准备数据。
我有多变量数据,有2个变量,并且想预测这两个变量。所以,基本上是2个输入和2个输出,但是我是否需要先将它们转换为监督形式,因为它们是温度和粘度,并且它们在时间上相互依赖?
所以,我应该先对它们进行监督,还是可以直接使用多变量时间序列进行预测,将数据分成5个时间步长并预测2个输出?
您是否也提供咨询服务?
也许这篇文章会有所帮助
https://machinelearning.org.cn/prepare-univariate-time-series-data-long-short-term-memory-networks/
以及这里的建议
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
关于咨询
https://machinelearning.org.cn/faq/single-faq/can-you-do-some-consulting
你好,
您能否告诉我如何可视化结果?因为当我重塑数组时,它无法从3D重塑为2D。
谢谢您,祝您有美好的一天!
您可以使用matplotlib的plot()函数创建折线图。
这将有助于重塑
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
我认为我没有正确地重新表述我的问题。我的问题是例如:我用300个n_step_in和300个n_steps_out训练了我的LSTM模型。现在,训练完成后,yhat的形状是(20000, 300,2)。所以,当我将其重塑为2D以查看结果时,它会给我一个错误,并且无法将其重塑回。
也许这篇博文能帮助您解决数组重塑问题。
https://machinelearning.org.cn/index-slice-reshape-numpy-arrays-machine-learning-python/
你好,我能否在此层之下添加一个额外的层?如果可以,应该如何操作?
model.add(LSTM(200, activation='relu', input_shape=(n_timesteps, n_features)))
提前感谢。
本教程展示了如何创建堆叠LSTM。
https://machinelearning.org.cn/stacked-long-short-term-memory-networks/
您好,您能否告诉我这种预测只适用于顺序数据吗?
序列预测适用于由序列组成的数据。您可以在这里了解更多。
https://machinelearning.org.cn/sequence-prediction-problems-learning-lstm-recurrent-neural-networks/
嗨,Jason,
如果我有一个无监督数据,并将其转换为LSTM模型的监督数据。
我的问题是,当我们使数据成为监督数据并提供输入数据点并预测输出数据点时,但输出只是输入的n+1点,最后我们只从整个数据中预测1点。基本上,我们只将所有点用于训练。
模型学习一个函数,该函数接受输入点并预测下一个点。
但是,如果我希望模型不仅接收所有数据作为输入点,而是只接收一些输入点来预测剩余数据呢?那么使用的是什么策略?
您控制着数据进入和离开模型的方式。
准备您想输入的数据并进行预测。
上面的示例将提供一个模板,您可以从中开始并为您的项目进行调整。
是的,我想将其应用于时间序列。
我推荐这里的相关教程。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
抱歉,您谈论的是时间序列,如果存在日期和时间呢?(我没有在您创建的数据中看到日期和时间特征)
日期和时间已从数据集中删除,并直接处理观测序列。
嗨,Jason,
在过去半年里,我非常享受您的许多文章。关于您使用堆叠LSTM模型的输出向量模型的问题。在底层,对于3个输入时间步和2个输出时间步,使用的是什么类型的架构?我确信这是一个many-to-many问题,但您能帮我弄清楚确切的可视化连接吗?第一个输出时间步是否直接覆盖在输入序列的第二个时间步之上?
好问题。
对于一个接收序列输入并输出一个时间步长(恰好是一个向量)的模型,我将其归类为many-to-one模型。
https://machinelearning.org.cn/models-sequence-prediction-recurrent-neural-networks/
很棒的阅读,这是一个很好的知识点。谢谢,我欣赏您的工作。
谢谢。
你好Jason,感谢您出色的博文和及时的回复。在多步LSTM模型中,当我加载我的数据集时,我首先注意到步长应该是数据集长度的倍数(即,如果我的数据有1239行,那么步长为59是合适的,因为1239/59 = 21)。实际上,尝试使用非倍数作为n_steps_in会导致拟合模型时出现nan损失值。我确实能够使用59 over 1239一直运行到50个epoch,但发生了一些我无法解释的事情:在重新运行代码而未做任何更改后,各个epoch的损失(在设置verbose为1后)又跳回了nan。它非常不稳定和不可预测,并且最终完成所有epoch似乎是碰巧成功。您能否帮我理解问题出在哪里?谢谢!
是的,在建模之前对数据进行缩放可能会有帮助。
是的,您是正确的,一如既往。缩放不仅避免了nan,还使每个epoch运行得更快。谢谢Jason!
干得好。
谢谢Jason。我很抱歉,如果这在评论列表中已经提到过,但在预测连续变量的情况下,您将如何比较LSTM与另一种算法(如Random Forest)的性能?
除了比较两个模型之间的实际值与预测值之外,是否还有单独评估两个模型准确性的方法?
使用相同的测试框架,即相同的评估方法,如前向验证。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
RMSE或MAE通常是很好的比较指标。
谢谢 Jason,
您所有的工作都很清晰!非常感谢您。请问我有一些问题。上面您应用的所有LSTM模型之间有什么区别?它们之间是否存在性能权衡?因为您重复说我们可以将它们中的任何一个用于时间序列预测。
另一方面,我正在研究无线信道预测领域。这是一个复杂数字问题。那么,我是否可以将其分解为实部和虚部,并分别将您的LSTM模型应用于每个部分,然后将输出结果连接起来?
好问题。
与其说是性能权衡,不如说是问题的不同表述,或者不同类型的问题。
目标是向您展示方法的灵活性,并且您应该根据您的项目来调整它,而不是根据方法来调整您的项目。
我不知道神经网络或Keras中的虚数,抱歉。
我想知道如何处理这个问题。假设我们有一个具有2个特征的时间序列,范围从0到n,表示为
[a0, b0], [a1, b1], [a2, b2] 到 [an, bn]
系列输出将是,
[a0 b0], [a1, b1], [a2, b2] -> [a3]
问题在于[b3]在确定[a3]时也起着重要作用。
我的问题是如何整合这一点,以便我能够使用a0, a1, a2, b0, b1, b2, b3作为输入模型并预测[a3]。
好问题,从这里开始。
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
然后这里
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
很棒的教程。
我有一个关于时间序列预测问题的LSTM模型的问题。我的数据集有四个输入特征,如78, 153.23, 77.25, 4.33。
第一个输入的顺序差异是78,80,87,96……等等。
其他输入的顺序是正常的,如77.25,77.35,77.40……。
我使用了一个LSTM模型,以前一个时间戳作为输入来预测下一个时间戳,它在最后三个输入上预测得很好,但在第一个输入上预测得很差。即
实际:78, 153.23, 77.25, 4.33
预测:82, 153.01, 77.02, 4.12
如何调整这个模型以获得第一个输入的良好结果?
您可以在这里找到有关诊断和调整深度学习模型的建议。
https://machinelearning.org.cn/start-here/#better
嗨,Jason,
我想建立一个模型来预测水库的入流,基于过去的降雨数据、温度数据以及过去的入流数据。
我希望模型能够根据过去一周的降雨和温度数据,预测未来一周(7个时间步长)的入流。
我应该使用什么模型?
好问题,请遵循此过程。
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
谢谢Jason。我通读了该过程以及您网站上的一些其他链接,并决定多变量多步LSTM会有帮助。
是否有针对该项目的特定链接?因为我只找到了单变量多步LSTM。
上面的教程是一个很好的起点,您可以根据您的项目进行调整。
嗨,Jason,
我能否将时间放在X轴上,在Y轴上预测风速?
此致
当然。您会丢弃时间,直接对风速进行建模。
抱歉,我没明白。我是应该丢弃时间,还是可以使用它来训练我的模型以预测风速。
当观测间隔一致时,时间列通常会被丢弃。
但如果时间不一致呢?
那么请看这里。
https://machinelearning.org.cn/faq/single-faq/how-do-i-handle-discontiguous-time-series-data
嗨,Jason,
在“Multiple Parallel Input and Multi-Step Output”示例中,您提到可以使用向量输出方法或编码器/解码器来实现,然后演示了编码器/解码器。
我一直在想这个示例在向量输出形式下会是什么样子。目标y,对于每个样本是否需要合并成一个单一的1D数组或向量?
例如,
如果y对于一个样本看起来像
[a1,b1,c1],
[a2,b2,c2],
…
[an,bn,cn]
我们是否应该将其重塑成类似这样的形式?
[a1,b1,c1,a1,b2,c2,…,an,bn,cn]
可能是一个长的1D向量,包含所有时间步长,您可以选择以任何您想要的方式来解释它(例如,通过期望/目标y的结构)。
我已在Google Colab中设置了所有示例:https://colab.research.google.com/drive/16nsMXFDmzgdpsSY_p1ZljN5ZDzq9u6jY#scrollTo=xgSwSfpE3-GO&forceEdit=true&sandboxMode=true
我宁愿你不要。
嘿,
我们如何在此模型的训练中看到均方根误差
此致,
Kannu
这里有一个例子
https://machinelearning.org.cn/custom-metrics-deep-learning-keras-python/
你好 Jason,
我正在尝试使用CNN-LSTM进行预测
split sequences 的输出为
(175196, 4, 4) (175196, 1)
其中 175196 是样本,4 是步数,4 是特征(变量)。
然后我按照教程中的指示重塑了输入向量,但当我运行模型时
我收到此错误
at: TypeError Traceback (most recent call last)
in ()
22 model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
23 model.add(TimeDistributed(Flatten()))
—> 24 model.add(LSTM(50, activation=’relu’))
25 model.add(Dense(1))
26 model.compile(optimizer=’adam’, loss=’mse’)
TypeError: while_loop() 收到意外的关键字参数 ‘maximum_iterations’
我知道这样调试很难!但你有什么想法可能是哪里出了问题吗?
其他 Keras 示例对你来说是否可用?
你的 Keras/TF 安装可能存在问题。
是的,其他的 Keras 示例都可用,包括 CNN、多头 CNN 等。
你说对了 🙂 我已更新到更高版本的 tensorflow 和 keras,它就能用了!谢谢!
很高兴听到这个消息。
这很奇怪,我不确定我是否有好的建议,抱歉。
也许可以尝试简化示例,看看你的工作站上可能是什么错误原因?
嗨,Jason,
感谢这篇精彩的文章。我可以使用 LSTM 为所有站点创建一个模型吗?也就是说,如果我们有例如一群人,每个人都有自己的时间序列数据,具有不同的特征,LSTM 模型可以一次性从所有这些时间序列中学习吗?
此致
当然。这里有一些建议
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
非常感谢您的帮助
不客气。
嗨 Jason,我们如何选择 split_sequence() 中的 n_steps?或者我们应该将 n_steps 视为超参数,还是可以通过统计检验来设置?感谢你的工作 Jason。我关注你的网站已经 2 年了,你的内容是 ML 社区中最好的。
一个超参数。
谢谢,我非常感谢您的支持!
嗨,Jason,
我在 LSTM 模型方面有一些问题。
首先,这是 LSTM 输入 x 的定义。在时间序列预测的情况下,我们通过 batchsize 参数将输入数据分成一些部分。之后,这些 2D 部分数据被转换为 3D 张量数据并馈入模型进行训练。所有部分都馈入模型并完成前向/后向传播后,一个 epoch 的例程就完成了。我的问题是:在 x[t] 输入时间,LSTM 模型输入 x 指的是仅第一部分 x 数据还是所有部分数据?
其次,LSTM_unit 参数的定义是什么?我的理解是 LSTM 输入 x 向量的元素数量。例如,如果有 10 个输入,LSTM_unit 应该是 10 才能捕获所有输入向量。但是,它不总是需要更高的数字,比如 20,等等。
第三,LSTM 现在有“特征重要性”的示例吗?我很期待,现在很沮丧。LSTM 和 XGBoost 可以有样本特征重要性结果吗?
非常感谢
X 指的是输入样本,定义请参见此
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
一个 unit 就像 MLP 中的一个节点。每个 unit 都将整个输入序列作为输入。节点的数量与输入时间步的数量无关。
据我所知,没有。
嗨 Jason,我运行了第一个示例,但它失败了。它显示:TypeError: Input ‘b’ of ‘MatMul’ Op has type float32 that does not match type int32 of argument ‘a’。你知道问题出在哪里吗?
很抱歉听到这个消息,我在这里有一些建议。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
谢谢 Jason。我已解决该问题。原因是,我安装了 tensorflow 2.0 + keras 2.2.4,但这两者不匹配,所以我使用了 tensorflow.keras 而不是 keras。我在代码中添加了一个命令 “x_input = x_input.astype(‘float32’)”,它运行得很顺利。另一种方法是安装 tensorflow 版本 1.15.0,这样就不会出现问题。
很高兴听到你解决了问题。
你可以使用 Keras 2.3. 配合 TensorFlow 2.0,或者 Keras 2.2 配合 TensorFlow 1.15。
嗨,Jason,
我有一个建模问题,我认为 LSTM 网络是最适合的模型。
我想在飞机起飞前预测其真实轨迹。我有一组数据,第一组是起飞前宣布的轨迹(假的),第二组是着陆后宣布的轨迹(真实的)。
我想预测真实的,给出假的。
我有一个数组列表,每个数组代表飞机的一次飞行。每次飞行由不同的变量表示,在插值后,我得到了每次飞行的 50 个观测点。
在每个点,我们可以观察到一个变量向量,如纬度、经度等。
假设我有 N 个这样的变量。
我有 2200 次飞行,所以我的输入数据是一个形状为 (2200,50,N) 的数组。
我已经尝试了一个小模型,但奇怪的是,模型似乎跟随了假轨迹而不是真实轨迹。
你有什么关于我可以使用什么架构的想法吗?
非常感谢
也许可以测试一套不同的方法,找出最适合您特定数据集的方法?
是的,我正在这样做,但也许你能帮助我处理最后一层,我认为错误就出在那里。
正如我所说,我有一个形状为 (50,N) 的向量,它代表一个有 50 个点和 N 个特征的飞行,我想预测一个形状为 (50,2) 的向量,即 50 个点和 (纬度、经度)。
我不能在模型末尾使用密集层,因为它不会返回正确的形状。
编码器-解码器,输出层有 2 个节点,RepeatVector 层有 50 个节点——这将实现所需的输出。
你好,
感谢您的教程;它们太棒了!我在实现您的想法时遇到了以下障碍:我使用您的“split_sequences”来准备网络输入,相应地训练我的网络并保存模型。当我将相同的输入用于训练好的模型并绘制它时,我得到了一个非常奇怪的图,比如许多重叠的线条。你介意告诉我我的问题是什么吗?
谢谢。
抱歉,我手头上没有,抱歉。
嗨,Jason,
我正在构建一个多并行输入和多步输出模型,我想知道为什么您在 `model.add(RepeatVector(n_steps_out))` 中重复相同的 LSTM 输出?我考虑的替代方法是使用 Keras 功能 API,从输入训练 n_steps_out 个 LSTM,连接这些 LSTM 的输出,然后将其馈送到下一个 LSTM,所以它看起来像这样
input = Input(shape=(n_steps_in,n_features))
concat_layers = []
for i in range n_steps_out
concat_layers.concat(LSTM(200,activation=’relu’))(input)
x = tf.keras.layer.Concatenate(concat_layers)
x = LSTM(200,activation=’relu’,return_sequences=True)(x)
x = TimeDistributed(Dense(n_features)))(x)
model=Model(input,x)
model.compile(optimizer=’adam’, loss=’mse’)
我可以看到的最大缺点是参数会多很多,但还有其他我忽略的问题吗?例如,这是否会消除前一个模型更好地维护的不同时间步之间的某些关系?
谢谢!
原因是它是一个编码器-解码器模型,其中输入的相同编码用于生成每个输出时间步。
也许可以尝试一下?测试一套不同的模型以找出最适合您特定数据集的模型是个好主意。
亲爱的 Jason,
感谢您的教程,它非常有帮助!但是,我很难理解下面 CNN LSTM 示例中给出的输入形状
X, y = split_sequence(raw_seq, n_steps)
# 从 [样本, 时间步] 重塑为 [样本, 子序列, 时间步, 特征]
n_features = 1
n_seq = 2
n_steps = 2
X = X.reshape((X.shape[0], n_seq, n_steps, n_features))
# 定义模型
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation=’relu’), input_shape=(None, n_steps, n_features)))
…
这里,X 首先被重塑为 4 维,但是,在模型 Conv1D 层中定义的输入形状是 3 维。这里的 None 是否指 X 的 “n_seq” 维度还是 X 的样本数……?
然后,用于拟合和预测的数据再次是 4 维……
您能否详细解释一下?我真的很困惑……
非常感谢!
是的,CNN 必须处理子序列,然后将处理过的子序列分组传递给 LSTM。
实际上,X 的每个部分都是 3 维(n_seq、n_steps、n_features),并且每次模型在此 CNN-LSTM 情况中接受一个 X 部分。
我认为 None 指的是 n_seq,但 n_seq 是通过使用 TimeDistributed() 来表示的,所以有一个 None 来占据第一个维度的位置。
你好 jason,
如果我们有一个数据集,其中包含一年中每一天的销售数据,并且我们想根据过去 30 天的销售数据预测例如 10 天的销售数据?我们应该得到什么形式的输出?还有获取预测值的代码?是 model.predict(X_test) 吗?
你可以直接预测这 10 天。
https://machinelearning.org.cn/faq/single-faq/how-do-you-use-lstms-for-multi-step-time-series-forecasting
嗨 Jason,我读到一半了,读这些东西简直是一种享受!感谢您付出的巨大努力并提供这些内容!我立刻成了您网站的粉丝。
谢谢 Arne!
嗨,Jason,
一个实际问题,在 LSTM 中。如果输入数据集的范围不同,如何处理 LSTM 预测模型?例如,如果输入向量一的范围是 0~100,向量二的范围是 0~0.5,我们是否仍然可以将这两个输入向量放在一起编译模型?我使用 SHAP 包来分析权重。在这种情况下,向量一总是非常强大,而不是向量二。从数学上看,这个结果是正确的。你对此有何看法?
jasper
你可以在建模之前尝试对每个变量进行归一化或标准化,或者尝试使用 relu 激活。
这个可能会有帮助
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
嗨,Jason,
感谢如此详细的解释。我有一个多步多元 LSTM 问题的数据缩放问题。我需要过去 14/21 天的数据来预测未来 7 天。您能否就使用 MinMax 进行这类问题的适当数据缩放方法给出一些想法,因为我对矩阵的形状感到困惑?
谢谢,很高兴它能帮到你!
是的,请看这个
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
谢谢。我知道缩放如何工作,并且已经在单步预测中实现了它。然而,当涉及到多步时,我们实际上会分割数据,在使用 split_sequency 函数后,它会变成 3 维。这意味着我们有 X 和 Y 的 3 维矩阵。
Scaler 不能在 3 维矩阵上工作。
如果我在分割之前进行缩放,我最终会得到一个矩阵维度,在预测后我无法检索它,因此将卡住而无法执行 inverse_transform 进行缩放。我将在此事上感谢您的帮助。
是的,这很棘手。你可能需要编写一些自定义代码,因为库不支持它。
也许可以尝试使用 relu 而不缩放,至少作为起点。
嗨,Jason,
我想在编码器-解码器模型中引入注意力机制
用于回归问题(具有多个输入)。有没有其他文章可以帮助我解决这个问题?
我希望将来能涵盖这个话题。
你好,Jason。
是否有任何简单的方法可以将注意力添加到本文的 Encoder_Decoder 模型中?
我尝试使用 AttentionWrapper 类来实现它,但我失败了,因为我很难在短时间内完成。你能给一些指导吗?
谢谢!
TensorFlow 2 API 提供了注意力层。
嗨,Jason,
非常感谢您提供如此有价值的教程。真的很感激。
Jason,我对 DL 和 RNN 方面有点新手。我有两个小问题需要澄清。在我的问题中,我想预测参与者明天将走的步数(即步数),以过去几天的步数为依据。为此,我们收集了大量参与者过去 n 天的步数数据。
这是一个单变量问题,其中每个参与者的步数都被视为一个单变量序列并训练模型吗?您认为 RNN 是解决此问题的好方法吗?
我是否必须对每个参与者的步数序列进行缩放(通过获取每个参与者当前的均值和标准差),还是可以使用原始计数?
提前再次非常感谢您。祝您未来工作一切顺利!!!!
San
不客气。
听起来像单变量问题,这会有帮助
https://machinelearning.org.cn/taxonomy-of-time-series-forecasting-problems/
在建模之前对数据进行缩放是个好主意,也许可以先尝试在原始数据上拟合以开始。
谢谢 Jason!!!请继续做好工作!!!
谢谢!
非常感谢您分享如此有知识的文章,
我有一个疑问,
对于最后一个——多并行输入和多步输出
我试图预测未来 6 或 12 小时的数据,目前正尝试预测未来 6 小时的数据,使用 n_steps_in- 72 进行训练,期望 n_steps_out- 6,具有 6 个特征。
但我得到了 nan 输出。
请看看我是否做错了什么。
def split_sequences(sequences, n_steps_in, n_steps_out)
X,y = list(), list()
pt = progress_timer(description= ‘Split Sequences’, n_iter=len(sequences))
for i in range(len(sequences))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out
# 检查我们是否超出了数据集
if out_end_ix > len(sequences)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :]
X.append(seq_x)
y.append(seq_y)
pt.update()
pt.finish()
return array(X), array(y)
dataset = df_104902.values
# 选择时间步数
n_steps_in, n_steps_out = 72, 6
# 转换为输入/输出
X, y = split_sequences(dataset, n_steps_in, n_steps_out)
# 数据集知道特征的数量,例如 2
n_features = X.shape[2]
# 定义模型
model = Sequential()
model.add(LSTM(200, activation=’relu’, input_shape=(n_steps_in, n_features)))
model.add(TimeDistributed(Dense(n_features_out)))
model.add(LSTM(200, activation=’relu’, return_sequences=True))
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=30, verbose=0)
# 演示预测
x_input = array(df_104902[-72:])
x_input = x_input.reshape((1, n_steps_in, n_features))
yhat = model.predict(x_input, verbose=0)
print(yhat)
输出为-
[[[nan nan nan nan nan nan]
[nan nan nan nan nan nan]
[nan nan nan nan nan nan]
[nan nan nan nan nan nan]
[nan nan nan nan nan nan]
[nan nan nan nan nan nan]]]
nan 输出不是好的。
也许可以检查输入数据的比例,并在拟合模型之前进行归一化或标准化?
我的 X 和 y 的形状是 – (20875, 72, 6) 和 (20875, 6, 6),
而 x_input 是 (1, 72, 6)
我遇到了同样的问题,数据标准化……它将特征数量减少到 1,我假设是因为 hstack 不起作用,而是使用了连接……有什么建议吗?
这个可能会有帮助
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
Jason,您好,我有一个问题,我如何验证预测方法?我看到在其他示例中,序列被分成两部分:训练和测试,而在这个案例中它没有,这是为什么?
最常见的方法是使用交叉验证。
https://machinelearning.org.cn/k-fold-cross-validation/
亲爱的 Jason,
首先,非常感谢您的时间和精彩内容。
其次,我长期研究了您的网站。我有一个问题:我开发了一个预测股票价格的模型,我的模型也可以预测 X_test 数据,现在我该如何预测未发生的序列(未来时间)?
不客气。
调用 model.predict(newData) 对新数据进行预测。
newData 不可用,也就是说,未来的日期还没有到来,也无法获得,我该如何为模型准备它们?
您必须设计和训练您的模型,使其能够基于在需要进行预测时可用的数据进行预测。
例如,如果您在预测下周时有前 7 天的数据,那么请围绕此数据设计您的模型并对其进行训练。
然后,当您开始在新数据上使用您的模型时,您将拥有可用数据。
亲爱的 Jason,
非常感谢您的时间和关注。我会尝试您的方法。
不客气。
亲爱的 Jason,
非常感谢您的时间和关注。
我想知道我是否可以使用时间作为单变量序列。
此致
当然可以。
你好 Jason,
我的模型将从过去的预测数据和实际 AC Power 数据中学习。
我的输入是未来 7 天的预测,以 csv 文件形式。
我的目标是根据输入预测 AC Power 数据。
我不知道如何在这里应用我的模型。
你能帮帮我吗?
也许从这里开始
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
非常感谢。我一直在努力理解 LSTM。
您的工作对我帮助很大。
不客气,我很高兴听到这个消息。
亲爱的 Jason,
感谢您的贡献。您在我开始学习深度学习时给了我很大的帮助。
我有一个问题。我正在做一个模型,但令人惊讶的是,预测的输出形状与训练数据的目标形状不同。
训练:X (12000, 12, 8), Y (12000,)
测试:X (3000, 12, 8); Y (3000,)
pred = model.predict (X (3000, 12, 8))
而 pred 的形状是 (3000, 12, 1),但我期望的是 (3000,)
我做错了什么?
请帮助我
也许可以仔细检查一下模型的结构,例如输出层/模型。
亲爱的 Jason,
感谢您的教程,它非常有帮助!但是,我使用数据归一化方法来处理输入数据(10,20,30…)来执行您的多步 LSTM 模型,但出现了错误。我不知道如何解决它。请看下面的程序。谢谢!
from numpy import array
来自 keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import collections
# 将单变量序列分成样本
def split_sequence(sequence, n_steps_in, n_steps_out)
X, y = list(), list()
for i in range(len(sequence))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out
# check if we are beyond the sequence
if out_end_ix > len(sequence)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
training_set = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
training_set = training_set.reshape(-1,1)
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range = (0, 1))
raw_seq = sc.fit_transform(training_set)
print(raw_seq)
# 选择时间步数
n_steps_in, n_steps_out = 3, 2
# 分割成样本
X, y = split_sequence(raw_seq, n_steps_in, n_steps_out)
# 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数]
n_features = 1
X = X.reshape((X.shape[0], X.shape[1], n_features))
# 定义模型
model = Sequential()
model.add(LSTM(40, activation=’relu’, return_sequences=True, input_shape=(n_steps_in, n_features)))
model.add(LSTM(40, activation=’relu’))
model.add(Dense(n_steps_out))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
print(‘X: \n’,X)
print(‘y: \n’,y)
model.fit(X, y, epochs=60, verbose=0)
# 演示预测
#x_input = array([70, 80, 90])
x_input = np.array([70, 80, 90])
x_input= x_input.reshape(-1,1)
x_input = sc.transform(x_input)
x_input = x_input.reshape((1, n_steps_in, n_features))
yhat = model.predict(x_input, verbose=0)
yhat = sc.inverse_transform(yhat)
print(100,110)
print(yhat)
我很想提供帮助,但我没有能力调试您的代码,抱歉。
这可能会有帮助
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
非常感谢。
我已解决该问题。
感谢您的教程。
很高兴听到这个消息。
X, y = split_sequence(raw_seq, n_steps)
# 从 [样本, 时间步] 重塑为 [样本, 子序列, 时间步, 特征]
n_features = 1
n_seq = 2
n_steps = 2
X = X.reshape((X.shape[0], n_seq, n_steps, n_features))
# 定义模型
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation=’relu’), input_shape=(None, n_steps, n_features)))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(50, activation=’relu’))
您帖子中的代码,使用 CNN+LSTM 来处理单变量模型。
我对 n_seq 的数字感到困惑,为什么是 2。我是否可以将 n_seq 视为 LSTM 的 times_step?
配置是任意的,您可以将其更改为您喜欢的任何内容。
我们有办法找到最佳的 n_seq 配置吗?
我能否将 n_seq 视为 LSTM 的 times_step?我的意思是第一个子序列是 LSTM 输入的第一个步骤,第二个子序列是 LSTM 输入的第二个步骤?
如果我的理解是错误的,请纠正我!
测试不同的值是个好主意。
是的,请看这个
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
感谢您的精彩教程!
顺便说一句,我找到了一个更 Pythonic 的方法来编写 split_sequence() 函数。
此致,
感谢分享。
Jason先生您好,
请,我有一个关于 LSTM 模型的技术问题。
LSTM 定义了默认激活函数,例如
用于输入门、遗忘门和输出门的 3 个 sigmoid。
和用于更新循环层内部状态的 2 个 tanh。
在您的代码中
在您的代码中
#########################
# 定义模型
model = Sequential()
model.add(LSTM(50, activation=’relu’, return_sequences=True, input_shape=(n_steps, n_features)))
model.add(LSTM(50, activation=’relu’))
model.add(Dense(1))
#########################
您是否将 sigmoid 更改为 relu 或 tanh?
是的。
感谢您的精彩解释。我有一个关于我的数据集和需求属于哪个类别的问题。
我想预测每个部件的缺陷数量。
我的数据集是这样的:Part (a,b,c 是 Tool 的组件)
date Part Tools shipped num of defects(of parts)
2019-01-01 part a 2 0
2019-01-01 part b 1 2
2019-01-01 part c 2 2
2019-01-08 part a 2 0
2019-01-08 part b 1 1
2019-01-08 part c 2 1
2019-01-15 part a 2 0
2019-01-15 part b 1 1
2019-01-15 part c 2 3
我想预测例如未来两周所有部件的缺陷数量。
Tools shipped 列与缺陷数量有关。我也有未来 Tools shipped 的数据。所以期望的输出是
2019-01-22 part a 2 ??
2019-01-22 part b 2 ??
2019-01-22 part c 2 ??
特定周的工具发货量是恒定的
听起来像一个时间序列预测问题。请看这里
https://machinelearning.org.cn/taxonomy-of-time-series-forecasting-problems/
嗨,Jason,
感谢您提供如此丰富的信息教程。我计划将 LSTM 应用于多元时间序列数据。输入维度是 (1000*7*24),输出是 (1000*30)。我想了解如何决定使用多少层和多少单元。同样,批量大小也适合这种情况。如果您能评论一些标准启发式方法或指向一些可靠资源,那就太好了。
好问题,请看这个
https://machinelearning.org.cn/faq/single-faq/how-many-layers-and-nodes-do-i-need-in-my-neural-network
嗨,Jason,
精彩的教程,它确实帮助我入门了。
我有一个关于多个并行系列的问题。并行是否意味着输入特征和输出在列之间被视为独立的?
具体来说,使用一个 3 特征向量和 4 个步长作为输入
[ [F1_t1, F2_t1, F3_t1],
[F1_t2, F2_t2, F3_t2],
[F1_t3, F2_t3, F3_t3],
[F1_t4, F2_t4, F3_t4] ]
来预测
[F1_t5, F2_t5, F3_t5]
F1(从 t1 到 t4)是否对预测 F2_t5 或 F3_t5 没有影响?
此外,在输入是 N 特征向量并使用 3 个时间步来预测 M 特征(多对一)的情况下,如何处理组合多个输入和多个并行系列?其中 M < N(并且 M 特征包含在 N 特征中)。
另外,关于将此与分类数据一起使用的文献有什么建议吗?我尝试对其进行编码为数值,但它们未被视为类别。
不,并行输入意味着随时间测量的独立输入变量。也许这会有所帮助
https://machinelearning.org.cn/taxonomy-of-time-series-forecasting-problems/
上面教程中有关于多输入和多输出的示例。
是的,尝试序数编码和独热编码,然后与嵌入进行比较。
https://machinelearning.org.cn/how-to-prepare-categorical-data-for-deep-learning-in-python/
嗨,Jason,
我刚开始学习 LSTM,你能为每种类型的可视化提供相关的拓扑图吗?
是的,请看这个
https://machinelearning.org.cn/models-sequence-prediction-recurrent-neural-networks/
嗨,Jason,
非常感谢您的辛勤工作和提供的精彩教程。我非常享受!
我对 LSTM 没有太多经验,所以我在定义方面已经遇到了问题,这些问题对大多数读者来说可能很清楚。对于 Vanilla LSTM,您说您使用了 50 个 LSTM 单元。这是否意味着我有一个 LSTM,其输入是 3 维的,输出是 50 维的,还是我实际上有 50 个 LSTM 接受 3 维向量和 1 维输出?
是的,50 个单元,每个单元都接收完整的输入并产生一个输出。
嗨 Jason,您提到“Vanilla LSTM 用于单变量时间序列预测并进行单次预测。”,是否有可能预测多个变量?我该如何修改以进行 5 次预测?
是的,上面教程中有关于多步的示例。
另外,请看这个:
https://machinelearning.org.cn/faq/single-faq/how-do-you-use-lstms-for-multi-step-time-series-forecasting
非常棒的帖子。非常开导人。
谢谢!
嗨 Jason
我需要帮助,我正在做一个关于视频数据集的 HAR 项目,你能帮我做一个模型吗?
它使用 cnn-lstm。
也许这会给你一些想法
https://machinelearning.org.cn/cnn-long-short-term-memory-networks/
你好,Jason。
干得好,我构建了一个模型,它的表现很好,但是当我关闭程序,重新打开运行时,它的表现就不一样了,但当我重启电脑就可以正常工作,是什么原因造成的?我该如何避免这种情况?您的回答将非常有价值。
我以前没听说过这种问题,抱歉。
也许可以尝试在 stackoverflow 上发帖分享你的经验?
谢谢
不客气。
你好,Jason
我想知道我们如何知道准确性并获得某种 validation_data(在 model.fit 中使用的参数)。
以便获得训练和验证的损失和准确性曲线。
您能给我一些指导吗?
非常感谢
我建议使用此处描述的滚动预测交叉验证。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
这是此处大多数教程中使用的过程。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
你好 Jason,
感谢您的宝贵努力。
您认为 TS 深度学习在应用于股票市场预测时已经证明了自己的成功吗?
不行。
看这里
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
还有这个。
https://machinelearning.org.cn/findings-comparing-classical-and-machine-learning-methods-for-time-series-forecasting/
当我训练模型时,它有一个二维输出——它是 (none, 1),对应于我试图预测的时间序列。但是,每当我加载保存的模型进行预测时,它都有一个三维输出——(none, 40, 1),对应于网络输入训练数据集的重塑。哪里出错了?
代码如下:
df = np.load(‘Principal.npy’)
# Conv1D
#model = load_model(‘ModeloConv1D.h5’)
model = autoencoder_conv1D((2, 20, 17), n_passos=40)
model.load_weights(‘weights_35067.hdf5’)
# summarize model.
model.summary()
# 加载数据集
df = df
# 分割为输入 (X) 和输出 (Y) 变量
X = f.separar_interface(df, n_steps=40)
# THE X INPUT SHAPE (59891, 17) length and attributes, respectively ##
# conv1D input format
X = X.reshape(X.shape[0], 2, 20, X.shape[2])
# 进行预测
test_predictions = model.predict(X)
## test_predictions.shape = (59891, 40, 1)
test_predictions = model.predict(X).flatten()
##test_predictions.shape = (2395640, 1)
plt.figure(3)
plt.plot(test_predictions)
plt.legend(‘Prediction’)
plt.show()
这将有助于解决形状问题——它适用于 LSTM 和 1D CNN。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
你好,
非常感谢您的回复。不过,这并没有帮助。我已将 Conv1D 的输入大小从 (2, 20, 17) 更改为 (40, 1, 17),但它不接受——它告诉我它有负维度。我不明白为什么在训练网络时不会发生这种情况,而在使用保存的模型进行预测时却会发生。
层(类型) 输出形状 参数 #
=================================================================
time_distributed_14 (TimeDis (None, 4, 1, 24) 4104
_________________________________________________________________
time_distributed_15 (TimeDis (None, 4, 1, 24) 0
_________________________________________________________________
time_distributed_16 (TimeDis (None, 4, 1, 48) 9264
_________________________________________________________________
time_distributed_17 (TimeDis (None, 4, 1, 48) 0
_________________________________________________________________
time_distributed_18 (TimeDis (None, 4, 1, 64) 12352
_________________________________________________________________
time_distributed_19 (TimeDis (None, 4, 1, 64) 0
_________________________________________________________________
time_distributed_20 (TimeDis (None, 4, 64) 0
_________________________________________________________________
lstm_3 (LSTM) (None, 100) 66000
_________________________________________________________________
repeat_vector_2 (RepeatVecto (None, 40, 100) 0
_________________________________________________________________
lstm_4 (LSTM) (None, 40, 100) 80400
_________________________________________________________________
time_distributed_21 (TimeDis (None, 40, 1024) 103424
_________________________________________________________________
dropout_2 (Dropout) (None, 40, 1024) 0
_________________________________________________________________
dense_4 (Dense) (None, 40, 1) 1025
=================================================================
也许你的代码中存在 bug。
我很乐意提出一些建议
– 考虑积极地将代码削减到最低限度。这将帮助您隔离问题并专注于它。
– 考虑将问题削减到只有一个或几个简单示例。
– 考虑寻找其他类似的代码示例,这些示例有效,并缓慢修改它们以满足您的需求。这可能会暴露您的错误。
– 考虑将您的问题和代码发布到 StackOverflow。
让我告诉你我是如何暂时解决这个问题的。
我使用了您的 split_sequences() 来处理多元和 40 个步长。因此,对于数据集,我取了 ith+40 步,然后是 ith+1+40 步,依此类推。它总是将每个子序列的最后一个项目作为新项目,其余的项目与前一个子序列相同。
输出层,出于某种我仍然无法弄清楚的原因,它正在预测每个子序列。然后我设计了一个函数,它获取每个子序列的第一个项目。
def separador_output(sequence)
X = list()
for i in range(len(sequence))
x = sequence[i][30]
X.append(x)
return np.array(X)
结果是,我得到了我试图复现的 1 维时间序列。
我分享这一点是因为我仍然认为有一种方法可以在不引入上述函数的情况下做到这一点。
此致!
也许可以编写自己的函数来按照您需要的方式准备数据?
这可能是一个有用的起点。
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
感谢您提供的精彩文章!
我正试图按照您在本文中概述的策略,对时间序列数据执行 LSTM 模型。
我有一个输入(特征)在过去的多个时间点,我使用您的代码“split_sequence()”将单变量序列分割成多个样本,每个样本都有指定的步数和一个输出。
我需要标准化我的“训练”数据集,为此我计划使用 StandardScaler(根据您其他精彩的文章,包括:https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/)。我正在执行标准化,然后在分割成多个样本以用于 LSTM 之前。这似乎很简单(但如果您认为此计划不合适,请评论)。
问题在于,在任何给定的时间点,我的单个输入特征实际上都有多个值,每个值都源自许多“相关但独立”的来源之一。虽然我可以单独地对每个来源执行 LSTM,但我想通过对所有来源的聚合数据执行 LSTM 来尝试最大化我的样本量(因为这些来源似乎彼此遵循相似的行为,但不一定在同一时间窗口内)。或者至少我想看看那个聚合模型的执行结果是什么样的。我唯一的问题是:是分别对每个来源执行数据输入标准化(这样每个来源都被标准化为均值为零、标准差为 1,并在模型中具有相等的权重)更好,还是在聚合数据中一次性对所有来源进行标准化更好?
(我对机器学习相对较新,所以如果我的问题有点天真,我先致歉。)
感谢您的想法。
Jim
每个特征或“时间序列”变量都需要单独缩放。
我明白了“特征”。
“时间序列”变量:您是指您示例中“split_sequence()”函数创建的每个单独序列都单独缩放吗?
谢谢!
不,是指原始数据中的每个序列。
你可以在这里了解更多
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嘿,Jason,感谢您写了这么有用的博客。你能帮我解决一个情况吗?
我的数据包含固定大小的输入(1, 16, 2),但输出的时间步数不同。我的意思是,一个可能是(1, 2, 2),另一个可能是(1, 20, 2)。我考虑使用编码器-解码器格式。但是问题在于确定“repeatVector()”的维度。我该如何做?
是否可以为每个输入调整其大小?
也许可以尝试将所有输出序列填充到相同的长度,然后使用编码器-解码器模型来处理该长度。
教授,请解释一下
为什么在多个输入序列中,输入形状是(3,2),而在多个并行序列中,输入形状是(3,3)?
本教程将帮助您理解 LSTM 的输入形状。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
关于 EarlyStopping、ModelCheckpoint 和 ReduceLROnPlateau 函数与 LSTM 的使用。另外,我想在我收到数据后更新我的模型。我的意思是,我想在每次新数据到来后训练我的模型。我该如何做?
是的,尝试一下,看看它们是否能提高性能。
您是否需要测试数据是否拟合?
抱歉,您确切地指什么?
嘿 Jason,写得非常好!
我有一个关于您下面 1DConv LSTM 网络的问题。
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation=’relu’), input_shape=(None, n_steps, n_features)))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(50, activation=’relu’))
model.add(Dense(1))
我对在序列数据上应用具有 1D 核的卷积的直觉是什么?这涉及到什么?它是否等同于将单个值作为特征来表示输入序列?
感谢这个资源!
谢谢。
它试图从序列中提取模式。
这不就是将在整个序列上等同地应用相同的常量滤波器,然后用某个常量对其进行转换吗?
每个滤波器都会从序列中提取不同的模式——就像滤波器从图像中提取模式一样。
嗨,Jason,
LSTM 模型在多步预测长度方面的限制是什么?例如,如果我们有 N 个样本和 M 个特征,并且我们正在预测一个一维变量的 K 个未来样本。是否有方法可以将 N、M 和 K 联系起来?或者有没有快速的经验法则来说明 K 能有多大而不会变得没有意义?
谢谢!
你预测的未来越远,错误就会越多地累积。
更难的问题更具挑战性,需要进行预测。
这就是我们可以说得如此普遍的——您需要测试特定模型在特定数据集上的表现才能了解更多。
嗨,Jason,
有没有一种方法可以选择最佳的 n_steps_in?我知道我需要进行为期 3 天的预测,并且我有 1 年的数据(8760 个观测值)。
测试您数据集的不同值,并使用产生最佳平均性能的配置。
教授,您能否编写相同的代码以用于函数式 API?
感谢您的建议,也许这会有所帮助。
https://machinelearning.org.cn/keras-functional-api-deep-learning/
谢谢 Jason 博士,
这对我来说非常有帮助。
我已经将其应用于我的数据集
https://www.kaggle.com/abdulmeral/rnn-4-models-for-lstm
干得好!
我的天哪,我的天哪,我的天哪,我去年刚毕业,实习的时候,我在那里学习了机器学习的奇妙之处。一年来,我看了很多教程,说什么都听,然后花几个小时去尝试运行那些没用的东西。然后我看到了这个,我的天哪,我停不下来。这就是我想要的。就是它了,我只想要一个我可以自己运行的简单代码,我不需要百万行的解释。我只想知道什么能起作用。你,先生,是我的英雄。我非常感谢你,从心底里感谢你,我真的觉得我不配你这样慷慨地提供免费可用的知识。谢谢你,Jason Brownlee 博士,我的英雄。
干得好!
Brownlee 教授,是什么让您在 LSTM 上使用 relu 激活函数?当我测试我自己的项目时,损失值呈天文数字般增长(例如,损失:2382585115.4067 精度:0.23)。
当我从 LSTM 中移除 relu 函数时,它运行得非常顺畅。您能多解释一下这个话题吗?
我发现当不缩放输入时,relu 在 LSTM 中效果很好。
如果它对您的数据效果不好,就不要使用它。找到最适合您项目的方法。
嗨,Brownlee 教授,
感谢您这项出色的工作。
我正在思考为什么当我使用“多输入多输出”并只选择 1 个 n_steps_out 时,结果与我只进行简单的多输入序列预测下一个输出的结果不一致?
结果应该是一样的,对吧?
谢谢你,
这些模型和数据在这种情况下都很小,它们只是为了展示如何使用它们,而不是真正解决微小的预测任务。
大家好。
感谢 Jason 先生。
我回顾了该网站的一些示例(飞机乘客和洗发水),并且我对时间步长和特征的概念完全感到困惑。
这里我们假设数据是这样的
X, y
10, 20, 30 40
20, 30, 40 50
30, 40, 50 60
然后得出时间步长是 3,特征是 1。
但对于洗发水销售预测,我们总是将数据形状更改为
X = X.reshape(X.shape[0], 1, X.shape[1])
无论我们在模型中使用了多少滞后。这意味着我们假设时间步长为 1,特征等于滞后数。
如果有人能帮助我理解这些概念,我将不胜感激。
是的,这是一个棘手的话题,我相信这会很有帮助。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
Jason,感谢您写了这么好的文章。
我有一组数字序列,被标记为“好”或“坏”。我需要构建一个模型,这样,给定一个新序列,它可以根据训练将其分类为“好”或“坏”。我不确定使用什么模型,因为我需要分类,而不是预测下一个值。
这就像用图片对狗和猫进行分类,但我们不是用图片,而是用数字序列,其中顺序很重要。
谢谢!
这听起来是一个很棒的项目!
这里的序列分类教程将帮助您入门。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
非常感谢您提供这些信息。准备数据总是一项艰巨的任务。我有一个聊天数据集,我想用它来创建一个聊天机器人。我该如何为编码器-解码器模型准备数据?
好问题,这取决于您模型的具体情况。
也许可以为输入和输出序列准备整数序列(序数编码的单词)。
你可以在这里看到例子
https://machinelearning.org.cn/start-here/#nlp
嘿 Jason,非常感谢您写这篇文章。我真的很喜欢这篇文章,并学到了很多东西。
我有一个时间序列数据,我有 60 个输入数据点,并且我需要在 LSTM 的最后一个层预测 1 个输出,所以基本上我想让我的 LSTM 如下:
第一天数据——> lstm_unit1——>第二天数据——>lstm_unit2——>……第 60 天数据——>lstm_unit60——>denseLayer——>output。
大致是这样的,
数据是—— [1,2,3,4….60],而输出只是一个单一的值,例如 5.6。如何使用 Keras 构建这个模型?
这将帮助您准备数据。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨,Jason,
如果我有一个时间序列,比如有 600000 个时间步作为输出,以及 3 个时间序列作为 3 个特征,它们长度相同。然后我从数据中形成序列(比如一次连续 60 个特征,第一个序列是 1-60,第二个是 2-61,第三个是 3-62,以此类推),现在我想将它分成训练集和测试集。
如果我将序列进行洗牌(在序列内部,所有点仍然按时间顺序排列),然后将数据分成 80% – 20% 的训练测试集,这样可以吗?还是会导致数据泄露到测试集?
是的。
Jason,对不起我提问时表达不清。您对以下哪项说了是?
1. 可以洗牌吗?
2. 数据泄露到测试集?
非常感谢!
如果您洗牌序列然后训练模型,很可能会导致数据泄露和对模型性能的乐观评估。
在大多数情况下,我们必须使用前向验证。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
谢谢 Jason!????
不客气。
也感谢您和所有其他文章!
不客气!
是否有任何关于 R 中的 LSTM + 时间序列的教程?
致以最诚挚的问候
抱歉,我没有 R 中 LSTM 的示例。
嗨!您做的这个网站太棒了!非常有帮助。
我有一个问题:训练样本的顺序重要吗?
例如
product_id | day_1 | day_2 | day_3 | day_4 | day_5 | day_6
1 | 10 | 3 | 2 | 5 | 9 | 10
2 | 11 | 5 | 2 | 4 | 3 | 2
3 | 14 | 8 | 5 | 0 | 2 | 14
4 | 10 | 0 | 1 | 5 | 1 | 1
训练数据集
[10,3,2,5] -> [9,10] #商品 1
[11,5,2,4] -> [3,2] #商品 2
[14,8,5,0] -> [2,14] #商品 3
[10,0,1,5] -> [1,1] #商品 4
(更准确地说,我有 x 件商品,每天的销售量为 z,我想让每件商品成为一个训练样本,但这样做的话,天数会为每件商品重复,这是否正确?或者我应该构建一个包含所有商品的训练样本?)* 我提到我实现了滑动窗口方法来构建每个商品的训练集。
谢谢!
是的,样本的顺序可能很重要,包括在划分用于训练/评估的数据时,以及在训练集和测试集本身内部。
在 model.fit 中,样本是自动洗牌的,所以这种情况下样本(商品)的顺序(在训练中)仍然重要吗?
嗨,Jason,
您能否就这个用例提供您的看法?我正在处理一个多元、多步的时间序列问题,以预测每个城市的需求量。我从您的教程中了解到如何将 LSTM 与向量输出用于此类问题,但我如何处理按城市进行预测?我读到的一种方法是为每个城市构建单独的模型,然后在最后将它们连接起来。您有什么看法?您是否有可以参考的文章?
您的博客一直是我解决所有问题的“首选”解决方案。感谢您分享知识并保持简单!
好问题,这将给您一些启发。
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
非常感谢这篇文章,您能简要解释一下如何使用 Deeplearning4j 库在 Java 中执行相同的操作吗?
抱歉,我没有 Java 的示例。
嘿,Jason
感谢这篇文章。您能否帮助我为 CNN LSTM 模型调整多并行序列的数据形状?如果您能提供一个 Python 函数,那就太好了。作为初学者,理解不同模型所需的数据形状有点棘手。谢谢。
是的,请看这个
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨,Jason,
当使用字符串数据作为输入时,我们应该怎么做?
我收到错误,说字符串数据无法转换为浮点类型。
我该如何解决这个问题?
如果字符串代表分类输入,您可以对其进行编码。
https://machinelearning.org.cn/how-to-prepare-categorical-data-for-deep-learning-in-python/
否则,您可以使用词袋模型或嵌入。
https://machinelearning.org.cn/start-here/#nlp
嗨,Jason。感谢您提供如此有用的博客和帖子。
我正在做一个项目,用于预测各国/地区的 COVID-19 增长。我的计划是使用训练中选择的一些国家的数据,并仅用一个国家进行预测(数据集:https://github.com/datasets/covid-19/blob/master/data/time-series-19-covid-combined.csv)。这在帖子中介绍的知识范围内是否可行?如果可行,我需要应用哪种类型的时间序列?单变量?多变量?多步?
此致,
Higo
更具体地说
我想使用“Confirmed”、“Recovered”和“Deaths”来预测“Cases”(最终预测“Deaths”)。
增长率可以直接用指数函数建模,在 Excel 中使用 GROWTH() 函数。
Jason,感谢您的回复,但我认为我没有很好地表达自己。
我的项目打算使用来自特定国家/地区的已确认病例、康复患者和死亡人数的数据来训练 LSTM,然后尝试预测另一个国家/地区的病例数。数据集就是我第一个评论中提到的那个。
例如:使用澳大利亚、哥斯达黎加、希腊、匈牙利和以色列的数据(从 2020-01-22 到 2020-06-15)训练 LSTM,然后尝试预测巴西的病例数(这里我想尝试两种方法:一种是在同一范围 2020-01-22 到 2020-06-15 的预测验证,另一种是针对预测未来病例,即超出 2020-06-15 日期)。
帖子中介绍的哪种方法我应该使用?对我来说还不清楚哪种是最好的。
提前感谢。
这听起来是一个很棒的项目,我想这可能会给你一些想法。
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
您好,先生,
我想知道,如何在一阶 LSTM 模型中获得下周的预测结果?在这个网站的示例中,我们只能得到单个预测值。
您能在这个场景中帮助我吗?
看这里
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
嗨,Jason,
感谢您发表了这篇有价值的文章。我有一个关于多步 LSTM 模型的问题。我一直在尝试将 CNN-LSTM 应用于多步模型,但我对如何将 [sample, timesteps] 重塑为 [sample, subsequences, time steps, features] 感到有些困惑。
堆叠 LSTM 的示例代码是
X = X.reshape((X.shape[0], X.shape[1], n_features))
但在 CNN-LSTM 的情况下,我们需要为 CNN 模型提供子序列的数量。但每当我输入 n_seq=2 并运行代码时
X = X.reshape((X.shape[0], n_seq, X.shape[1], n_features))
就会出现错误:ValueError: cannot reshape array of size 15 into shape (5,2,3,3)
您能否帮我解决这个问题?
先谢谢您了。
不客气。
您可能需要尝试不同的输入形状,这些形状可以被每个样本中的时间步数整除。
嗨,感谢您做出如此出色的解释。
我有另一种情况,假设我
20 33
30 43
40 53
50 63
60 ?
因此,我需要预测一个时间序列,但需要借助我已有的另一个时间序列,最好的方法是什么?
我建议您尝试一系列不同的模型和配置,以找出最适合您数据集的方法,这可能会有帮助。
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
嗨 Jason,非常感谢您所有的工作!
拥有一位像您这样才华横溢的教育家来教授机器学习的实际应用,真是一种祝福。
我使用了这个教程为 COVID 19 进行了时间预测。
我想知道,我是否可以使用不同的数据生成器(在我具体实践的案例中:国家)来学习其行为?
在您对洗发水销售的示例中:我可以使用不同公司的销售数据来预测吗?
还是我必须为每个数据生成器拟合一个网络?
不客气!
好问题,是的,这会给你一些想法。
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
你好,
我正在测试一些预测算法,包括 LSTM 模型。因此,我想了解它在内存和计算时间方面的复杂性。
所以,如果允许的话,以上示例中单变量时间序列预测的复杂度是多少?
非常感谢。
我不确定,抱歉。您可能需要查阅文献,看看是否有人估计过该方法的大 O 表示法。
嗨,Jason,
我有一个有点复杂,但我不认为罕见的预测问题想解决。
示例描述
假设我们进行地面气象测量,但也在 15 公里高空进行测量。在过去的两年里,我们每天都开始使用探空气球来测量 15 公里高空的压力。探空气球很昂贵,而且对环境不太友好,所以我们想减少所需的探空气球数量。
想法
从现在开始,我们可以只在周日开始放飞探空气球。在接下来的六天里,我们可以根据每天地面层的实际测量值来预测 15 公里高空的压力,而在周日,我们可以使用真实世界测量值来“重新校准”我们的模型。
这对我来说是可行的,但我不知道从哪里开始。
我的第一个想法
并非我想要的,但有可能
将过去一周的所有输入数据(周日+?周一-周日)放在一个特征集中,并构建一个标准的 RNN 来预测周一至周日的 15 公里高空压力。我认为这会奏效,但那样我只会得到上周的值。如果我想得到今天的估计值,我就看不到方法了。
我认为许多流程可以通过这种方式进行优化。在工业生产中也是如此,一个批次的产品通常具有相当一致的特性。如果我们基于一些简单的测量值来预测需要很长时间才能完成的校准测量值,我们可以大大缩短生产时间。
您有什么关于如何开始构建此类模型的想法吗?您知道有任何好的书籍有类似的例子吗?
祝好,
Julian
听起来像一个有趣的项目。
一般来说,我建议您对您能想到的每种方法进行原型设计和评估,而不是预先猜测什么可能最好——以结果来指导您。
感谢您富有洞察力的工作。
为什么输入形状包含步数?
model.add(LSTM(50, activation=’relu’, input_shape=(n_steps, n_features)))
model.add(Dense(1))
似乎输入的实际形状也可以完成工作。
model.add(LSTM(50, activation=’relu’, input_shape=(X.shape[1], n_features)))
再次感谢。
您可以两者都使用,只要模型与数据匹配即可。
很棒的教程,您的工作一直对我很有帮助。我正在尝试为皮带传动开发一个预测模型。在这种情况下,我的时间序列数据不一定是用于预测,而是训练模型根据新的时间序列数据预测皮带传动的状态。LSTM 仍然是最优的吗?或者您是否推荐了两种或三种适合这种情况的神经网络?
不客气。
好问题。我建议测试一系列算法和算法配置,以找出最适合您特定数据集的方法。
嘿 Jason,我非常喜欢您的教程!您认为,是否有“正确”的数据点数量(例如,行数)可以输入到 LSTM 模型中?我正在考虑使用大约 500,000 到 100 万个数据点,我想知道这是否太多了,以及使用小型数据集与非常大的数据集之间的限制是什么?
谢谢,我喜欢您的网站!
谢谢。
好问题,这可能会有帮助。
https://machinelearning.org.cn/much-training-data-required-machine-learning/
你好 Jason,
非常感谢您的精彩教程,它们一直非常有用。
我对 LSTM 的计算过程感兴趣。我熟悉 LSTM 中使用的所有公式,但我不确定 Vanilla LSTM 示例中每个计算步骤的输入是什么。
例如,假设输入时间序列是 [30, 40, 50]
所以,在第一步,使用 C_{0}(单元记忆),H_{0}(单元输出)和数字 30(来自上面的时间序列),我们计算 C_{1} 和 H_{1}。
接下来,使用 C_{1}、H_{1} 和 40 来计算 C_{2} 和 H_{2},依此类推,对吗?
我有点困惑,因为在句子时间序列中,每个词可以表示为一个独热向量,在这种情况下,句子将是独热向量的时间序列,并且在每个计算步骤中,公式中的输入将是一个独热向量。
此致,Enes
不客气。
好问题,这会有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
还有这个。
https://machinelearning.org.cn/faq/single-faq/how-is-data-processed-by-an-lstm
嗨,Jason,非常感谢您的精彩教程。
我正在使用多变量、多步编码器-解码器 LSTM。在我的情况下,输入步数、输出步数和 n_features 分别是 150、15 和 11。但我有非常多的时间步长(约 100,000)。
因此,使用输入 [100000, 150, 11] 和输出 [100000,15, 11] 进行训练。我将 epoch 设置为 50,并在 4 小时后获得了模型。但发现在这个模型上所有的预测结果都保持不变,即 [0, 15, 11]、[1, 15, 11]、[2, 15, 11]……都一样。
如果您能给我一些可能的原因让我检查,我将不胜感激。
谢谢!
时间步长太多了。我建议将序列拆分。
https://machinelearning.org.cn/handle-long-sequences-long-short-term-memory-recurrent-neural-networks/
嗨 Jason,非常棒的文章!!!
我有一个数据集,包含 3 年的历史降水和辐射数据。
以上哪种模型更适合用于同时预测这两个变量?
这些数据足够用于预测吗?
我如何从最后一个数据集日期预测本月的未来 30 天?
抱歉提出这么多问题!
也许可以从这个框架开始。
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
你好
我有一个 EEG(脑信号)数据集,我想用于分类。每个受试者(患者)都连接了 64 个电极,每个电极记录了 5012 个样本。这样,每个受试者都有 64 个 5012 个样本的序列和一个类标签。同样,有 108 名这样的受试者。
您能建议一种适用于分类的正确深度学习方法吗?
我建议测试一系列不同的问题框架、模型、模型配置和数据准备方法,以找出最适合您特定数据集的方法。
这里的教程将帮助您入门
https://machinelearning.org.cn/start-here/#deep_learning_time_series
我有一个关于构建测试框架以测试 LSTMs 与不同其他模型的问题。
我的数据结构如下:
输入:天气信息、施工工程、道路网络中的事故。
输出:通过计数器的车辆。
早晨发生的事故会影响下午的交通,早晨由于这些事故产生的交通模式也会受到影响。因此,我认为 LSTM 可以有所帮助。但我想与更简单的模型进行测试。
我想象模型性能在一天中的不同时间会有所变化,因此我的性能度量将是一个图,显示模型在一天中的误差分布,因为测试集将包含多天。
我卡住的地方是训练部分:我选择了过去几年中的一些特征日来传递给模型。我认为从一天到下一天的影响不会溢出,因为夜间几乎没有交通。因此,实际上我的训练数据集包含一些将被单独处理的日子。这样我就不必传递多年的数据,但可以为典型日期选择并只在这些日期上训练。我该如何将这些传递给模型,同时避免“记忆”从前一天获取信息?”
我应该只使用一个 model.fit(X, y),我在 X 中添加一个代表日期的虚拟变量吗?我认为这似乎不是一个好的做法。如果我不专门指出日期,模型可能会认为前一天的神经网络状态会影响第二天。
或者拟合模型多次,例如
for day in sample_days
model.test(X_day, y_day)
抱歉,上一个代码片段有误。应该是
for day in sample_days
model.fit(X_day, y_day)
也许您可以使用直到您想测试的那一天的所有先前数据作为训练,然后测试保留的那一天。为要评估的每一天重复此操作。
你好 Jason,感谢您的教程,非常有帮助。我现在正在处理面板数据,也就是说,我在不同时间观察了几个个体的一些变量。我有一个包含 719 个个体和 11 个变量的数据集,这些变量每天观察 10 年(2010 年至 2019 年)。
可以对这些数据应用 LSTM 模型吗?
如果可以,如何准备数据(重塑)?
谢谢你。
如果每个个体都是一个时间序列,并且您想跨个体学习,LSTM 可能是合适的。
这将帮助您准备数据。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
谢谢 Jason,Emmanuel。我阅读了数据准备方面的链接——非常有帮助。我有一个需要澄清的问题。
我拥有 200 家不同公司的面板数据,每家公司都属于一个不同的行业,共有 12 个不同的行业,用数字 1-12 标记。
对于每家公司,有 8 种不同的价格信息,例如价格、市值、交易量等。
然后我有一列是未来公司股票价格,比当前日期晚 10 天。我的目标是预测这一列。
日期范围是从 2010 年到 2012 年。每周,所有 200 家公司的 104 个日期。
我的理解是,这意味着 200 个样本,104 个时间步长,9 个特征,包括落后 10 天的股票价格。
这是否意味着我需要训练 200 个不同的模型?如果我拿到这个数据集,您会如何处理这个问题?
如果这是一个愚蠢的问题,我很抱歉。我是机器学习新手。
嗨 Guanta……您可能想考虑多变量 LSTM 模型。
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
嗨,Jason,
您的回答一直激励着我。我一直很感谢。
请问我有一个问题。
我正在处理一个股票价格预测问题。
假设(t-当前时间,t+1-未来时间),我准备的数据集如下:Xt -> Yt+1,这样数据将当前特征输入与价格的未来变化联系起来。
据我所知,RNN 试图映射 Yt -> Yt+1。在我的案例中,我不能将(Yt+1, Yt+2,…)包含在训练集中,因为在使用训练模型进行预测时;这些将是未知的未来值,无法输入模型。
另一方面,使用 Xt -> Yt 的数据集并不包含核心信息:股票的未来价格变化,以便能够预测它。
您有什么建议?
如何利用例如:Xt-n, … ,Xt, Yt-n,…,Yt 来预测 Yt+1?
谢谢。
我认为股票价格是不可预测的。
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
谢谢 Jason,我知道您对股票价格预测的看法,但我只是为了学习目的收集了该领域的数据。我正在尝试学习更多关于时间序列预测的知识。如果您能回答我上面的问题,我将不胜感激,因为它对我更好地理解 RNN 的使用至关重要。
Malik
抱歉,我不确定您的问题。
回想一下,您对模型的输入和输出的选择有完全的控制权。尝试一系列不同的问题框架,并找出最适合您数据集的方法。
也许可以尝试使用您拥有的任何和所有数据来建模目标。然后,一旦您有了可行的方案,尝试删除/剔除数据并查看它对模型性能的影响。
如果您的问题是关于准备数据的机制,也许这个教程中的函数会有帮助。
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
嗨 Jason,我的时间序列眼睛数据,如直径、眨眼次数、注视持续时间,并且每个特征都有不同的阈值,例如直径大于 3.5 表示眼睛的认知负荷高。我可以使用哪种 LSTM 来测量认知负荷?或者任何其他 ML 是否适合这个问题?
我建议测试一系列不同的模型和模型配置,而不是列出 LSTM,以找出最适合您特定数据集的方法。
嗨,Jason,
感谢您的建议。
我没有地面真实数据。我正在用设备记录数据,并且我正在考虑让用户标记最近 2-3 分钟的录制数据。但是,用相同的标签标记许多行有一个缺点。是否有任何方法可以生成地面真实数据?
谢谢
您可以将每个候选答案视为一个单独的行,或者尝试使用众数或平均估计值来合并每一行。
谢谢你,Jason。
我非常喜欢您的文章,我已经购买了您的几本书,我觉得非常棒。
我有一个数据准备问题……。
我正在训练一个 LTSM 多分类模型;
我发现我的训练集中的类别(训练数据在时间上早于 val 和 test 数据)非常不平衡。
我特别对少数类感兴趣(它们的准确预测对我更重要)。
考虑到时间序列观测值的依赖性质以及我如何以批次进行训练(即使在无状态 LSTM 中,每个批次也保持状态)。
我是否正确地认为我不能对训练数据进行上采样或下采样来平衡类别(因为在这种情况下,省略或添加任何数据点(每个日期都有一个数据点)都会破坏批次中的时间序列)?
您对如何平衡我的训练数据集有什么建议吗?
感谢您的见解。
谢谢,
Simon
非常感谢您 Simon!
很好的问题。
首先,选择一个合适的指标,而不是准确率。
第二,尝试成本敏感的 LSTM(以及其他神经网络)。首先尝试平衡类别的权重,然后尝试更激进的过度纠正权重,看看是否能做得更好。
最后,尝试通过简单地复制少数类的输入模式并添加高斯噪声来对观测值进行采样——例如,一种初级的随机过采样形式。
告诉我进展如何。
Jason,您提出了绝妙的建议,谢谢!
我会尝试的,我从您那里学到了很多东西,并感谢您的解释。
不客气。
非常感谢您的文章,我一直在学习深度神经网络和 LSTM,这极大地帮助我深入理解并构建自己的时间序列分析模型。
不客气!
嗨,Jason!
我一直很欣赏您的博文。它们帮助我理解 DNN 的深层思想以及珍贵的示例代码。
现在,我在处理多变量-多步时间序列预测问题的 CNN + LSTM 模型时遇到了一些困难。
我通过实验在 LSTM 层之前添加了 CNN,并且您的博文让我意识到我需要在 LSTM 层之前的层使用 TimeDistributed 包装器。为此,我进行了如下输入重塑,以及 x 验证集。
[添加 CNN 之前]
InputLayer(input_shape=(x_train.shape[1],x_train.shape[2]), batch_size=BATCH_SIZE))
x_train.shape[1]:时间步长(例如 600)
x_train.shape[2]; 特征数(例如 4,因为它是多变量的)
batch_size:我将其指定为 128 或 256,因为 LSTM 参数中 stateful=True。
[现在]
InputLayer(input_shape=(x_train_multi.shape[1],x_train_multi.shape[2],x_train_multi.shape[3]), batch_size=BATCH_SIZE)
x_train.shape[1]:子序列(例如 600)
x_train.shape[2]:时间步长(例如 1)
x_train.shape[3]:特征数,无变化。
batch_size:无变化。
我调整了 [1]:[2] 的比例,然后发现 600:1 是最好的。
毕竟,以下是我当前的模型片段。
model.add(InputLayer( “如上所述” ))
model.add(TimeDistributed(Conv1D(filters=200, kernel_size=3, strides=1, padding=”causal”, activation=”relu”)))
## model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(150, stateful=True, return_sequences=True))
model.add(LSTM(150, stateful=True, return_sequences=False))
model.add(Dense(150, activation=’relu’))
model.add(Dense(8)) # 预测 8 个时间点
“fit()”正常工作,并且准确率与添加 CNN 之前几乎相同。
但是,当我启用 Conv1D 层之后的 MaxPooling1D 层时,该层会抛出与输入形状相关的 ValueError。当我删除 Conv1D 参数中的“padding=”causal””时,Conv1D 也会抛出相同的 ValueError。
抱歉这个长问题,但如果您发现任何错误的部分,尤其是关于输入形状,请给我您的评论。
谢谢你。
干得好!
抱歉,我没有一个很好的即时答案。您需要为您的项目调整模型,包括确保架构与流经模型的数据形状良好匹配。我无法为您调试模型。
感谢您的回复,Jason!
您的评论让我很开心,因为我是办公室里唯一做 ML 的人。
我找到了这个 ValueError 的原因。这是因为 MaxPooling1D 的大小必须大于“时间步长”。正如我上面所说,我将原始时间步长 600 重塑为 600 x 1(子序列 x “时间步长”,在 [样本,子序列,“时间步长”,特征] 中)。
它必须是 300 x *2*(或更多),因为池化大小是 *2*。
但是没有错误并不意味着它是正确的。我希望这能奏效。
Shinichiro Imoto,做得好!
嗨,Jason,谢谢您的教程。我有一个问题,我想预测洪水,但我的数据不是连续的,例如,对于 2019 年,我有 5 月份的第 8 周数据,对于 2020 年,我有 3 月份的第 6 周数据。我该如何进行预测?
这可能有帮助
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
抱歉 Jason,我读了很多遍,也看了上面人们问的一些问题。我还是不明白使用 RepeatVector 与 LSTM 的 return_sequence = True 有什么区别?有没有一种简单的方式来理解主要区别?我想了解什么时候使用每种方法是理想的。
非常感谢!
Repeat vector 在解码器创建每个输出步骤时使用来自编码器的相同的单个输出向量。
Return sequences 是编码器每个输入时间步的输出。
嗨,Jason,
感谢您写了这篇精彩的帖子!
我尝试了您示例中的多步“向量输出模型”,使用了完全相同的数字、相同的代码。一些重要的数据
raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90]
n_steps_in, n_steps_out = 3, 2
x_input = array([70, 80, 90])
print(yhat)
[[124.500435 137.70433 ]]
正常情况下 yhat 应该接近 100 和 110。您能否解释一下发生了什么或者可能出了什么问题?
顺便说一句,我正在运行 Keras ‘2.3.0-tf’。重新运行模型会改变数字,但它离 100 和 110 还很远。
好问题,请看这个
https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code
我将回到您的多步 LSTM 示例。
您在示例中有以下参数
raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90]
n_steps_in, n_steps_out = 3, 2
我想知道,最多可以预测多少个多步?
假设我有一个包含 100 个时间点的序列。什么是最大可靠的多步预测和最有效的 X 和 y 分割?
你好 Jason,
非常感谢您出色的工作。请允许我问您两个问题
a) 我能否使用例如 timestep = 5 的序列来训练(拟合)LSTM,但用 timestep = 1 的数据来预测网络?
b) 时间步长数量与隐藏层数量或每层神经元数量之间是否存在关系?
谢谢
此致
Armin
我看不出为什么不行。您可能需要在拟合模型后重新定义模型的输入层。
是的,这取决于数据集和模型。在您的情况下,运行敏感性分析以查看性能如何随模型容量变化。
非常感谢您,并致以巴伐利亚的问候。
不客气!
感谢您的算法。我有一个关于如何优化 LTSM 超参数的问题。是否有某种算法可以做到这一点?
是的,网格搜索或随机搜索是不错的开始。
我在理解LSTM的输入形状时遇到了困难。例如,我有50个视频,其中25个被归类为清醒(0),25个被归类为嗜睡(1)。我预处理了它们,提取了每秒的眼部纵横比(EAR)和口部纵横比(MAR)作为特征。
现在我的数据是(视频文件名,时间序列,EAR,MAR,标签)
Video1 1 0.30 0.25 0
Video1 2 0.31 0.27 0
Video1 3 0.35 0.25 0
Video2 1 0.30 0.25 1
Video2 2 0.27 0.28 1
Video2 3 0.31 0.29 1
Video2 4 0.33 0.30 1
我分别从两个视频的前3秒和4秒提取了上述数据,因为视频的长度可能不同。
我有一个非常基本的问题。我应该如何将这些数据输入LSTM?任何代码示例都可以。我知道输入形状应该是[Batch Size, Time Step, Features],但我很困惑该如何输入到LSTM,我是否应该在一个循环中输入每个视频的数据。
请帮助我解除我的疑惑。
这会有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
你好 Jason,
好文!
关于拆分序列方法用于多输入多输出,我有一个快速的问题。
在这一行,你只选择了X中的前两个特征和Y中的最后一个特征。
seq_x, seq_y = sequences [i: end_ix,: -1], sequences [end_ix-1: out_end_ix, -1]
为什么不包含X中的3个特征?
也就是说,使用这3个特征来预测其中第3个。
这会有问题吗?
谢谢你
你可以按你希望的方式构建预测问题。
也许这能帮助你理解如何重塑数据。
https://machinelearning.org.cn/time-series-forecasting-supervised-learning/
感谢Jason分享这篇精彩的文章!
不客气。
非常感谢您分享这些!我从您不同的帖子中学到了很多,尤其是LSTM。只是想知道您是否有关于使用LSTM进行异常检测的建议?谢谢!
谢谢。
是的,您可以使用LSTM进行时间序列分类,这会很有帮助。
https://machinelearning.org.cn/faq/single-faq/how-do-i-model-anomaly-detection
感谢分享!我很好地学习了LSTM模型,我想知道为什么你在“Multiple Input Series”部分使用了Vanilla LSTM,为什么我不能使用其他模型,如Stacked LSTM、Bidirectional LSTM或ConvLSTM。是因为输入的维度吗?
在某些情况下是的,在其他情况下是因为一个模型在给定数据集上比其他模型表现更好。
感谢分享,如何为任意时间步进行回归问题建模?例如:预测一个拐点,我们关心拐点何时出现以及在哪个时间步发生。例如:下一个预测的拐点12345发生在t+136。
这会是和上面一样的多时间步LSTM模型,还是一个完全不同的问题,我们该如何处理?
有很多方法可以解决这个问题,也许可以先尝试几种,然后找出最适合你的数据集的方法。
例如,时间序列分类——一个事件是否会在下一个时间段发生。
或者进行多步预测,然后使用if语句对预测进行后处理。
等等。
首先,感谢您分享这篇精彩的文章,我刚在LinkedIn上找到它。
目前我正在从事一个项目,我想预测未来三个月应该订购多少数量的材料。
我有20,000种材料(不同的时间序列)的采购数据,按月度计算,这些数据在季节性方面相互关联,但时间序列非常短(50-80个数据点)。
例如
日期 | 材料 | 数量 | 工作量 |
2020-08 | A | 20.0 | 0.8
为这种问题构建LSTM模型是否有意义?
作为回归器,我可以输入月份(用于季节性)以及本月的工作量。
我可以训练模型,使用所有时间序列和80-90%的数据点。(其余10-20%用于测试集)
也许有更好的模型?(S)ARIMA只是一个单变量方法,所以我无法输入工作量。
谢谢!
好问题,我建议评估一套不同的算法/配置,找出最适合您数据集的方法。
这个框架可能会有帮助
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
谢谢你的回复!
你有没有处理受COVID-19影响的时间序列数据的办法?
例如:我有一个从2017年到2020年的月度时间序列。
有两个月(2020年3月和4月)产量下降,所以这两个月的值很小,而且随后的几个月里也有一些高值,因为产量又上升了(总的来说,有4-6个月的异常值)。
我尝试了几种方法,但这些COVID-19的异常值使得预测(训练/测试)结果难以达到良好。
您有什么建议吗?
是的,请看这个
https://machinelearning.org.cn/faq/single-faq/how-can-i-use-machine-learning-to-model-covid-19-data
模型是仅用训练数据训练,还是每次预测时都将实际预测数据添加到训练数据中并重新训练模型?
如果您愿意,可以在新的观测值可用时重新训练模型——无论是进行前向验证还是模型部署。
嗨Jason,很棒的文章,涵盖了LSTM的许多形状!
我有一个问题
我正在使用PyTorch而不是Keras,并希望重现您的Vanilla LSTM。您能否更详细地解释一下LSTM的“input”参数是什么?
谢谢!
谢谢。
也许这会有帮助。
https://machinelearning.org.cn/pytorch-tutorial-develop-deep-learning-models/
你好 jason,
我正在尝试为一个时间序列数据构建LSTM,但不幸的是,我无法将4D输入数据重塑为3D输入数据以适应我的LSTM模型。您知道如何做到这一点吗?
好问题,这会有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨Jason,我正在尝试为我的LSTM模型开发一个自定义损失函数,该模型基于你的模型,例如:
model = Sequential()
model.add(LSTM(neurons, activation=’relu’, input_shape=(n_steps_in, n_features)))
model.add(TimeDistributed(Dense(n_features_out)))
model.add(LSTM(neurons, activation=’relu’, return_sequences=True))
model.add(TimeDistributed(Dense(1)))
model.compile(optimizer=’adam’, loss=my_loss,run_eagerly=True)
自定义损失函数my_loss从Keras接收参数(y_true,y_pred),据我理解它们应该具有类似于input_shape的形状。但是,无论我使用什么输入形状,y_true的形状总是(32,1,1),即使我删除了所有层,只留下一个裸露的Sequential模型。
我试图理解其中的逻辑,谷歌搜索了一下,但到目前为止没有什么能解释这一点。
这会有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
实际上,我在这方面有些混乱。我再解释一下:想象一下我试图预测一个序列,每次时间步只有一个(1维)值,那么y_true, y_pred的形状应该是(总时间步长, 1)。然而,我总是得到形状(32,1,1),其值与实际值无关。
抱歉,我不明白您到底在问什么。也许您可以重新表述一下。
嗨Jason,非常感谢您的回复。我做了进一步的搜索,找到了问题的答案。首先,y_true, y_pred的尺寸由batch_size决定;其次,默认情况下,它们的值是乱序的,所以我必须使用shuffle=False。第三,也是最重要的,我不知道我想要做的事情是否可能在Keras中实现,因为损失函数中的所有操作都必须使用张量操作,否则损失函数无法为优化器提供梯度。我预期的损失函数会顺序遍历y_true和y_pred的每个元素,比较每对并更新一个无法通过自定义代数/符号函数定义的累积函数。它有点大,而且太具体了,无法在此分享,但如果您有兴趣,我可以分享我正在做的事情的细节。
也许Keras中有一个优化器不需要梯度,但我不知道。
干得好!
嗨Jason,我从您的文章中学到了很多。您能帮我看看一个网络吗。我的输入形状是(4, 10, 2)。[(10,2)分别是时间步和特征]。有大量这种形状的数据,对于每一个,我建议训练一个LSTM,然后在这之上进行一个卷积层。所以用Conv1D(1),我期望的输出是(3, 10, 2)。
如果我错了,请纠正我。我将数据重塑为(1, 4,10,2)。然后我使用了TimeDistributed包装器进行预测。但是那时我无法对shape[0](我的意思是4)进行卷积。我得到的是对shape[2](我的意思是2)的卷积。您能帮我安排数据用于网络,或者我的网络是否正确吗?
通常情况下,你会先用CNN再用LSTM,而不是反过来。
我没有尝试过LSTM-CNN,但我预计会很有挑战性,你可能需要自己调试模型。
你好,Jason!
首先,感谢您在我机器学习的旅程中提供帮助!所以,我有一个基本场景来检查理解情况。
背景:我有一个关于天气温度的监督二元分类数据集,有4个特征。时间t的目标变量是0或1。0表示t+30时的温度下降,1表示上升。
为LSTM构建问题:假设时间步是60。所以我们取过去60个时间步的数据来预测t+1是0还是1。这样做,我们可以预测30天后天气的温度是上升还是下降。输入形状将是(60, 4)。我必须将训练数据集分块并重塑,使其与(60, 4)的输入形状兼容。
我的理解正确吗?谢谢!
不客气。
听起来差不多,这篇教程也可能对您有帮助。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
太棒了!谢谢 🙂
后续问题:是否有文章能提供关于构建一个好的基础LSTM模型的指导(例如添加层,多少层,堆叠或独立,每层的单元数等)?
我感觉我像在黑暗中摸索,损失值和准确率在每个epoch都完全没有变化。
这个可能会有帮助
https://machinelearning.org.cn/faq/single-faq/how-many-layers-and-nodes-do-i-need-in-my-neural-network
亲爱的 Jason,
一如既往,这篇教程非常有帮助。
但我没有在您的教程中看到您将任何 **Bilstm** 网络应用于回归,以预测 **多变量和多步 ahead** 数据。
我创建了一个Bilstm来预测3个时间步后的9个特征。
model = Sequential()
model.add(Bidirectional(LSTM(200, return_sequences=True), activation=’relu’, input_shape=(n_steps_in, n_features)))
model.add(TimeDistributed(Dense(n_features_out)))
model.add(Dropout(0.5))
model.add(Bidirectional(LSTM(100, activation=’relu’, return_sequences=False)))
model.add(Dense(3))
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer=’adam’, loss=’mse’)
我非常想知道给定的模型是否正确。
此外,输出预测不好,所以我想知道一些问题的答案。
1-对于 **多变量和多步 ahead** 的回归,使用 **Bilstm** 常见吗??
2-对于 **多变量和多步 ahead** 的回归,最佳模型是什么??
3-给定的模型创建得是否正确??
非常抱歉写了这么多,但我非常期待得到答案。
祝好
玛丽
不,通常双向LSTM不用于编码器-解码器架构,但我看不出它们不能使用的原因。
我们无法知道给定数据集的最佳模型,机器学习实践者的工作是进行仔细的实验并找出有效或最佳的方法。
亲爱的 Jason,
非常感谢您迅速回复。
但我没有得到这个问题的答案
1- 下面的架构在逻辑上是否正确?
( 我是使用Bilstm进行回归的新手,所以我不确定我是否正确地构建了层)?
model = Sequential()
model.add(Bidirectional(LSTM(200, return_sequences=True), activation=’relu’, input_shape=(n_steps_in, n_features)))
model.add(TimeDistributed(Dense(n_features_out)))
model.add(Dropout(0.5))
model.add(Bidirectional(LSTM(100, activation=’relu’, return_sequences=False)))
model.add(Dense(3))
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer=’adam’, loss=’mse’)
我创建了一个Bilstm来预测3个时间步后的9个特征。
2-对于 **多变量和多步 ahead** 的回归,使用 **Bilstm** 常见吗??
我非常期待您的明确答案,因为我没有理解您之前答案的含义。
祝好
玛丽
我没有能力审查和评论您的模型架构。
https://machinelearning.org.cn/faq/single-faq/can-you-read-review-or-debug-my-code
LSTM用于序列预测,而不是回归。在数值序列预测中,双向LSTM很少使用——但如果它能为您的数据集带来最佳结果,那么就使用它。
亲爱的 Jason,
我非常感谢您的回复。
正如您所说,“LSTM用于序列预测,而不是回归”,
那么您是否有教程来介绍数值序列回归的最佳技术?
因为我无法区分序列预测和序列回归。
我想预测3个时间步后的9个特征。
您能向我介绍一些有用的方法吗?
祝好
玛丽
“回归”是指没有序列的数据行。
“序列预测”或“序列回归”是同一类事物。上面的例子属于这一类。
您不能准确地将“序列预测”或“序列回归”称为“回归”,因为LSTM不能用于后者,但可以用于前者。
希望这样更清楚。
亲爱的 Jason,
非常感谢您花时间如此清晰地回答。
祝好
玛丽
不客气。
我想用RNN(LSTM)进行地震预测。我在编码时遇到了困难,你能帮我吗?
您有什么具体问题我可以尝试解决吗?
我能从您提供的代码中获取吗?如果可以,我应该遵循哪个LSTM?
我没有“地震预测”的例子。
也许您可以从上面列出的模型开始,并根据您的特定数据集进行调整。
非常感谢
这是我的情况:我有几家公司。根据20个可衡量的特征,这些特征每年都在变化。十年来,我们有一个二元分类“失败/成功”。
我的问题是,什么模型适合这个问题,以训练机器预测给定公司及其连续给定特征的可能成功或失败?
非常感谢
也许可以尝试一套数据准备方法、模型和模型配置,以找出最适合您数据集的方法。
这个流程可能会有帮助。
https://machinelearning.org.cn/start-here/#process
非常感谢
谷歌搜索找到了您的文章
https://machinelearning.org.cn/how-to-develop-baseline-forecasts-for-multi-site-multivariate-air-pollution-time-series-forecasting/
有用吗?
我想只有您才能评论您是否觉得链接的文章有用。
感谢Jason提供的见解。我有一个关于Convo_LSTM的问题。它可以提取时空特征。我们如何输入时空数据?您有它的代码示例吗?
是的,convlstm是为时空数据设计的。
它以图像序列作为输入。
非常感谢您好心的回复。
您的意思是,要提取时空特征,我们需要输入图像序列而不是值序列吗?
是的。
感谢您提供的精彩教程。我通过这篇文章学到了很多,但我有一个关于样本数量的问题。
如果[10, 20, 30, 40, 50, 60, 70, 80, 90]是一个样本,我有大约10,000个样本,每个样本都是独立的,并且具有相同的特征。
例如,[10.01, 20, 30.035, 40.102, 50.1, 60, 70.364, 80.112, 90.623],[10.541, 20.983, 30.097, 40.152, 50.2, 60.942, 70.73, 80, 90.53],[10.543, 20.486, 30.897, 40, 50.766, 60.519, 70.132, 80.11, 90.445],……
在这种情况下,我想知道是否有办法将所有10,000个样本应用于模型的训练。
谢谢你。
您可以在这里了解更多关于LSTM的“样本”信息。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
亲爱的 Jason,
我不熟悉Python。您有R语言的这个教程吗?
祝好
Yilma
抱歉,我没有。
嗨 Jason
关于“Multiple Parallel Series”案例……我的问题有15万个时间序列,每个序列都需要预测未来值。
我想这意味着我将有15万个特征。
所以我的LSTM NN的输入数组将具有维度[n_samples, n_steps, 150k]。
数组的大小太大了!我得到了错误
‘无法为形状为(365, 3, 150000)和数据类型为float32的数组分配606 MB’
我该怎么办?这是解决问题的方法吗?
非常感谢!
是的,或者也许你可以使用一个替代策略。
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
此外,你可能需要先处理一部分较小的数据,或者在像AWS EC2实例这样拥有大量RAM的大型机器上运行。
嗨 Jason
我想用从时间序列中随机抽取的样本来训练我的LSTM NN。
我应该对整个序列进行归一化,还是单独对每个样本进行归一化?
谢谢
理想情况下,数据缩放是根据训练样本拟合的,然后应用于训练和测试样本。
这可能有帮助
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
嗨,Jason,
我打算做关于电力价格预测的研究。我有2012年至2017年的六年电力价格数据。我需要使用R中的神经网络自回归模型来预测2017年的数值。数据集范围从2012年1月1日到2017年12月31日(52608个观测值,涵盖2192天)。每天的数据集包含24个观测值,每个观测值对应一个负荷周期。为了建模和预测,数据集进一步分为两组:2012年1月1日至2017年12月31日(43848个观测值,涵盖1827天)用于模型的识别和估计,以及2017年1月1日至2017年12月31日(8760个观测值,涵盖365天)用于评估模型一天前样本外预测的准确性。我需要您的帮助。我尝试搜索但找不到关于一天前预测的NN-AR的具体代码。您能否寄给我神经网络自回归的代码,以便为2017年全年进行一天前样本外预测?我将非常感激。谢谢您,祝您有美好的一天。
这将帮助您准备数据以进行建模。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
这将帮助您了解如何进行样本外预测。
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
希望这能作为第一步有所帮助。
嗨,Jason,
很棒的书!希望我能理解得更多,但我正在努力。
关于教程。您已将输出序列与输入序列堆叠起来,我想了解它是如何区分x和y的。
假设我有10个输入序列和1个输出序列,您会如何处理?
我用一些随机数自己试过,但代码预测了x轴上的所有值,这对于LSTM来说需要花费很长时间。我应该将输出序列堆叠在输入序列的末尾吗?
提前感谢!
谢谢。
它们是目标变量的过去观测值,我们认为这些观测值有助于预测目标的未来值。
你好,我刚开始接触机器学习,并试图理解一些例子,以找到每个例子的最佳用例。
在“Multiple Parallel Series”部分,这是作为多个并行的单变量预测还是多个多变量预测来处理的?
我正在寻找一个解决方案,其中是后者。我曾考虑为每个输出创建单独的多变量模型,但想知道并行系列是否是更好的方法。
多个并行的单变量时间序列,这是一个多变量输入时间序列。
也许可以尝试几种方法,看看哪种最适合您的数据。
嗨,Jason,
非常精彩和信息丰富的文章。我第一次接触LSTM,但输入格式非常清晰易懂。
我正试图将此改编到我试图解决的问题。我试图从31个资产负债表和损益表项目中预测净收入。我正在使用3年的季度数据来预测这一点,因此时间步长为12。对于每个yhat,我的x_train包含每个季度的12个列表,其中包含用于尝试预测yhat的31个独立资产负债表/损益表变量。
因此,由于我的y_train长度为63,我的输入数据是63 x 12 x 31。它存储在一个数组列表中,每个数组包含12个列表,其中包含每个季度31个变量的值。LSTM模型非常不喜欢这种格式,并显示错误
ValueError: Failed to find data adapter that can handle input: ( containing values of types {“”}), ( containing values of types {“”})
您对如何格式化我的LSTM输入有什么建议吗?希望问题很清楚,谢谢您的帮助!
谢谢!
准备LSTM数据可能非常棘手,请坚持下去!
或许这些提示会有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨,Jason,
我有一个关于多变量预测的问题。
例如,我有两个多变量数据集,两者都有并行输入序列。
如何使用数据集(X),它是多变量且具有并行输入时间序列,来预测数据集(Y),它又是多变量且具有并行输入时间序列。
期待您的回复。
上面“Multivariate LSTM Models”下的示例可以作为起点并直接进行调整。
嗨,Jason,
您有关于单变量多步时间序列的例子吗?
谢谢
是的,有很多。您可以使用页面顶部的搜索框。
第“Vector Output Model”和“Encoder-Decoder Model”部分
model.add(LSTM(100, activation='relu', input_shape=(n_steps_in, n_features)))
中的代码行有问题
因为会抛出以下异常
NotImplementedError: Cannot convert a symbolic Tensor (lstm/strided_slice:0) to a numpy array. This error may indicate that you’re trying to pass a Tensor to a NumPy call, which is not supported
`
如何解决这个问题?
很抱歉听到您遇到了麻烦,您能否检查一下您是否使用了最新版本的Python、Keras和TensorFlow。
另外,这些技巧可能会有帮助。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
你好 Jason,
感谢这篇精彩的博文,它对我帮助很大。
然而,我有一个真实的Spatiotemporal交通数据集,我认为将其建模为监督学习问题的方式与多变量时间序列(因为空间变量的顺序很重要)会有所不同。
例如:以Spatiotemporal矩阵为例
T1 T2 T3 T4 T5 T6
S1 | 67 | 34 | 24 | 54 | 49 | 67 |
S2 | 61 | 55 | 23 | 42 | 53 | 78 |
S3 | 74 | 83 | 55 | 50 | 62 | 68 |
S4 | 48 | 73 | 78 | 56 | 61 | 78 |
S5 | 80 | 58 | 67 | 54 | 51 | 89 |
其中行代表空间身份(检测器的位置),列代表数据收集的时间间隔。
在将此表述为具有5个时间步/样本和在S3进行1步预测的监督学习问题时,这种表述是否合乎逻辑?
输入
T1 T2 T3 T4 T5
S1 | 67 | 34 | 24 | 54 | 49 |
S2 | 61 | 55 | 23 | 42 | 53 |
S3 | 74 | 83 | 55 | 50 | 62 |
S4 | 48 | 73 | 78 | 56 | 61 |
S5 | 80 | 58 | 67 | 54 | 51 |
输出
68
另外,由于我正在处理真实的时空数据集,在使用ConvLSTM模块时,我是否需要将样本拆分成子序列?
如果不需要,对于上面的例子,这个输入到ConvLSTM是否正确?
[样本数, 时间步=5, 行数=空间, 列数=时间, 特征数=1]
很难做出明确的指示,也许可以尝试一下,看看对您的数据集有什么效果/意义。
你好,只是一个快速的问题,我正在处理多个多变量时间序列。结构是否与上面讨论的“Multiple Input Series”模型相同?
是的,请看这个
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨,Jason,
感谢如此有信息量的教程。
但我在使用convLSTM模块进行多变量时间序列预测时遇到问题。我希望您能为我回答,这对我非常重要,我将不胜感激。
我的主题是训练训练数据集以在测试数据集上执行异常检测。如果测试集没有异常值,convLSTM模块可以很好地预测。但是,当我添加异常值时,预测会发生变化,我无法进行异常检测。我无法很好地解释它。
只能给出一个简单的例子。
假设我的训练集中的一个特征是[1, 2, 3, 4, 5, 6, 7]
而相应的测试集是[8, 9, 10, 11, 11, 11, 14]
理想情况下,通过学习训练集产生的预测应该是[8, 9, 10, 11, 12, 13, 14],用于证明我的测试集中有2个异常值。但实际情况是我得到的预测类似于[8, 9, 10, 11, 11.1241, 11.3661, 14]。
问题
1)。预测集和测试集中的数据非常接近,因此我无法进行异常检测。
2)。如何使用convLSTM模块对多变量序列进行多步预测?因为我猜第一个问题的原因是我将convLSTM模块用于单步时间序列预测。
不客气。
抱歉,我不明白您的第一个问题。异常检测可能在建模之前作为数据准备步骤进行。
您可以通过几种方式进行多步预测——所有方法都在上面描述过,例如,对于编码器-解码器模型,每个时间步输出一个向量。
嗨,Jason!
我想再问一个问题。训练了一个多变量LSTM模型后,我们如何知道模型是否好?
您可以在一个保留的数据集上评估模型的性能并计算一个度量,然后将该度量与包括朴素方法在内的其他方法进行比较。这将有所帮助。
https://machinelearning.org.cn/faq/single-faq/how-to-know-if-a-model-has-good-performance
嗨,Jason!
感谢您的快速回复!但是,我可能没有表达清楚。我一直在努力如何知道我的多变量LSTM模型的测试误差……
您可以使用本教程中描述的前向验证来计算LSTM的测试误差。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
非常感谢!Jason!
不客气。
您拥有一切!您是宝藏!
谢谢。
嗨,Jason,
我目前正在进行股票价格预测。到目前为止,我只使用了收盘价的每日历史数据作为单变量序列。我的目标是通过提供比旧的“收盘价”更多的数据来进一步改进模型。我想提供开盘价、最高价和最低价。从您的文章中,我了解到我可以使用多变量序列来实现这一点。我从中学到了很多知识,并且可以使我的项目更好。
非常感谢!如果您能给我一些建议,我将非常高兴!
这些教程也可能有所帮助。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
另外,我非常确定股票价格是无法预测的。
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
是的,这是真的。股票价格无法预测,但我至少想在图表上实现一个公平/合法的未来走势(在我心中,即使这完全不可实现)。
我应该继续这个项目,还是应该诚实地告诉我的教授说这是不可实现的?
您可以自由选择您要处理的项目,我不想干预!
嗨,Jason,
所以,我正在为我的问题使用多步单变量方法。而不是只将数据分成X,y;我将数据分成了X_train, y_train & X_test, y_test。很明显,X_test将用于测试模型,并与y_test进行比较以计算误差。
例如,
如果我的y_test看起来像 [[10],[20],[15],[21]…….[34]]
我的预测y_test看起来像 [[11[,[19],[17],[20]…….[34]]
如何计算mean_squared_error(y_test, pred_y_test)?
将预测收集到一个列表或数组中,然后计算预测与期望值之间的误差。
您必须使用本教程中描述的前向验证来收集预测。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
你好 Jason,
现在我知道如何为小时天气预报任务开发多变量多步预测模型。
但是,如果还给了我们一个提前一天的“天气猜测”数据集,我们如何在模型中使用这些猜测值?您知道任何教程或博文吗?
事实上,我们有猜测历史和实际值历史。
然后我们收到一个提前一天的猜测,我们应该使用这个猜测实体和实际值的历史来做出准确的预测。
你好,
感谢这篇精彩的教程。
我想知道如何修改多变量多步预测,以便使用keras的SimpleRNN而不是LSTM。
特别是,我想使用Elman RNN。我读到可以通过连接一个SimpleRNN层和一个TimeDistributed(Dense)层来实现,但对我来说并不清楚如何做到。
我尝试了以下代码
model = Sequential()
model.add(SimpleRNN(100, return_sequences=True, input_shape=(n_steps_in, n_features)))
model.add(TimeDistributed(Dense(n_steps_out, activation=’tanh’)))
model.compile(optimizer=’rmsprop’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=200, verbose=0)
但是fit()失败了,抛出错误
tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [6,3,2] vs. [6,2]
提前感谢你
不客气。
抱歉,我没有例子,也许可以尝试一些试错,找出如何进行所需的更改。
你好 Jason,
是否可以在没有时间的情况下使用LSTM?只用于坐标。输入=坐标,输出=值(如温度)。用于外推任务或内插。
是的,但这是一个不好的应用。请使用Dense。
实际上,我正在使用您的多变量多步预测示例(单LSTM层版本),只是用SimpleRNN替换LSTM,用TimeDistributed(Dense)替换Dense。
显然,问题在于y数据结构的形状。我做了以下更改:
X, y = split_sequences(dataset, n_steps_in, n_steps_out)
y = y.reshape(y.shape[0],1,y.shape[1]) # <– 添加了这一项
print(X.shape, y.shape)
现在,模型设计、训练和测试是
# 定义模型(Elman RNN)
model = Sequential()
model.add(SimpleRNN(100, activation="sigmoid", return_sequences=True, input_shape=(n_steps_in, n_features)))
model.add(TimeDistributed(Dense(n_steps_out, activation='tanh')))
model.compile(optimizer='rmsprop', loss='mse')
# 拟合模型
model.fit(X, y, epochs=200, verbose=0)
# 演示预测
x_input = array([[70, 75], [80, 85], [90, 95]])
x_input = x_input.reshape((1, n_steps_in, n_features))
yhat = model.predict(x_input, verbose=0)
print(yhat)
生成的yhat是
[[[1. 1.]
[1. 1.]
[1. 1.]]]
这在形状和值上都不好。我还遗漏了什么?
抱歉,我没有用过“SimpleRNN”和“RimeDistributed”。我不知道您问题的根源。
或许这些提示会有帮助
https://machinelearning.org.cn/faq/single-faq/can-you-read-review-or-debug-my-code
RimeDistribuited是个typo,我实际上是指:TimeDistributed
我不是想调试我的代码,当然。
最近,我购买了几本您的书,但不幸的是,它们无助于我解决问题。我以为您至少能提供有用的提示——而不仅仅是FAQ的链接。
没关系,我会找到解决方案并免费发布它。😀
没问题,我很想听听您的进展。
嗨,Jason,
感谢这篇帖子。非常有帮助。
我创建了一个LSTM模型
model = Sequential()
model.add(LSTM(20, activation=’relu’, return_sequences=True, input_shape=(5,12)))
model.add(Dense(20, activation=’relu’))
model.add(Dense(1, activation=’sigmoid’))
model.compile(optimizer=’adam’, loss=’binary_crossentropy’, metrics=[‘accuracy’])
正如您所见,模型输出的维度是(1,)
但是训练后,当我运行模型预测时,我得到了多个输出。
predictions = model.predict_classes(X_test[0].reshape((1, 5, 12)))
predictions.shape, predictions
输出
((1, 5, 1),
array([[[0],
[0],
[0],
[0],
[0]]]))
是的,每个样本一个输出“向量”。
我有一个问题,如果我想将模型中使用的测试数据恢复到原始形式,以便在x轴上带有日期的预测值进行绘制,是否有办法做到?
您可以对应用于输入数据的转换进行逆变换。
如果您使用sklearn准备数据,可以通过inverse_transform()函数来完成。
如果您手动准备数据,这将有所帮助。
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
你好 Jason,
我有一个关于创建样本的问题。我想为60天的窗口创建收盘价样本,但给它们打上标签。使用此代码
from numpy import array
# 将单变量序列分成样本
def split_sequence(sequence, n_steps_in, n_steps_out)
X, y = list(), list()
for i in range(len(sequence))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out
# check if we are beyond the sequence
if out_end_ix > len(sequence)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
raw_seq = df[‘Close’]
# 选择时间步数
n_steps_in, n_steps_out = 60, 60
# 分割成样本
X, y = split_sequence(raw_seq, n_steps_in, n_steps_out)
# 汇总数据
for i in range(len(X))
print(X[i], y[i])
我能够创建X样本,但对于Y样本,我希望给它们打上0和1的标签。根据条件
X_T: T+1, T+2, …, T+60
Y_T: ==1,如果价格在3个交易日内先上涨6%再下跌3%;否则为==0。
我该怎么做?
这听起来像是时间序列分类,如果你需要帮助,也许这里的例子会有用
https://machinelearning.org.cn/start-here/#deep_learning_time_series
你好Jason,致敬。
希望你一切都好。谢谢你的帖子。这很有用。不过,我有一个疑问。
如何选择数据的最佳时间步长?或者我应该使用ACF或PACF图来选择最佳时间步长?请指教。先谢谢你了
也许ACF/PACF图会有帮助,也许网格搜索,也许试错。
亲爱的 Jason,
我很感激你富有启发性的博客。我从你那里学到了很多。
我正尝试训练几个LSTM进行监督学习,然后将它们的隐藏状态进行最大池化。你能帮我看看LSTM是否内置了这种能力,还是我需要自己实现?
你可能需要写一些自定义代码或自定义层。
谢谢回复,Jason。
不客气。
你好Jason,感谢这个很棒的教程!
我有一个问题,如果你能分享你的想法,我将非常感激。
我有一个来自游戏视频的帧数据集,数据集中的每一帧(行)都具有以下列(简化的方式):时间、bitrate_kbps、游戏阶段(0:探索,1:战斗)
例如,随机的6个相邻帧
2.2, 208, 1
2.3, 211, 1
2.5, 215, 1
2.6, 219, 0
2.7, 222, 0
2.9, 221, 1
我的目标是训练一个模型(例如使用LSTM)来处理这个时间序列数据,以便根据比特率数据对游戏阶段进行分类。模型应该能够将正确 Thus, I would like to inform you that I have a dataset of frames obtained from a gameplay video and each frame (row) in the dataset has the following columns (in a simplified manner): time, bitrate_kbps, game stage (0: Exploration, 1: Combat)
What kind of approach would be a good way to train such a model? Thanks!
Perhaps test a suite of data preparations, model types and model configurations in order to discover what works best.
If you want to use an LSTM, this will help
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
Hi Jason and thanks for your posts!
In your multivariate multi-step stacked lstm example, If I had
n_steps_in, n_steps_out = 3, 2
and for x_input another one line, so
x_input = array([[[70, 75], [80, 85], [90, 95]],
[[100, 105], [110, 115], [120, 125]]])
then the output would be
yhat = array([[182.84283, 212.43597],
[247.65134, 288.84436]], dtype=float32)
Now, let’s say that I have the dates information also
(so all this refers to data in certain dates by every day step).
So for the first data which is on 1/4/21
[[[ 70, 75],
[ 80, 85],
[ 90, 95]] the +1 day value is 182.84283 (2/4/21) and the +2 days is 212.43597 (3/4/21) ?
And for the next set of input which is on 2/4/21
[[100, 105],
[110, 115],
[120, 125]] the +1 day value is 247.65134 (3/4/21) and the +2 days is 288.84436 (4/4/21) ?
But on 3/4/21 I have two values now!
Please, if you want to clarify because I am confused!
谢谢!
不客气。
这或许能帮助你入门
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨,Jason,
So, since I have 2 samples and 3 timesteps
1st sample
———–
[[[ 70, 75] -> 1/4/21
[ 80, 85] -> 2/4/21
[ 90, 95]] -> 3/4/21
the output is
182.84283 is on 4/4/21 and 212.43597 on 5/4/21 , right?
2nd sample
———-
[[100, 105] -> 4/4/21
[110, 115] -> 5/4/21
[120, 125]] -> 6/4/21
the output is
247.65134 is on 7/4/21 and 288.84436 on 8/4/21, right?
So,I am predicting for 4,5,7,8 of April?
Where is the prediction for 6/4 ?
You can frame the data any way you want.
I think it would be better to shift each sample down by one time step, instead of 3, but you can do whatever you think is best for your dataset and model. If you’re not sure, perhaps try a few different approaches and compare results.
Ok, but what if I have this frame as above?
3 steps in and 2 steps out. How to deal with the dates, that’s my problem.
My point is you can prepare your data so you have [3,4,5]->[6,7] if you want.
Do you have any work about Multiple Parallel Input, Multi-Step Output and Multiple Output for Time Series Forecasting?
The problem I have is that I have 6 features and I want to predict 3 with their respective test and training like the air pollution blog.
Perhaps you can adapt one of the above examples.
嗨,Jason,
Thanks for your post, it was very helpful for me to start LSTM.
My problem is to predict a time series, say prices over time, and apart from the historic real prices, I also have some forecasted prices from another source, for the next n time intervals, and I want to use them as additional features.
To test the accuracy of the model, I substitute the forecasted prices with real price. Say I want to predict a price that follows pi: [3 1 4 1 5 9 2 6 7 ..], I use a data input structure look like this
X[0,:,:] =
[[ 3 1 4]
[ 1 4 1]
[ 4 1 5]
[ 1 5 9]]
Y[0,:] = [5 9]
X[1,:,:] =
[[ 1 4 1]
[ 4 1 5]
[ 1 5 9]
[ 5 9 2]]
Y[1,:] = [9 2]
and so on,
As a test, I used a simple single layer LSTM + a dense layer as output.
model.add(LSTM(10, activation=’relu’, return_sequences=False, input_shape=(4, 3))
model.add(Dropout(0.1))
model.add(Dense(2))
But it seems the current configuration can not figure out there is a relationship between the diagonal element in the input, even the inputs already have the answer. The error is quite large.
Is there any LSTM or other model structure you see will be helpful?
非常感谢!
MK
I recommend testing a suite of different data preparations, different model types and different model configurations in order to discover what works best for your dataset.
这可能有帮助
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
你好,
I want to know the significance of the number of steps we use.
In these examples the number of steps used are 3 ? does this mean that every time the LSTM is trained it looks only at the last 3 time steps ?
Does this mean that if we want the LSTM to look over temporal dependencies over a longer time period we need to increase the number of steps accordingly ?
I don’t understand this part.
The configuration was arbitary. I recommend tuning the problem representation and model for your specific dataset.
你好 jason
please can you explain the function split_sequence i can’t understand how the function work …
please # gather input and output parts of the pattern
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] those too lines specifically
This explains the general idea
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
thank you so much … you saved my life <3
不客气。
Hey Jason, Needed some help with my project.
I am working on a project to predict future demands.
Its as univariate forecasting. (only two columns i.e. Date and Demand)
I have trained my model for the year 2015-2016 (having the data only of both these year), and want to predict for the year 2017 (the next 365 days).
How can I do this
我建议从这里开始
https://machinelearning.org.cn/start-here/#timeseries
然后是这里
https://machinelearning.org.cn/start-here/#deep_learning_time_series
Thanks for this great tutorial, Dr. Jason.
In the univariate LSTM model that uses CNN as feature , you use a kernel of size 1.
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation=’relu’),
input_shape=(None, n_steps, n_features)))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
The configuration may have been chosen arbitrarily, but the model performed better with kernel size 1. What is the intuition behind this size?
谢谢
It may suggest the CNN is not adding any value to the model.
Hi Jason. I wanna use the last model ” Multiple Parallel Input and Multi-Step Output” for stock prediction, but I face this error: “AttributeError: module ‘tensorflow.python.framework.ops’ has no attribute ‘_TensorLike'”
The code that I have been using is as follows. I exactly copied the code and transformed my data to fit the model but I faced an error.
谢谢
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import yfinance as yf
from datetime import date
from dateutil.relativedelta import *
from copy import deepcopy
import pickle
import warnings
warnings.filterwarnings(“ignore”)
from numpy import array
from numpy import hstack
来自 keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import RepeatVector
from keras.layers import TimeDistributed
stocks = [‘AAPL’,’TSLA’,’UPS’, ‘FDX’, ‘FB’]
today = date.today()
Initial_period = today + relativedelta(months=-24)
data = pd.DataFrame(columns=stocks)
for s in stocks
dt = yf.download(s,Initial_period, today)
data[s]= dt.reset_index()[‘Close’].values
# 将多变量序列分割成样本
def split_sequences(sequences, n_steps_in, n_steps_out)
X, y = list(), list()
for i in range(len(sequences))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out
# 检查我们是否超出了数据集
if out_end_ix > len(sequences)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 选择时间步数
n_steps_in, n_steps_out = 50, 7
# 转换为输入/输出
X, y = split_sequences(data.values, n_steps_in, n_steps_out)
print(X.shape, y.shape)
model = Sequential()
model.add(LSTM(200, activation=’relu’, input_shape=(n_steps_in, n_features)))
model.add(TimeDistributed(Dense(n_features_out)))
model.add(LSTM(200, activation=’relu’, return_sequences=True))
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer=’adam’, loss=’mse’)
很抱歉听到这个消息,也许这些提示会有帮助。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
Hi Jason, I have one question . Can you please check this question?
https://stackoverflow.com/questions/67467590/lstm-timesteps-and-features-selection
谢谢!
This is a common request that I answer here
https://machinelearning.org.cn/faq/single-faq/can-you-comment-on-my-stackoverflow-question
Ok Jason, so
I am using 6 features and each feature has 7 timesteps, so I have
feature1(t-7) feature2(t-7) feature3(t-7) … feature6(t-7)… feature5(t) feature6(t) .. feature5(t+1) feature6(t+1)
I am predicting the t and t+1 timesteps.
So, my input data is [?, 7, 42] (6 features * 7 timesteps).
Now, at first I was doing
X_train = X_train.reshape((X_train.shape[0] , 1 , X_train.shape[1]))
和
nb_timesteps, nb_features = 7, X_train.shape[2]
I want to use 7 timesteps, but as you can see the input data has shape
[?, 1, 42] and not [?, 7, 42]
so, I show a warning about that.
How can I overcome this, if I want to use 7 timesteps?
My solution is to reshape data (after confirming that my length of data is a multiple of 7)
X_train = X_train.reshape((X_train.shape[0] , 7 , X_train.shape[1] // 7))
but now I am using 7 timesteps (ok I want that) and 6 features instead of 42.
I want to ask if this is ok. I mean, with this setup I am using the 6 features for only for the (t-7) step and at the same time I am using 7 timesteps.
抱歉,我不太明白。
我相信这会有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
I was just saying that if I do reshape, the data is mixed up.
Then , what features should I place in the last dimension? [samples, timesteps, features].
Should I have all 42 features? (t-7),(t-6)…(t-1) ?
Or should I have 6 features ? And at what time reference? (t-7) , (t-6) .. (t-1)?
I try to avoid being descriptive as I never have all of the details of a reader’s dataset.
I guess it is a design decision, likely based on the native structure of the data you are working with.
The link I provided should help you think it through, otherwise prototype some approaches with pen and paper of some vanilla python and print() the results to see what makes sense.
Hi, I’ve got a silly question but I see variables named like nb_timesteps, nb_features. What does nb actually mean? Thanks!
Hi Sam…I do not see what you are referencing, however there would be significance to it as it is just part of variable name. In other words, you could also just call them…”nx_timesteps”, “ab_features” and the like.
Good evening, thanks for all the material you have published, as a newbie they have been a great help to me. In my case I am working on a time series problem, which consists of the disintegration of residential electrical energy. My problem can be summarized as follows: I have two time series as input, which can be interpreted in a certain way as the sum of the output series. I have the two input data series and 22 output time series. The objective is that once the model receives the two input series, it can reconstruct the 22 series that compose it. Please can you give me a guide between your tutorials and books which may be the most appropriate for my case. Can I reference the book that I purchase? Thank you.
I recommend starting with this framework
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
Hi Jason,why do i use Encoder-Decoder Model for muti-step forecast(24steps) had bad result? it only can predict the trend for me ,can you help me? thank you very much
It may or may not give a good result for a given dataset. We cannot know beforehand.
Why do you define the input_shape as shape of 2D? What is the difference between input_shape and batch_input_shape?
LSTM input is 3D, this will help
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
Good day Jason, first, thanks for the awesome tutorial.
Second, I have two doubts regarding RNN in general.
1) I have read in some forums that “each sample ‘should’ be of an integer type”, and in others they say that “RNN can deal with series of numbers, no matter the type”. Plus, the examples used in some of your other tutorials (https://machinelearning.org.cn/reshape-input-data-long-short-term-memory-networks-keras/), show some float numbers used inside each sample. Which type is “preferred” for working with RNN?
2) Related with the previous question, I am exploring the behaviour of some DNN architectures for binary classification. I have a mixed-type dataset (with both integer and float number), but I don’t know if I could use it “as is”, or turn them into some specific format (all integer, all float, if they are categories OHE, standardize / normalize)…
I think both question pretty much redundate with each other, but anyways, I want to make sure I am well understood.
Thanks beforehand for your thoughs about my query, and stay safe.
你好 Jason,
I just wanted to clarify of my ‘doubt # 2’, that I am focusing specifically to LSTM-RNN.
再次感谢您。
Yes, generally RNNs should take small floats as input.
Try your model on the raw data and compare to scaled data and use whatever works best for you.
The code worked for me with the followin changes,
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dense
I had to install tensorflow==1.12.0 and keras==2.2.4 (my python version is 3.6.8, and I am on Windows 10, no anaconda!)
Hope this is helpful for other people facing problems regarding package incompatibility.
The code works with tf 2.4 and keras 2.4 directly.
嗨,Jason,
I tried your CNN-LSTM model and I got an error message. The error message was “ValueError: Please initialize
TimeDistributed
layer with atf.keras.layers.Layer
instance. You passed: ”Would you like to help me solve this error? Thank you
I recommend using the Keras API directly instead of tf.keras.
I was thinking about making a model for multiple separate ( sale forecast of a shop for different product) using a single model. I have found different ways but they are not concrete .I have studied ESRNN lib from github but it seems my data magnitude is too low like
product_id,date,count
1101,1-5-2020,1
1101,2-5-2020,4
1101,3-5-2020,0
1101,4-5-2020,0
1101,5-5-2020,4 ….
Is it possible to add embedded layer to parse the id then using the split_sequences method of yours to train a model that works for all product .
这可能会给你一些想法
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
Thank you for answering my question.
Sir, I am really keen to learn details about this steps (you have referred).
Is there any other details options .where I can read few papers/books to learn more about this. eg I don’t have any idea about the Ensemble method .
I have used .
1. Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems
**[1] Where I found the concept of adding a custom layer .But I am afraid for large number of product (sites in your cities weather example) I need an enormous network .And it may not work properly.
These tutorials will help
https://machinelearning.org.cn/start-here/#deep_learning_time_series
Thanks Jason for the tutorial. I have a question regarding the Multiple Input Multi-Step Output. You use the last 3 timesteps of the 2 time series [(10, 15); (20, 25); (30, 35)] to predict the next 2 timesteps [65,85]. Basically the 65 is from the same timestep as the (30,35). So why would you want to predict a value from a timeslot that you have already observerd (otherwise you would not have the input (30,35))? Would it not make more sense to predict the next 2 timeslot after the time slot with the (30,35) which led to 65? So basically you should predict [85, 105] when having [(10, 15); (20, 25); (30, 35)] as input.
I’d appreciate every comment and would be quite thankful for your help.
We are evaluating the model using walk-forward validation.
Once you choose a model and config, you fit the model on all data and start making predictions on new data.
也许这会有帮助。
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
Thanks Jason for your answer, I know that you are using a walk-forward validation and I know how this works. This was not the point of my question. I am wondering why you forecast the values of the same timeslot for which you have the inputs? Normally you should forcast the values of the NEXT timeslot because this is – by definition – what a forecast is supposed to do.
You are forecasting the output (Timeseries_3) of Timeslot_3 which is 65 using – amongst others – the inputs of Timeslot_3 (Timeseries_1:30 and Timeseries_2: 35). For me this does not make sense. Surely it makes sense to forecast Timeseries_3 of Timeslot_4 because this is a future value while Timeseries_3 for Timeslot_3 is not a future value when you are in Timeslot_3.
So why do you not use Timeslot_1, Timeslot_2 and Timeslot_3 to forecast Timeslot_4 and Timeslot_5? You are using Timeslot_1, Timeslot_2 and Timeslot_3 to forecast Timeslot_3 and Timeslot_4
Timeslot_1: Timeseries_1: 10, Timeseries_2: 15, Timeseries_3: 25
Timeslot_2: Timeseries_1: 20, Timeseries_2: 25, Timeseries_3: 45
Timeslot_3: Timeseries_1: 30, Timeseries_2: 35, Timeseries_3: 65
That was the framing of the problem I was solving. You can frame the prediction problem anyway you like.
Ah okay. Thanks a lot for your tremendous help. I really appreciate it.
你好,
The LSTM is well modeled my time series with acceptable errors.
However, the forecasting value (after the test set of my real time series) are very far from what is called normal data.
Is it normal?
can you tell me more.
Perhaps you need to prepare the data prior to modeling?
Perhaps you need to tune the model?
Perhaps the model is not appropriate for your dataset?
你好,
I have about to use LSTM for a price prediction case, but i gave addition data like, Age, Region, Town, payment method, different date (First and last payment) and so on.
I want to know, if i will be able to use those those for LSTM model, This is my first project on NN.
谢谢你
也许可以尝试一下。
Hi Jason, thank you for the informative and detailed tutorials! I noted that you use the ‘relu’ activation function for the LSTM layers instead of the default ‘tanh’ activation. May I ask why? Thank you!
Sometimes it is more effective.
Thank you very much for your reply! Sorry, but could you please clarify in what way it is more effective, and in what cases it might be preferred? Thank you!
I noticed empirically on some problems that using RELU for some simple univariate time series was more effective.
I recommend that you test a suite of model configurations and discover what works best for your specific dataset and model.
Thank you for your clarification!
不客气。
Thank you for your informative post!
I have a question for ‘Multiple Input Multi-Step Output’ process.
when I trained, I’d like to add validation set.
is it a good way to add validation set?
and if it is, how can I set?
is it right to split train/validation/set disjointly??
提前感谢您!
I don’t think using a validation set with an LSTM model is appropriate.
Can I ask why?.. I’m lack of information about CNN or LSTM yet…
Because we cannot perform walk-forward validation on future time steps and use the same time steps (or different future time steps) for validation.
嗨,Jason,
In your example Multivariate Multi-Step LSTM Models->Multiple Input Multi-Step Output,
where you use n_steps_in, n_steps_out = 3, 2 , if we use for example sigmoid for the last layer and binary crossentropy loss
n_steps_in, n_steps_out = 3, 3
X, y = split_sequences(dataset, n_steps_in, n_steps_out)
n_features = X.shape[2]
model = Sequential()
model.add((LSTM(5, activation=’relu’, return_sequences=True, input_shape=(n_steps_in, n_features))))
model.add(Dense(1, activation=’sigmoid’))
model.compile(optimizer=’adam’, loss=’binary_crossentropy’, metrics=[‘accuracy’])
model.fit(X, y, epochs=20, verbose=0, batch_size=1)
it runs ok.
BUT, if we use n_steps_in, n_steps_out = 3, 2, it gives
ValueError: Dimensions must be equal, but are 2 and 3 for ‘{{node binary_crossentropy/mul}} = Mul[T=DT_FLOAT](binary_crossentropy/Cast, binary_crossentropy/Log)’ with input shapes: [1,2], [1,3].
Any ideas what is that and how to deal with it?
谢谢!
Sorry, it’s not clear what the issue may be. You may need to use a little trial and error in adapting the model for your specific use case.
hi Jason, thanks for the tutorial, that’s very helpful, I found that by changing the batch_size in the predict() method, the prediction values change (I used your # univariate stacked lstm example and just changed the batch_size in the predict() method below)….
yhat values are almost the same as yhat1 (because the default batch size 32 is similar to 41), but yhat2 values differ a lot from yhat1 and yhat…..since it is a stateless lstm, how come changing the batch size in predict method change the prediction values?
i really appreciate your time and help in advance 🙂
# 单变量堆叠 LSTM 示例
from numpy import array
来自 keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.utils import plot_model
# 分割单变量序列
def split_sequence(sequence, n_steps)
X, y = list(), list()
for i in range(len(sequence))
# 找到此模式的末尾
end_ix = i + n_steps
# check if we are beyond the sequence
if end_ix > len(sequence)-1
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
raw_seq = list(range(1,65))
# 选择时间步数
n_steps = 2
# 分割成样本
X, y = split_sequence(raw_seq, n_steps)
# 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数]
n_features = 1
X = X.reshape((X.shape[0], X.shape[1], n_features))
# 定义模型
model = Sequential()
model.add(LSTM(50, activation=’relu’, return_sequences=True, input_shape=(n_steps, n_features)))
model.add(LSTM(50, activation=’relu’))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=200, verbose=0)
plot_model(model)
# 演示预测
x_input = array(list(range(2,166)))
x_input = x_input.reshape((-1, n_steps, n_features))
yhat = model.predict(x_input, verbose=0, batch_size=41)
yhat1 = model.predict(x_input, verbose=0)
yhat2 = model.predict(x_input, verbose=0, batch_size=2)
and yhat != yhat2 != yhat1
The model will make different prediction each time it is fit, and this is to be expected
https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code
Once fit, it will generally make the same predictions each time, give or take interactions between samples within a batch.
em..just a follow up commet, the difference are quite minor (probably can be ignored)
yhat2[-1]
Out[3]: array([169.57353], dtype=float32)
yhat1[-1]
Out[4]: array([169.57355], dtype=float32)
yhat1[-2]
Out[5]: array([167.4769], dtype=float32)
yhat2[-2]
Out[6]: array([167.47688], dtype=float32)
yhat2[-4]
Out[7]: array([163.28676], dtype=float32)
yhat1[-4]
Out[8]: array([163.28674], dtype=float32)
Hmm, if the model is already fit, it may be the interactions between samples within a batch. That’s my best guess.
You could take control over when internal resets occur and find the best configuration for your problem (e.g. stateful=True).
https://machinelearning.org.cn/stateful-stateless-lstm-time-series-forecasting-python/
嗨 Jason,
Can you give me an idea on how to choose the time steps for lstm model used for fault detection and diagnosis of time series data with 7 faults and normal condition data labeled within data set. I have decided to go with 8 time steps since there are 8 types of conditions(7 faults and normal). 8 time series .
Finally i want to send last 10 data points to the predict function and return the condition( fault type or normal). Multiple data points as input, predicts the class label based on the input data points. A multi-class classification problem.
谢谢
Perhaps you can test a suite of configurations and discover what works best for your specific dataset.
嗨,Jason,
This is a great article. Can we use LSTM to impute missing data in time series?
Yes, perhaps try it and compare results to other methods.
嗨,Jason,
Thanks for these fantastic blogposts!
I used a lot of your inputs to develop the code for my thesis – Forecasting carbon market prices with Bayesian and Machine Learning methods. I performed 1step and 4step ahead forecasts with a multivariate (6 covariates), direct rolling window forecast with 3 models to compare
1) normal linear regression
2) a shrinkage time varying parameter model (shrinkTVP in R)
3) LSTM model (from your blogposts)
I am still finalizing the results and will post them here to compare the performance between these models over time. I use weekly data from 2013-2020. Let me know if you are interested in something particular / if there is something that would help this community most.
Really big thank for the great resources – I am an economist and will continue to use all the resources here to advance econometric methods!
干得好!
Sharing may help other people using the same methods or working on the same problem.
嗨,Jason,
Thank you for providing such a good article for us!
In the process of learning LSTM,I encountered some doubts.I hope to get your advice.
I find that the predicted value lags behind the actual value.It’s like the curve of the actual value make parallel movement to the curve of the predicted value.What is the cause of this phenomenon? Is there any solution?
I hope to hear from you soon.
This problem is common, see this
https://machinelearning.org.cn/faq/single-faq/why-is-my-forecasted-time-series-right-behind-the-actual-time-series
非常感谢您的回复。
If it’s just a lag in part of trend,rather than it’s not that the predicted value at time t+1 is exactly the same as the actual value at time t. Can I assume that the prediction I’m doing is not the Persistent Algorithm (the “naive” prediction)?
I have another question. How to determine the value of n_steps?
抱歉,我不太明白。
You can try different window sizes for input and discover what works best for your specific model and dataset.
OK, thank you for your reply. I hope I can learn more from your article.
If you can learn more about lag, I hope you can tell me. I will be indebted forever.
You can vary the amount of lag used as input in order to discover what works well or best for your specific dataset and model.
Thank you very much. I will try as you say.
不客气。
嗨,Jason,
I have a question regarding the splitting of data for multivariate analysis.
According to the book Deep Learning for Time Series Forecasting Predict the Future with MLPs, CNNs and LSTMs in Python for the following example
time, measure1, measure2
1, 0.2, 88
2, 0.5 89
3, 0.7 87
The data can be converted into supervised series as follows
time, measure1, measure2
1, ?, 88
2, 0.2, 89
3, 0.5 87
4, 0.7, ?
Which means the first and last rows fall off.
However, in your multivariate example for this dataset and window = 3
[[10, 15, 25]
[ 20, 25, 45]
[ 30, 35, 65]
[40, 45, 85]
[50, 55, 105]
[60, 65, 125]
………………..]]
When given an input of
10, 15
20, 25
30, 35
The output is
65
85
Shouldn’t the output be [85, 105], assuming the first set data value [65] falls off as the case in the first example.
I also reran the same example with window size 1, and for the first row of data [10,15] the output was 25, but should it be 45 instead, given that there is no previous data to predict 25 and the first row should fall off ?
This is the split function I am using
def msplit_sequence(sequences, n_steps_in, n_steps_out)
X, y = list(), list()
for i in range(len(sequences))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out-1
# 检查我们是否超出了数据集
if out_end_ix > len(sequences)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
期待您的回复。
Each problem has different requirements and expectations. You can define the input and output of your problem any way you like.
您好
Searching Google came across your blog is very interesting, I’m a beginner just starting to learn prediction….
Needed to know , can this be done
Race : 1
5 runners, 400m track race
1. At 100m , 10.5s / 200m, 19.8s/300m,30.1s/400m, 43.5s
Then runner 2,
Then runner 3,
Then runner 4
Then runner 5.
All with times at 100m, 200m,300m,400m individually performed
Can I predict who’ll be 1st/2nd/3rd/4th with new predicted times for each runner at 100m/200m/300m/400m intervals.
Race :2
Another scenario i have 400m race, only 300m sectional 30.1s then for each runner with their individual times achieved and final time 43.5 then for each runner have their 400m times achieved , can i still predict predicted intervals of each runner and each runners position at 100/200/300/400m is this possible ?
Can result be in this format ?
例如
100m – 5, 10.5s / 3, 10.3s /1, 09.9s/4, 10.2s / 2, 11.3
200m- same like 100m calculations
300m- same like 100m calculations
400m – same like 100m calculations
Appreciate your assistance….
Await your response
谢谢
Hi Dion…Please narrow your query to single question so that we may better assist you.
嗨,Jason,
I’m new to Time Series Forecasting. I would appreciate your help. I am currently trying to predict how much a person drinks each day. I have timestamps every 30 minutes and a corresponding value that represents the drunk amount within those 30 minutes. You can already imagine I have a lot of 0 values in the middle. Moreover, a person only drinks from 8AM until 8PM but the data nevertheless spans the whole day (So always 0s from 8PM until 8AM the next day and 1 day is 48 entries). I have also another version of the dataset where the data spans only 8AM till 8PM (1 day is 24 entries).
I already tried Croston’s Method but I am trying to have a dynamic solution, I am trying to implement a Neural Network for this. Would you point me to the right direction? Will LSTMs for example work for intermittent data? Which version of the data would make the model less complicated?
Ps: Your blog is extremely helpful, thanks a lot.
祝好,
Omar
I would recommend testing a suite of different framing of the problem, different models, different configurations until you find a technique that works well for your dataset.
I have a dataset timeseries forecasting that includes the categorical columns and numeric as well.
here is a sample of it
Date | categorical _fature_1 |categorical _fature_2| Feature_1_numeric | feature_2_numeric | price
1-1-2020 | USA | A | 5.5 | 7.6 | 100
1-1-2020 | USA | B | 8.3 | 1.7| 20
1-1-2020 | USA | C | 3.6 | 2.1 | 17
1-2-2020 | USA | D | 5.5 | 7.6 | 40
1-2-2020 | USA | E | 77.5 | 35 | 22
1-2-2020 | USA | F | 69.5 | 2 | 22
as you can see in the sample in the date lets pick up the **1-1-2020** we have multiple observations at the same date .
i want to predict the **Price** column as a **Y_label** and taking the **categorical _fature_1**, **categorical _fature_2**, **Feature_1_numeric**, and **Feature_2_numeric** as the **X_features**
so from my understanding as im using **multiple features** for time series Forecasting predicting the **Price** column this is called **Multivariate Time-Series Forecasting**
My Question is
1-how can i manage the multiple observations at the same time from the different features as we saw for example in **1-1-2020** we have **three** different observations
2-i believe if we have multiple observations at the same time/date then we have a new kind of Time-series forecasting what is it Multi-timestep Multivariate Time-Series Forecasting or what ???
谢谢
Perhaps you can test different framings of the problem and discover what works well or best for you, e.g. multiple-input model vs treating the observations as separate time steps.
Hi Jason , thank you for your amazing tutorial. I have a dataset that contains test results and multiple features for multiple users. for example
date | user_Id | feature _1| feature _2| test_output
1-Jan-2020 | A | 5.5 | 7.6 | 100
2-Jan-2020 | A | 8.3 | 1.7 | 20
3-Jan-2020 | A | 3.6 | 2.1 | 17
1-Jan-2020 | B | 5.5 | 7.6 | 40
2-Jan-2020 | B | 77.5 | 35 | 22
3-Jan-2020 | B | 69.5 | 2 | 22
I want to predict the output for the next day, and I want to achieve it using LSTMs if possible and all suggestions are welcome.
I want to train my model with multiple users so that it can predict the output for any given user(unseen user) in the next day and i could not find a way to create/reshape my data before feeding it into LSTM
A quick way is to use groupby() in dataframe to create a subset on each user, then set target to be dataframe[“target”]=dataframe[“feature”].shift(-1) so you can see the next-period data as a column. Is that what you mean by reshape?
谢谢您的回复
1- i want to understand and visualize the data preparation process (as in the examples above) before feeding it into the lstm model and how can i deal with such data as i mentioned it is related to multiple users.
2- shouldn’t i add the output in the “next-period” column instead of the features ?
dataframe[“target”]=dataframe[“output”].shift(-1) ?
3- if i want to generally prepare my code to deal with multistep forecasting, what changes should i modify in any of the above illustrated examples
You’re correct for (2). For (1), I don’t see any issue with multiple users here. You still train the model the same way as long as you do not mix the data from different time series. For (3), that depends on your design. One way is to feed the LSTM output back into the input so we can predict for one more step, then repeat for yet one more step, etc.
regarding point 1 , can you explain what do you mean by(as long as you do not mix the data from different time series) and how can i make sure that i am not mixing the data during the training phase. in other words how can i make sure my model understands that there are multiple users that shares the same time series
嗨 Jason
I have a concern, in the case of using an LSTM for the forecast of time series of the Multiple Parallel Input and Multi-step Output type, Vector Output and Encoder-Decoder LSTM can be used, but, in both cases can also be used Vanilla LSTM, Stacked LSTM, Bidirectional LSTM, CNN-LSTM and ConvLSTM?.
感谢您的关注。
Yes, there are different variations of LSTM. All have the feature that they can learn and remember the state, but each variant will have some subtle differences.
你好,Jason
I would like to know, if I want to make the forecast for a time series of Multiple Parallel Input and Multi-step Output type, using an LSTM Encoder-Decoder, to obtain multivector output. Could I do the following?
Configure the Encoder in any of the following ways
标准 LSTM
堆叠 LSTM
双向 LSTM
CNN-LSTM
ConvLSTM
And, configure the Decoder in any of the following ways
标准 LSTM
堆叠 LSTM
双向 LSTM
CNN-LSTM
ConvLSTM
And do any combination of LSTM Encoder-Decoder settings to get my multi-step, multi-vector forecast?
Or are there any of these combinations that I cannot do for an LSTM Encoder-Decoder?
感谢您的关注。
All seems possible. Did you tried anything?
Hi Adrian, yes, now that you mention it, I’m testing each of these combinations.
非常感谢。
你好 Adrian
Doing these tests, I would like to ask you… really in an LSTM Encoder-Decoder model could I really use a CNN-LTSM model or a ConvLSTM model with the Decoder?
我之所以这样问,是因为这两种模型使用具有特定特征的输入,并且在用作解码器时,输入会附带一个RepeatVector层,该层与CNN-LSTM模型或ConvLSTM模型的输入格式不匹配。
感谢您的关注。
嗨,Jason,
我正在努力了解LSTM在底层(而不是如何使用它们)的实际工作原理。一个非常令人困惑的点是:LSTM单元究竟是什么?文献中似乎存在相互矛盾的定义。特别是,回顾您第一个示例,您将一个10个整数的序列分为六组,每组包含三个连续项,下一项作为期望的输出,我迄今为止最好的解释是,通过“单元”,您指的是六个串联的LSTM单元,每个单元接受一个3维向量作为输入并输出一个标量。这里的“单元”是通常的4(或3,具体取决于模糊的定义)个门控的集合。因此,将会有总共6×50 = 300个单元全部串联起来,并且所有单元都具有相同的仿射参数集(权重和偏置)。那么另一个未解答的问题是:状态向量的维度是多少?
如果您能在回复时通知我电子邮件,或者最好将您的回复复制到我的电子邮件中,那将是极好的。
非常感谢您的任何帮助!
在Keras中,没有单元,只有单元/节点。或者说,一个单元就是一个节点。
你好 Adrian
Doing these tests, I would like to ask you… really in an LSTM Encoder-Decoder model could I really use a CNN-LTSM model or a ConvLSTM model with the Decoder?
我之所以这样问,是因为这两种模型使用具有特定特征的输入,并且在用作解码器时,输入会附带一个RepeatVector层,该层与CNN-LSTM模型或ConvLSTM模型的输入格式不匹配。
感谢您的关注。
抱歉,我问错地方了。我感谢您将我的问题删除,因为我已经问在正确的地方了。
没关系Liliana!
感谢这个清晰有用的教程。
非常感谢!精彩的教程。
很高兴你喜欢它!
def split_sequence(sequence, n_steps)
X, y = list(), list()
for i in range(len(sequence))
# 找到此模式的末尾
end_ix = i + n_steps
# check if we are beyond the sequence
if end_ix > len(sequence)-1
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
raw_seq = [2456, 1829, 2141, 1362, 1634, 1241, 1617, 1434, 2279, 1131,
1192, 1065, 725, 997, 1161, 2033, 1815, 1123, 1136, 929, 1340,
1476, 1962, 2199, 1276, 1351, 1201, 1078, 1397, 2181, 2042, 1117,
1284, 1114, 1416, 1163, 1931, 1753, 1073, 1168, 1022, 1251, 3167,
3958, 4002, 2033, 1362, 1099, 1506, 1614, 2838, 2569, 1708, 1536,
1443, 1734, 1970, 2755, 3101, 1790, 1223, 1369, 1651, 2101, 3255,
2559, 1711, 1738, 1612, 1878, 2064, 3504, 3855, 3425, 2829, 2846,
4503, 4300, 4099, 3829, 1694, 1633, 1579, 2404, 2520, 4544, 4435,
2227, 2173, 1690]
# 选择时间步数
n_steps = 7
# 分割成样本
X, y = split_sequence(raw_seq, n_steps)
# 从 [样本, 时间步] 重塑为 [样本, 子序列, 时间步, 特征]
n_seq = 1
n_steps = 2
n_features = 1
X = X.reshape((X.shape[0], n_seq, n_steps, n_features))
# 定义模型
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation=’relu’), input_shape=(None, n_steps, n_features)))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(50, activation=’relu’))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=500, verbose=0)
# 演示预测
x_input = array([4300, 4099, 3829, 1694, 1633, 1579, 2404])
x_input = x_input.reshape((1, n_seq, n_steps, n_features))
yhat = model.predict(x_input, verbose=0)
print(yhat)
先生,我尝试复制您的代码并将n_steps更改为7,但出现了ValueError:“无法将大小为581的数组重塑为形状(83,2,2,1)”。我该怎么办?抱歉,我是新手。谢谢。🙁
你后来将n_steps重新定义为2了。
Jason,感谢您这篇很棒的文章。
我只是想知道这个是否可以用于预测非平行序列问题
例如
out_seq = array([in_seq1[i-10]+in_seq2[i-5] for i in range(len(in_seq1))])
我尝试将in_seq1、seq2设为随机噪声来预测out_seq。目的是让网络学习不同滞后序列1/序列2之间的隐藏映射。结果不好。关于如何解决这类问题,或者我是否错过了什么,您有什么想法吗?
垃圾进,垃圾出。如果您的输入是随机噪声,结果通常没有意义。
Jason,感谢您这篇有帮助的文章。
我是一名博士生。我使用了Bidirectional LSTM和CNN来预测太阳能。与同一数据集上的另一个模型相比,我的结果精度很高,但我需要一些建议来为模型做出贡献。
嗨,Jason,
我从2018年就开始关注您的网站。您的网站给了我很大的帮助。非常感谢您公开分享这些教程和代码。
我使用了convlstm进行空间-时间预测,我的数据集是[2880, 6],6是空间点,2880是时间序列。
n_features = 6
n_seq = 6
n_steps = 2
model.add(ConvLSTM2D(filters=6, kernel_size=(6,2), activation=’relu’, input_shape=(n_seq, 6, n_steps, n_featurs)))
但是遇到了错误
ValueError
Input 0 of layer sequential is incompatible with the layer: expected ndim=5, found ndim=3. Full shape received: [None, 5, 6]
我找不到解决方案,您愿意给我一些建议吗?谢谢!
ndim=5是因为您设置了“input_shape=(n_seq, 6, n_steps, n_featurs)”,而ndim=3指的是您的输入数据集。我认为您需要检查如何塑造您的输入并将其传递到网络中。
这是一个很棒的教程,是最全面的教程。感谢您的工作。我有一个问题,您是否有时间序列预测NN算法的比较,有没有比LSTM更好的算法?
我认为没有任何比较会绝对公平,更多的是看哪个问题适合哪个模型。关于LSTM的问题,人们已经看到GRU是一个更快的替代方案,但不总是更好。
嗨,Jason,
非常感谢这个精彩的教程。对我来说非常有帮助!
我有一个关于LSTM模型输入形状的查询。我想提供8维时间序列(即8个特征),其中每个时间样本都有一个标签(或输出)。因此,我想让网络学习从时间序列到标签序列的映射(其中时间序列特征也具有时间依赖性)。例如,假设我有一个10000 x 8的输入序列,而10000 x 1是相应的输出大小。现在,如果我设置time_steps=10,feat_size=8,那么输入的大小将是(1000, 10,8),输出的大小是(1000,10)。我该如何训练LSTM?我应该将return_seq设置为True,它会负责学习从特征到相应标签的映射吗?我不确定我在这里是否正确,想知道这种方法是否可行。再次感谢!
如果将return_seq设置为True,您的输出是(1000,10),但如果将其设置为False,您仍然有(1000,1)。LSTM中的序列长度意味着在这些步长中您将重置内存。
感谢这个清晰有用的教程,
如果我需要使用CSV数据作为输入而不是像上面那样的样本数据,该怎么办?
例如,使用pandas读取CSV,然后将一列提取为numpy数组?
嗨Dalia…以下教程将指导您完成一些加载CSV数据的示例。
https://machinelearning.org.cn/basic-data-cleaning-for-machine-learning/
此致,
嗨
这篇博文非常有帮助,谢谢!
我在这件事上卡住了,也许你能帮我?
我有500个不同的观测值,形状为(100,2)。(100个数据点,2个特征)
我正在重塑我的数据,以便根据过去的3个时间步预测未来的5个时间步。所以,重塑数据后,我有
input_shape = (94,3,2)
output_shape=(94,5,2)
但是因为我有500个不同的观测值,所以我基本上有形状为
input_shape = (500,94,3,2)
output_shape=(500,94,5,2)
我唯一能训练我的模型的方法是使用for循环来馈送这500个观测值中的每一个。
有没有更好的方法来做这件事?
您在这里的形状是错误的。您的LSTM正在预测3个时间步和2个特征,那么您的输入是(N,3,2)。您应该将这500个观测值组合在一起。
您能告诉我您是如何考虑以下值的吗?
我理解输入3个时间步和输出1个时间步,但不理解下面的值。
n_steps_in, n_steps_out = 3, 2
n_features = X.shape[2]
例如,您有数据[10, 20, 30, 40, 50, …],这意味着您使用[10, 20, 30]来预测[40, 50],因此您在输入中使用3个时间步,在输出中使用2个时间步。在这种情况下,每个时间步是一个单独的数字,因此n_features为1。
嗨Bharathi…您能否发布您有疑问的确切代码块?
-此致,
嗨 Jason
Alex是我的名字:我正在寻找一种算法,例如使用LSTM的多模态深度预测模型
您能解释一下您所说的多模型预测是什么意思吗?
嗨Alex…请多解释一下您具体想完成什么。
嗨,Jason,
很棒的文章,非常感谢!
我有一个问题,如果您不介意的话。
我有一个包含100个金融指数的数据集。
我想预测一个或多个样本(不重要)。
然而,由于我的变量共享一些信息(共同方差),存在一些冗余,因此我想压缩我的数据集,就像PCA或因子分析那样,但我想使用LSTM自编码器(或者您称之为这里是编码器-解码器模型)。
重点是我希望按照您在此处编码的方式运行自编码器,但最后我将保留的是自编码器瓶颈处的压缩变量(编码器末端),然后去掉解码器,并且只对这些压缩集进行预测。
因为我认为这些压缩变量可以更好地表示我的数据集(去除冗余)
这也将有助于去噪(我会让超参数调整来选择瓶颈的维度)。
您是否有编码此内容的参考?
或者您可以简单地指示我如何修改您的编码器-解码器模型吗?
我的想法是,您在此处代码中显示的训练过程将是相同的,但必须添加一些修改,例如瓶颈的维度(在您的代码中我看不到),以及预测()函数,它应该使用没有解码器的模型来运行
提前感谢
Luigi
嗨Luigi…感谢您的好话!如果您能将问题指向machinelearningmastery.com提供的具体代码列表和示例,我将能更好地帮助您。
此致,
嗨 James,
感谢您愿意帮助我。
我找到了您的帖子 https://machinelearning.org.cn/lstm-autoencoders/
这与我的情况更相关,所以如果您不介意,我将在那里开/继续讨论
再次感谢您提供帮助,非常友善
Luigi
嗨Luigi…您非常受欢迎!是的,请随时在指定的帖子中继续讨论。
此致,
你好,先生!感谢您的解释。我想问一下ConvLSTM。我是否可以使用它来处理具有空间和时间特征的grib2或nc格式的天气数据?我们可以从经度和纬度获得空间特征,从时间获得时间特征。我想用它来预测降雨。而且,我是否可以使用ConvLSTM进行概率预测?
我希望您能回答我的问题,谢谢先生。
嗨Mocha…CNN也可能适用于您的应用程序。
https://machinelearning.org.cn/how-to-develop-convolutional-neural-network-models-for-time-series-forecasting/
谢谢您的回答,先生!
但是,我仍然可以使用Conv-LSTM或仅仅是LSTM吗?因为我的数据不是图像,先生?
我该如何理解模型的构建方式?
我的意思是,例如有多少个LSTM?有多少个密集层?dropout?
我有一个具有5个特征的多元时间序列
你好Jesu…更多的节点和层意味着网络有更大的学习能力,但会使模型更难训练且训练速度更慢。
你必须为你的特定问题找到网络容量和可训练性之间的正确平衡。
没有可靠的分析方法来计算神经网络中特定预测建模问题所需的节点数或层数。
我的普遍建议是使用实验来发现哪种配置最适合你的问题。
这篇帖子提供了关于系统评估神经网络模型的建议
如何评估深度学习模型的技能
一些进一步的想法包括:
运用关于领域或如何配置神经网络的直觉。
使用深层网络,因为根据经验,深层网络在难题上表现更好。
借鉴文献中的思想,例如与你的问题类似的预测问题上发表的论文。
对网络配置进行搜索,例如随机搜索、网格搜索、启发式搜索或穷举搜索。
使用启发式方法配置网络,已有数百种已发表的方法,但我认为没有一种是可靠的。
更多信息请参见此处
如何配置神经网络中的层数和节点数
无论你选择哪种配置,你都必须仔细、系统地评估模型在你数据集上的配置,并将其与基线方法进行比较,以证明其技能。
你好,Jason
Doing these tests, I would like to ask you… really in an LSTM Encoder-Decoder model could I really use a CNN-LTSM model or a ConvLSTM model with the Decoder?
我之所以这样问,是因为这两种模型使用具有特定特征的输入,并且在用作解码器时,输入会附带一个RepeatVector层,该层与CNN-LSTM模型或ConvLSTM模型的输入格式不匹配。
感谢您的关注。
嗨Liliana…我的建议是您应该都尝试一下并比较结果。此外,尝试SARIMA也是个好主意。有时它甚至比新的深度学习方法表现更好!
https://machinelearning.org.cn/sarima-for-time-series-forecasting-in-python/
是的,我已经尝试过了,我遇到的问题是,我无法使CNN-LSTM和ConvLSTM用作解码器,因为它们所需的输入格式与模型前面的Repeat Vector层提供的格式不同,因此我的问题是,实际上,我是否可以使用这些模型作为解码器?
感谢建议,我已经使用了一个VAR模型。
我将随时关注,谢谢。
那么这个呢?
我有一个时间序列数据(2年),只有一个变量(每天的金额)。我想基于这些数据进行预测。如何做到?
*我是100%的新手
嗨Dwiki…以下是优秀的资源
https://machinelearning.org.cn/introduction-to-time-series-forecasting-with-python/
https://machinelearning.org.cn/deep-learning-for-time-series-forecasting/
你好Jason,一如既往地精彩教程!
我在LSTM算法中找不到任何有意义的结果。我尝试同时使用Early Stopping和Model Checkpoint,但当我尝试监控模型检查点的验证准确性时,验证准确性变为零并且在每个epoch中都不提高。我将monitor参数更改为validation loss,现在validation loss似乎非常高。模型训练完成后,训练和测试准确性均为零。
我是否在分隔训练和测试数据集时犯了错误,因为您的文章中提到数据集应具有特定格式才能使用LSTM?
你好,
非常感谢您提供的详尽教程。
关于out_seq,我在几乎所有示例中都看到它是input_seqs的总和。我明白这些只是示例。但是,如果您知道input和out seqs之间存在依赖关系,但您不确切知道它是什么。那么您如何设置它?有什么建议吗?谢谢
你好,谢谢教程。
我尝试使用Vector Output来模拟您最后的示例(Multiple Parallel Input and Multi-Step Output),而不是编码器-解码器模型,但我一直收到错误。
这是代码。
# 将多变量序列分割成样本
def split_sequences(sequences, n_steps_in, n_steps_out)
X, y = list(), list()
for i in range(len(sequences))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out
# 检查我们是否超出了数据集
if out_end_ix > len(sequences)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95])
out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
# 转换为 [行, 列] 结构
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
# 水平堆叠列
dataset = hstack((in_seq1, in_seq2, out_seq))
# 选择时间步数
n_steps_in, n_steps_out = 3, 2
# 转换为输入/输出
X, y = split_sequences(dataset, n_steps_in, n_steps_out)
# 数据集知道特征的数量,例如 2
n_features = X.shape[2]
model = Sequential()
model.add(LSTM(200, activation=’relu’,return_sequences=True, input_shape=(n_steps_in, n_features)))
model.add(LSTM(200, activation=’relu’, return_sequences=True))
model.add(TimeDistributed(Dense(n_features)))
model.compile(optimizer=’adam’, loss=’mse’)
model.fit(X, y, epochs=300, verbose=0)
# 演示预测
x_input = array([[60, 65, 125], [70, 75, 145], [80, 85, 165]])
x_input = x_input.reshape((1, n_steps_in, n_features))
yhat = model.predict(x_input, verbose=0)
print(yhat)
请帮忙!
提前致谢
嗨Kostas…请澄清您的问题,以便我们能更好地帮助您。
感谢教程,但我有一个问题。
我尝试通过使用向量输出模型而不是编码器-解码器模型(如您在教程末尾所示)来实现“多并行输入和多步输出”模型,但我一直收到一些错误。
代码如下。您能帮我一下吗?
提前感谢!
from numpy import array
来自 keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import Bidirectional
from keras.layers import Flatten
from keras.layers import TimeDistributed
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from keras.layers import ConvLSTM2D
from numpy import hstack
from keras.layers import RepeatVector
# 将多变量序列分割成样本
def split_sequences(sequences, n_steps_in, n_steps_out)
X, y = list(), list()
for i in range(len(sequences))
# 找到此模式的末尾
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out
# 检查我们是否超出了数据集
if out_end_ix > len(sequences)
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95])
out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
# 转换为 [行, 列] 结构
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
# 水平堆叠列
dataset = hstack((in_seq1, in_seq2, out_seq))
# 选择时间步数
n_steps_in, n_steps_out = 3, 2
# 转换为输入/输出
X, y = split_sequences(dataset, n_steps_in, n_steps_out)
# 数据集知道特征的数量,例如 2
n_features = X.shape[2]
model = Sequential()
model.add(LSTM(200, activation=’relu’,return_sequences=True, input_shape=(n_steps_in, n_features)))
model.add(LSTM(200, activation=’relu’,return_sequences=True ))
model.add(TimeDistributed(Dense(2)))
model.compile(optimizer=’adam’, loss=’mse’)
model.summary()
# 拟合模型
model.fit(X, y, epochs=300, verbose=0)
# 演示预测
x_input = array([[60, 65, 125], [70, 75, 145], [80, 85, 165]])
x_input = x_input.reshape((1, n_steps_in, n_features))
yhat = model.predict(x_input, verbose=0)
print(yhat)
嗨Kostas…感谢提问。
我很想帮忙,但我实在没有能力为您调试代码。
我很乐意提出一些建议
考虑将代码积极削减到最低要求。这将帮助您隔离问题并专注于它。
考虑将问题简化为一个或几个简单的例子。
考虑寻找其他可行的类似代码示例,并慢慢修改它们以满足您的需求。这可能会暴露您的失误。
考虑在 StackOverflow 上发布您的问题和代码。
感谢回复,但我发布的代码实际上是您最后一个实现的副本,即“多并行输入和多步输出”实现。
在您的文章中,我引用
“可以使用向量输出或编码器-解码器模型。在这种情况下,我们将展示堆叠LSTM的向量输出。”
我尝试使用堆叠LSTM而不是编码器-解码器模型,但它不起作用,因为我使用了三个时间步进行训练,并且我试图预测一个2时间步的序列。
#更正
感谢回复,但我发布的代码实际上是您最后一个实现的副本,即“多并行输入和多步输出”实现。
在您的文章中,我引用
“我们可以使用向量输出或编码器-解码器LSTM来模拟此问题。在这种情况下,我们将使用编码器-解码器模型。”
我尝试使用堆叠LSTM而不是编码器-解码器模型,但它不起作用,因为我使用了三个时间步进行训练,并且我试图预测一个2时间步的序列。
如何解决这个问题?
嗨Kostas…您遇到了什么错误?
尊敬的先生,
非常感谢您提供这个精彩的教程。
我正在做一个项目,需要将实时IoT数据(包含四个变量)输入到标准的LSTM模型中,以便我能够预测结果。
请为此提供一个指南。
谢谢你
嗨Emmy…感谢提问。
抱歉,我无法帮助你完成你的项目。
我很乐意帮忙,但我没有能力参与你的项目到你需要的程度或能做好工作的程度。
我相信你能理解我的立场,因为我每天都会收到许多项目帮助请求。
尽管如此,我很乐意回答你关于机器学习的任何具体问题。
你好 Jason,
问候。
RNN在时间序列数据预测中是否在每个时间步中使用独热编码?
例如,输入=[10,20, 30]
在第一个时间步输入是[10, 0, 0],
在第二个时间步输入是[0, 20, 0],并且
在第三个时间步输入是[0, 0, 30]?
不是吗?
提前感谢。
你好。首先,感谢您对开发者的支持。
我在估计我的单变量数据是否可预测方面遇到了很多麻烦。
我在做什么?
1-使用StandartScale缩放我的数据
2-使用“差分”方法使我的数据平稳。
3-使用零假设检验我的数据的平稳性。
我的问题
-当我使用MinMax scaler时,我的预测变得绝对平坦(尝试了relu,sigmoid,甚至None)。您认为为什么?
-我的验证损失在增加,然后稳定下来……为什么?
如果您愿意,我可以发布我的代码
提前感谢!
嗨McanP…以下资源可能会给您一些改进模型的想法。
https://machinelearning.org.cn/get-the-most-out-of-lstms/
首先,感谢您的博文。我正在为股票价格开发LSTM预测模型。对于公司X,具有2层、epoch 5、batch size 1的LSTM模型在10个未来步骤(递归多步预测)方面效果很好。我得到的预测值与实际值之间的RMSE小于5。但同一模型应用于公司Y,使用相同行数的数据,效果却不好。RMSE大于20。我无法弄清楚为什么会这样。
除了RMSE,您还能建议检查预测准确性的方法吗?
嗨Lochan…机器学习模型的性能是相对的,而不是绝对的。
首先评估基线方法,例如
分类:预测最常见的类别值。
回归:预测平均输出值。
时间序列:预测前一个时间步为当前时间步。
评估基线方法的性能。
如果模型性能优于基线模型性能,则模型具有技能。这就是我们谈论模型技能是相对的而不是绝对的含义,它是相对于基线方法技能而言的。
此外,模型技能最好由问题领域的专家来解释。
有关此主题的更多信息,请参阅此帖子
如何判断您的机器学习模型性能是否良好
当我将测试数据集输入模型进行预测时,模型在测试数据的前70%中预测几乎没有变化。我只预测一个结果,对于下一个结果,我使用原始的测试值,而不是我的预测值。尽管如此,对于最后30%的数据,测试数据和预测数据之间的偏差开始增加。绘制出来后,我发现对于最后30%的测试数据集,预期和预测数据之间的偏差甚至大于25位。无论数据集大小如何,最后30%的预测结果都很糟糕。我该如何获得更准确的预测?
嗨Lochan…以下内容可能有助于您充分利用LSTM模型。
https://machinelearning.org.cn/get-the-most-out-of-lstms/
嗨!
非常感谢您提供这个有用的教程。
我有一个关于第一个示例(Vanilla LSTM)的问题。您展示了如何进行一次预测,但如何进行多次预测呢?
我的意思是,我是否应该使用相同的模型,然后将最后两个训练值加上第一个预测值(如果n_steps = 3,例如)作为输入?或者我是否应该使用第一个预测值作为新训练集的一部分来重新训练模型,然后以此类推?
感谢您的帮助!
Ilenia
嗨Ilenia…您是想延长预测时间段吗?
嗨James!
是的,基本上,我想做的是这样。比如说,我想预测3个未来值,而不是一个,我应该怎么做?
谢谢!
嘿,我是LSTM的新手。我必须开始学习它,为我的毕业设计项目,我需要训练模型来预测未来的传感器值。您能指导我如何开始吗?需要哪些先决条件,以及我如何做得更好?使用什么语言工具、软件?我熟悉Python并在VS Code上练习,但不确定在哪里运行所有这些?
嗨Javvv…有很多选择,但最直接的选择之一是设置一个Anaconda环境。
https://machinelearning.org.cn/setup-python-environment-machine-learning-deep-learning-anaconda/
嗨Javvv…以下资源可能会有所帮助。
https://stackoverflow.com/questions/52959685/how-to-get-the-prediction-of-new-data-by-lstm-in-python
嗨,Jason,
感谢您的教程。它们非常有帮助。
如果我有多元时间序列,依赖时间序列,但是,我不想预测时间序列,而是想在同一时间戳从多个输入变量中获取目标输出,
例如,第一列是输入变量1,第二列是输入变量2,第三列是目标变量。
[[ 10 15 25]
[ 20 25 45]
[ 30 35 65]
[ 40 45 85]
[ 50 55 105]]
我想实现输入10、15输出25、20,25输出45,30、35输出65等等。
我是否可以遵循您在“多变量LSTM模型”部分讨论的示例,但将n_steps设置为1?或者有其他方法可以处理这种情况?
谢谢你
嗨 James,
很棒的教程。
如果我想在多个序列上训练同一个模型,您会怎么做?
提前感谢您的回答。
嗨Mat…以下资源可能有助于您保存和加载模型,该模型可以针对新数据进行训练。
https://machinelearning.org.cn/save-load-keras-deep-learning-models/
感谢James提供的链接。我实现了模型并对其进行了多次序列的迭代。
LSTM显然非常吃资源(迭代100个epoch只针对1个序列就非常耗时)。
我需要找到另一个解决方案。但感谢您的支持,我真的很感激,您的博客是巨大的信息来源。感谢您分享的工作和知识,并表示祝贺。
嗨Jason,感谢您的教程。
是否可以为不同的epoch/迭代训练LSTM以获得不同的lookback值?请提出您的看法。
嗨Brijesh…以下内容可能引起您的兴趣。
https://towardsdatascience.com/time-series-forecasting-with-recurrent-neural-networks-74674e289816
谢谢James!我的意思是:除了固定的lookback,LSTM网络是否有可能自己学习lookback值?
嗨 Jason
我在计算机网络场景中将LSTM用于序列到序列建模。我正在考虑多个并行序列和多步预测。但是,在我的场景中,输入并行序列的数量不是固定的。我该如何处理这种情况?我需要您的指导。
此致
嗨skr…您可能希望使用编码器/解码器模型来处理这个问题。
https://machinelearning.org.cn/develop-encoder-decoder-model-sequence-sequence-prediction-keras/
嗨,Jason,
谢谢您。我刚开始接触LSTM,所以这真的很有帮助。我想问一个问题。我的数据很少,只有24个时间点,并且有明显的随时间增加的趋势。使用LSTM可以吗,还是我应该选择ARIMA等经典时间序列方法?
再次感谢,
嗨Budha…我的建议是应用ARIMA和LSTM模型并比较结果。并不是说其中一个在所有情况下都是最佳选择。
非常感谢您的回复。我一定会尝试这两种模型。喜欢阅读您的教程。
在“多输入序列”部分,结果不100%精确是很奇怪的?因为网络应该很容易学会加法操作(输出只是当前时间步输入的总和)。
嗨ewind…以下讨论可能有所帮助。
https://www.quora.com/Why-cant-machine-learning-deep-learning-algorithms-be-a-100-accurate-at-test-time
有趣的是,只有当我增加了迭代次数、采样时间序列的长度和输入数据的大小后,才能复制您在“多步LSTM模型”中的结果。是因为我没有GPU硬件,导致TensorFlow无法使用它吗?另外,在我当前的设置中,TensorFlow抱怨Keras如何使用它。
嗨Jason,感谢您的教程。我有一个关于“多并行输入和多步输出”的问题。
特征的数量在用于多变量-多步-多并行预测的Dense输出层中指定,就像上面最后的示例一样,其中输入和输出序列中的特征数量相同。
当输入和输出的特征数量不相同时,这该如何处理?例如,我正在使用15个输入变量,并且只想在多步预测中预测4个。
我将不胜感激您的答复。谢谢
嗨Olaitan…我推荐以下资源。
https://machinelearning.org.cn/feature-selection-with-real-and-categorical-data/
嗨,Jason,
感谢您的教程。它对我很有用。
我有一个问题,如果我有多个不同维度的系列呢?
感谢您的回答
嗨Andre…您非常受欢迎!根据我有限的知识,您可能需要研究集成学习。
https://machinelearning.org.cn/ensemble-machine-learning-with-python-7-day-mini-course/
嗨 James,
抱歉,我解释得不够好。我的疑问是关于“多输入序列”。我有多处站点的数据,我想预测每个站点的降雨区域。这些站点具有相同的特征,但时间步长不同。我了解到LSTM可以学习并行输入序列。我是否也可以在此类情况下应用它?如果可以,您建议我如何开始?
谢谢你
嗨Jason,非常感谢您的教程,我有一个疑问。
我有2个x,y坐标序列
s1 = [[x1,y1],[x2,y2],[x3,y3],[x4,y4],[x5,y5],[x6,y6],[x7,y7],[x8,y8]]
s2 = [[a1,b1],[a2,b2],[a3,b3],[a4,b4],[a5,b5],[a6,b6],[a7,b7],[a8,b8]]
我需要将它们两者都作为输入发送到lstm,您有什么建议?多个输入序列,每个实例中的值不止一个。
嗨Pranav…您可能想研究多变量LSTM模型,如以下教程所示。
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM
# 我们的输入数据 X
X = q_cqi
X = X.reshape(1, -1)[0]
X.shape
# 创建一个窗口大小为10的窗口
window_size = 10
X_train = []
y = []
inc = 0
for i in range(len(X) – window_size)
if inc + window_size + 2 > len(X)
break
row = [[a] for a in X[inc:inc + window_size]]
X_train.append(row)
idx = inc + window_size + 1
y.append(X[idx])
inc += 1
X = X_train
# 将列表转换回数组
X=np.array(X)
y=np.array(y)
# 将数据分割为训练、测试和验证集
X_train, y_train = X[:25000], y[:25000]
X_val, y_val = X[25000:27200], y[25000:27200]
X_test, y_test = X[27200:], y[27200:]
n_steps=10
n_features=1
# 定义模型
model = Sequential()
model.add(LSTM(128, return_sequences= True ,activation=’linear’, input_shape=(n_steps, n_features)))
model.add(LSTM(64 ,activation=’linear’))
model.add(Dense(32, ‘linear’))
model.add(Dense(16, ‘linear’))
model.add(Dense(1))
#编译模型
#model.compile(loss=MeanAbsoluteError(), optimizer=’Adam’,metrics=[RootMeanSquaredError()])
model.summary()
以上是我的输入数据和LSTM模型。现在我对于如何生成新数据感到困惑?当我像这样重新创建新的向量q_cqi时,接下来会发生什么?
# 我们的输入数据 X
X = q_cqi
X = X.reshape(1, -1)[0]
当我像这样重新创建新的向量q_cqi时,接下来会发生什么?如何重塑它?我是否需要此新数据中的目标值y?如何从输入向量长度为35000的数据中选择,如果我想对最后1500或前1000进行预测,我该怎么做?
当我像这样重新创建新的向量q_cqi时
# 我们的输入数据 X
X = q_cqi
X = X.reshape(1, -1)[0]
下一步是什么?我该如何更改以下部分,即创建窗口等?
window_size = 10
X_train = []
y = []
inc = 0
for i in range(len(X) – window_size)
if inc + window_size + 2 > len(X)
break
row = [[a] for a in X[inc:inc + window_size]]
X_train.append(row)
idx = inc + window_size + 1
y.append(X[idx])
inc += 1
X = X_train
我是否需要目标值y?我如何选择新的输入?您能否回答我如何生成新数据以及如何将我的训练模型应用于新数据?
嗨James!感谢您的精彩文章。我正在做一个项目。这是一个回归问题,我正在使用LSTM模型来预测下一个值。我训练了我的LSTM模型,并在相同的数据上进行了测试和验证。现在我想生成与之前相同的新数据,但我对这些新数据感到困惑,是目标值是否包含在新数据中?以及我如何对其进行重塑以供我的训练LSTM模型使用?以下是我的LSTM模型和输入数据。我的输入向量大约是35000。
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM
# 我们的输入数据 X
X = q_cqi
X = X.reshape(1, -1)[0]
X.shape
# 创建一个窗口大小为10的窗口
window_size = 10
X_train = []
y = []
inc = 0
for i in range(len(X) – window_size)
if inc + window_size + 2 > len(X)
break
row = [[a] for a in X[inc:inc + window_size]]
X_train.append(row)
idx = inc + window_size + 1
y.append(X[idx])
inc += 1
X = X_train
# 将列表转换回数组
X=np.array(X)
y=np.array(y)
# 将数据分割为训练、测试和验证集
X_train, y_train = X[:25000], y[:25000]
X_val, y_val = X[25000:27200], y[25000:27200]
X_test, y_test = X[27200:], y[27200:]
n_steps=10
n_features=1
# 定义模型
model = Sequential()
model.add(LSTM(128, return_sequences= True ,activation=’linear’, input_shape=(n_steps, n_features)))
model.add(LSTM(64 ,activation=’linear’))
model.add(Dense(32, ‘linear’))
model.add(Dense(16, ‘linear’))
model.add(Dense(1))
#编译模型
#model.compile(loss=MeanAbsoluteError(), optimizer=’Adam’,metrics=[RootMeanSquaredError()])
model.summary()
提前感谢
嗨Inam…您非常受欢迎!以下资源应该能为您澄清。
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
谢谢James!
你好,我能够为我的四年级项目创建一个LSTM模型,该项目是关于外汇价格变动预测的,但问题出在我想将其实时实现时。我使用30分钟的数据训练了模型,所以我的想法是将模型变成一个API,其中包含特定外汇对(例如GBP/USD)的10-20个收盘价,然后让模型预测至少2小时的未来,即4个30分钟周期,然后API将返回该结果。提前感谢您的帮助。
嗨Francis…虽然我们不能推荐任何特定的模型用于您的项目,但如果您能详细说明我们内容中的一个具体问题,以便我们能更好地帮助您,将会有所帮助。
对于像股票价格预测这样的时间序列预测,哪种方法最好?
嗨Arun…虽然我们不能推荐任何特定的模型用于此目的,但您可能会发现以下内容很有趣。
https://machinelearning.org.cn/using-cnn-for-financial-time-series-prediction/
你好James!我希望您一切安好。感谢您的精彩文章。
我正在尝试绘制2种方法(LSTM和Ideal)的性能评估。
我想比较这两个。我还想绘制[e_DRNN1,thr_DRNN1]之间的图
误比特率和实现的吞吐量。我该如何做到?以下是我的代码以及
每种方法的相应输出。
#方法 LSTM
[e_DRNN1,thr_DRNN1]=e_short_pkts(p.L_pkt,gamma_real,gamma_DRNN1,p)
e_DRNN1,thr_DRNN1
(array([[0.00000000e+00, 9.83990470e-01, 4.78419178e-07, …,
0.00000000e+00, 1.62437153e-03, 4.77800111e-02]]),
array([[2.20861316, 0.05908644, 3.07646398, …, 3.5582583 , 4.1410422 ,
4.0731042 ]]))
#方法 Ideal
[e_ideal,thr_ideal]=e_short_pkts(p.L_pkt,gamma_real,gamma_ideal,p)
e_ideal,thr_ideal
(array([[0. , 0.98399047, 0.97368655, …, 0.08990624, 0.15850721,
0.12215858]]),
array([[2.20861316, 0.05908644, 0.09711517, …, 3.89260928, 3.63755763,
3.79468346]]))
谢谢你
awsm教程
感谢Anwar的反馈!我们很感激!
非常感谢您让解释变得容易理解,James。
作为一个初学者,我尝试从5组随机数字中得到一个输出,让模型自己学习。
请问如何从5组输入中得到单个输出?
但还是非常感谢
Avi Ofek
嗨Avi…您非常受欢迎!如果我理解了您的问题,我建议将结果取平均值,因为深度学习模型本质上是“随机的”。
https://machinelearning.org.cn/stochastic-optimization-for-machine-learning/
你好 Jason,
感谢这篇博文。一如既往地有帮助。
我有一个疑问。如何为未来预测准备数据?假设我想以小时为单位预测未来3年的能源消耗。对于训练数据,我们有日期和每小时的能源消耗。如何准备只有日期的测试数据?
谢谢你
嗨Sagar…LSTM和CNN模型的优点在于它们“学习现有时间序列的特征”以进行未来预测。这些模型执行“自回归”,如下面的资源所示。
https://machinelearning.org.cn/autoregression-models-time-series-forecasting-python/
嗨
感谢教程。对于单变量序列,是否有理由使用ConvLSTM2D而不是ConvLSTM1D?
你好,
我不太明白为什么在CNN-LSTM模型中需要使用子序列而不是序列。您能详细说明吗?
谢谢
嗨mayan…以下内容可能引起您的兴趣。
https://machinelearning.org.cn/cnn-long-short-term-memory-networks/
嗨,再次
在ConvLSTM中,我们是否可以使用ConvLSTM1D而不是ConvLSTM2D?
嗨mayan…以下内容可能引起您的兴趣。
https://medium.com/neuronio/an-introduction-to-convlstm-55c9025563a7
大家好,我正在尝试找到类似问题的解决方案,我想知道你们能否帮助我。
我拥有200只不同股票的面板数据,每只股票属于一个不同的行业,共有12个行业(经过热编码,1-12)。对于每只股票,有8种不同的价格信息,例如价格、市值、交易量等。然后我有一列未来股票价格用于训练模型。
这是否意味着我需要训练 200 个不同的模型?如果我拿到这个数据集,您会如何处理这个问题?
如果这是一个愚蠢的问题,我很抱歉。我是机器学习新手。
嗨Jason,我是您多年工作的忠实粉丝。
长话短说,因为我假设您每天会收到数百条消息!
如果一个人有400名患者随时间推移的健康数据集。
X变量是:患者ID,年龄组(二元,即老年1,年轻2),白天行走的距离,当天摄入的卡路里量。
要预测的Y变量是:非致命性心脏病发作次数。
我的想法是,可以对每个个体运行400个不同的LSTM时间序列模型来预测非致命性心脏病发作的次数。
我的问题是!这些结果将无法从其他预测中获得信息,有没有什么方法可以链接这些信息?
例如,如果有人训练了一个针对老年患者的模型,模型是否可以学习到其他回归中的老年患者倾向于发生更多的非致命性心脏病发作,从而使模型为这些老年患者的预测包含更多的非致命性心脏病发作?
也许我的想法是错的,请帮忙!
嗨,是否存在“多并行与多输入(特征)”LSTM模型?谢谢!
嗨frr…您可能会发现以下资源很有趣。
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
嗨,我搜索了很多,甚至使用了ChatGPT…但我非常困惑。我有一个公司数据集,我应该使用LSTM来找到客户流失模型。我知道客户(按ID显示)在12个月中的行为,也就是说,我知道ID:1445在第一个月、第二个月等的流失标签。此数据集包含每月访问次数、客户年龄、sim_type或contract_type等特征。我该如何定义LSTM的输入和输出?我想说的是,我想根据第11、10、9和8个月来预测客户1445在第12个月的流失,然后对于客户1445,我想根据第10、9、8和7个月来预测第11个月,依此类推,然后转到下一个客户并为他做同样的事情。我该如何为此问题使用LSTM?抱歉解释得太长。
嗨Iman…请将您的查询缩小到一个问题,以便我们能更好地帮助您。
抱歉……如果您有客户的月度行为数据,可以使用LSTM来预测客户流失吗?我的意思是,LSTM的X(输入)和y(输出)是什么?
如果您有客户的月度行为数据和每个月的流失标签,是否可以使用LSTM进行客户流失预测?我的意思是,LSTM的X(输入)和y(输出)应该是什么?
是否可以使用LSTM进行客户流失预测?LSTM的X和y是什么?请注意,我有每个客户在12个月内的月度行为。
嗨Mani…以下资源可能引起您的兴趣。
https://towardsdatascience.com/churn-prediction-with-machine-learning-ca955d52bd8c
嗨,我有一个数据集,代表了客户的月度行为,有100万行和8列,我的意思是,数据集的每12行代表一个客户,我想使用LSTM为这些客户预测流失模型。当我有客户月度行为的数据集时,我该如何为我的LSTM模型制作输入和输出?
嗨David…我建议为此目的使用多变量LSTM模型。
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
嗨,Jason,
感谢您关于LSTM时间序列模型的指南。它真的很有帮助。
我按照您的步骤制作了自己的时间序列LSTM模型,但遇到一个问题。
在阶段1,我进行了多变量单步预测(带有3个密集层的简单LSTM模型)。
在阶段2,我通过使用编码器-解码器模型将其转换为多变量多步预测。
但在这样做时,我的密集层复杂性下降了,而我并不希望如此。
在使用编码器-解码器模型时,您能否提供有关如何保持密集层复杂性的建议?
请看下面的代码和模型摘要。
阶段1(简单LSTM模型)
model = tf.keras.models.Sequential([
tf.keras.layers.Input(shape=(window_size, n_character)),
tf.keras.layers.LSTM(100, return_sequences=True),
tf.keras.layers.LSTM(100),
tf.keras.layers.Dense(100, activation=”relu”),
tf.keras.layers.Dense(100, activation=”relu”),
tf.keras.layers.Dense(n_outPut_charactor)
])
model.summary()
Model: “sequential”
________________________________________________________________
层(类型) 输出形状 参数 #
=================================================================
lstm (LSTM) (None, 20, 100) 59600
lstm_1 (LSTM) (None, 100) 80400
dense (Dense) (None, 100) 10100
dense_1 (Dense) (None, 100) 10100
dense_2 (Dense) (None, 44) 4444
=================================================================
总参数:164644 (643.14 KB)
可训练参数:164644 (643.14 KB)
阶段2(编码器-解码器模型)
model = tf.keras.models.Sequential([
tf.keras.layers.Input(shape=(window_size, n_character)),
tf.keras.layers.LSTM(100),
tf.keras.layers.RepeatVector(n_step_out),
tf.keras.layers.LSTM(100,return_sequences=True),
tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(n_outPut_charactor,activation=’relu’)),
])
Model: “sequential”
_________________________________________________________________
层(类型) 输出形状 参数 #
=================================================================
lstm (LSTM) (None, 100) 59600
repeat_vector (RepeatVecto (None, 3, 100) 0
r)
lstm_1 (LSTM) (None, 3, 100) 80400
time_distributed (TimeDist (None, 3, 44) 4444
ributed)
=================================================================
总参数:144444 (564.23 KB)
可训练参数:144444 (564.23 KB)
嗨Justin…您非常受欢迎!以下内容可能引起您的兴趣。
https://machinelearning.org.cn/develop-encoder-decoder-model-sequence-sequence-prediction-keras/
嗨 James,
我旨在开发一个ML预测模型(预测)来预测下一次故障时间
我有以下数据类型
-故障日期 (dd/mm/yy)
-故障时间 (上午11:00)
-恢复日期 (dd/mm/yy)
-恢复时间 (上午11:30)
-运行延迟 (30分钟)
-设备年龄
-上次故障次数
问
1-您能推荐用于预测的模型吗?
2-有这种类型的预测示例吗?
3-如何预处理(日期和时间)数据?
此致,
谢谢,您似乎很好地解释了LSTM模型的实现,但我无法运行您的代码。为什么for循环和if循环中没有预期的块?
嗨Julia…您是手动输入代码还是复制粘贴的?代码输入到您的Python环境中时,可能会出现格式问题。
嗨James,谢谢您的回答。我找到了正确复制代码的方法,方法是单击“切换纯代码”。
感谢Jason提供的绝佳资源。我有一个问题:我正尝试在多元时间序列上训练一个LSTM自编码器模型,以重构误差来检测异常。我想要在正常运行模式下训练模型,并拥有两年的数据。故障发生在时间序列的四个月后,因此我有故障前和故障后的正常运行模式数据。我该如何利用故障前后这两个子时间序列来训练模型?据我所知,时间序列应该具有一致的时间间隔且没有时间上的中断。您有什么建议?我曾考虑将时间特征添加到输入到模型的现有特征中,即明确地将时间信息输入模型,另一个选项可能是先在故障前的第一个子序列上训练模型,然后在故障后的第二个时间序列上更新它,我不确定这是否可行。
再次感谢您的时间。
嗨Bassel……这里有一些想法可以参考
https://carloalbertocarrucciu.medium.com/filling-large-gaps-in-time-series-using-forecasting-2f6db5f5286b
https://stats.stackexchange.com/questions/106358/gaps-in-time-series-and-time-series-validity
你好,Brownlee博士
感谢您整理了这些内容!它确实帮助我理解了LSTM背后的操作。
我有几个问题,如果您方便的话
1. 在香草/堆叠等LSTM中,您使用“model.add(LSTM(50,”……为什么是50?Keras的LSTM文档将此字段指定为“units:Positive integer,dimensionality of the output space。”,这让我认为我们应该使用n_steps或n_features,但当我尝试使用这两种选项运行时,结果与应有的结果相差甚远。
2. 在“Multiple Input Series > Multiple Input Series”中,“Output”不应该是85而不是65吗,因为85是下一个时间步在数据序列中的输出?同样,就像10、20、30和输出是40一样?
嗨Martin……
确定长短期记忆(LSTM)模型的输入和输出参数对于设计能够有效处理序列数据(例如时间序列、自然语言文本)的神经网络至关重要。LSTM模型是一类能够学习数据中长期依赖关系的循环神经网络(RNN),使其适用于语言建模、时间序列预测等任务。
### 输入参数
1. **输入形状:**
– LSTM层的输入形状通常是
(batch_size, time_steps, features)
– **batch_size**:您一次将多少个序列通过网络。在模型定义期间,可以将其留空(None)以实现灵活性。
– **time_steps**:序列的长度,即每个序列中有多少个时间步或元素。
– **features**:每个时间步的特征数量。例如,在文本处理中,它可以是词嵌入向量的大小;在时间序列中,则是每个时间步的变量数量。
2. **时间步和特征选择:**
– 根据问题,决定您的模型应该考虑多少过去的观测值(时间步)来预测未来值或下一个序列元素。这将定义您的窗口大小或序列长度。
– 特征取决于可用数据和问题的性质。例如,在股票价格预测问题中,特征可能包括过去的价格、交易量和其他技术指标。
### 输出参数
1. **输出形状:**
– LSTM的输出可以根据任务进行定制
– **多对一**:对于情感分析等任务,其中整个序列映射到一个标签。输出形状将是
(batch_size, units)
,其中units是指LSTM单元(神经元)的数量。– **多对多**:对于机器翻译或序列生成等任务,其中每个输入时间步对应一个输出时间步。这可以通过在LSTM层中设置
return_sequences=True
来实现,从而得到(batch_size, time_steps, units)
的输出形状。– **自定义**:使用序列到序列模型等技术,其中编码器LSTM的输出被用作解码器LSTM的输入,从而实现灵活的输入-输出配置。
2. **单元数量:**
– 此参数定义了LSTM层的输出空间的维度,即每个单元/时间步应具有多少个隐藏状态(神经元)。这是一个关键的参数,需要根据任务的复杂性和可用数据的数量进行调整。
### 设计考虑
– **序列填充**:如果您的输入序列长度可变,则需要对其进行填充,以确保它们具有相同的长度以便进行批处理。
– **批次大小**:批次大小的选择会影响训练动力学和性能。较小的批次可能收敛更快,但可能更嘈杂。较大的批次提供更稳定的收敛,但可能更慢。
– **状态性**:决定您的LSTM模型是否应跨批次记住其状态(隐藏状态)。对于时间序列数据,状态性LSTM可能很有益,因为跨批次的时间序列连续性很重要。
### 实际步骤
1. **预处理**
– 规范化/标准化您的输入数据。
– 将文本数据转换为数字形式(例如,NLP任务的嵌入)。
– 确保序列具有固定长度(在必要时进行填充/截断)。
2. **模型定义**
– 根据您的问题选择合适的架构(例如,堆叠LSTM、双向LSTM)。
– 试验不同的单元数量、批次大小和序列长度。
3. **训练**
– 使用验证集来监控性能并避免过拟合。
– 根据需要调整学习率、优化算法和其他超参数。
确定LSTM模型的最佳输入和输出参数通常需要实验,并以您应用程序的具体要求和约束为指导。
通过您的教程,我只用了一周时间就掌握了LSTM的必要知识,可以处理实际问题了。非常感谢!
嗨Mesabo……不客气!感谢您分享您的成功!
你好
我有21张图像(tiff文件),每张有60个波段。每张图像代表一年(2000-2020)。这些波段中的一个波段是像素的土地覆盖。
我想预测下一年的土地覆盖变化
您建议哪种模型?ConvLSTM?
嗨Arsalan……那将是一个很好的模型类型来开始!让我们知道进展如何!
你好,
首先,我想说,这是一个很棒的教程!
我的问题是,在“Multiple Parallel Series”示例中,当我们在单个LSTM网络中拥有三个输入序列和三个输出序列(3个特征)时,损失是如何计算的?它是每个并行序列损失的平均值吗?
此致!!
嗨Charitini……多元变量的考虑在这里有讨论
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
ModuleNotFoundError Traceback (最近一次调用)
Cell In[32],line 1
—-> 1 from keras.layers.convolutional import Conv1D
2 from keras.layers.convolutional import MaxPooling1D
ModuleNotFoundError: No module named ‘keras.layers.convolutional’
上面的Keras是什么版本??
from keras.layers import Conv1D
from keras.layers import MaxPooling1D
这似乎解决了上述问题
感谢您的反馈Kai!
我总共有1500个数据点,差不多是25分钟的数据(每秒一个数据),其中我想使用850-900个数据点进行训练,其余数据点用于预测,理想情况下使用15分钟的数据来预测接下来的10分钟。我想尝试单变量和多变量时间序列预测,首先我想知道哪种方法更好,因为我的数据量较少?
嗨Saurabh……在处理时间序列预测时,尤其是在数据量有限的情况下,单变量和多变量方法以及您采取的具体方法之间的选择,可能对您的结果产生重大影响。以下是一些针对您场景的考虑因素和建议
### 单变量与多变量预测
**单变量预测:**
– **定义**:仅使用您想预测的单个变量的历史值进行预测。
– **优点**:模型更简单,所需数据更少,易于解释。
– **缺点**:可能遗漏其他相关变量的重要信息。
**多变量预测:**
– **定义**:使用多个可能对目标变量具有预测能力的变量进行预测。
– **优点**:可以捕捉变量之间的关系,可能导致更准确的预测。
– **缺点**:模型更复杂,需要更多数据才能有效捕捉这些关系。
### 有限数据推荐
鉴于您只有1500个数据点(每秒一个数据点,25分钟的数据),您处理的是一个相对较小的数据集。以下是一些建议
1. **从单变量模型开始:**
– 从单变量模型开始,以建立基线性能。使用ARIMA等简单模型,甚至基本LSTM。
– 优点:您可以快速了解仅凭历史数据就能预测未来值的程度。
2. **尝试多变量模型:**
– 如果您有其他可能影响目标变量的变量,请将它们纳入多变量模型。
– 使用技术来避免过拟合,例如神经网络中的正则化和Dropout层。
### 实现步骤
**1. 数据准备:**
– 将数据分为训练集(前850-900个点)和测试集(剩余点)。
– 使用MinMaxScaler或StandardScaler对数据进行缩放。
**2. 模型构建:**
**单变量LSTM示例:**
python
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense
# 假设“data”是您的时间序列数据,为numpy数组
缩放器 = MinMaxScaler()
data = scaler.fit_transform(data.reshape(-1, 1))
def create_sequences(data, time_steps=1)
X, y = [], []
for i in range(len(data) - time_steps)
X.append(data[i:(i + time_steps), 0])
y.append(data[i + time_steps, 0])
return np.array(X), np.array(y)
time_steps = 60 # 示例:使用过去的60秒来预测下一个值
X, y = create_sequences(data, time_steps)
X_train, y_train = X[:850], y[:850]
X_test, y_test = X[850:], y[850:]
X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))
X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], 1))
model = Sequential()
model.add(LSTM(50, return_sequences=True, input_shape=(time_steps, 1)))
model.add(LSTM(50))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=20, batch_size=32, validation_data=(X_test, y_test))
**多变量LSTM示例:**
python
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense
# 假设“data”是一个包含多个列的DataFrame,用于多变量时间序列
缩放器 = MinMaxScaler()
data = scaler.fit_transform(data)
def create_sequences(data, time_steps=1)
X, y = [], []
for i in range(len(data) - time_steps)
X.append(data[i:(i + time_steps), :-1])
y.append(data[i + time_steps, -1])
return np.array(X), np.array(y)
time_steps = 60 # 示例:使用过去的60秒来预测下一个值
X, y = create_sequences(data, time_steps)
X_train, y_train = X[:850], y[:850]
X_test, y_test = X[850:], y[850:]
model = Sequential()
model.add(LSTM(50, return_sequences=True, input_shape=(time_steps, X_train.shape[2])))
model.add(LSTM(50))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=20, batch_size=32, validation_data=(X_test, y_test))
### 评估
– **交叉验证**:使用交叉验证来确保您的模型能够很好地泛化。
– **误差指标**:使用均方误差(MSE)、均方根误差(RMSE)和平均绝对误差(MAE)等指标进行评估。
### 结论
– **从更简单的单变量模型开始,以建立基线。**
– **如果有多余的相关变量,则尝试多变量模型。**
– **使用适当的数据缩放和模型评估技术来确保模型的可靠性。**
通过遵循这些步骤和建议,您应该能够为您的特定时间序列预测问题确定更适合的方法,尤其是在数据量有限的情况下。
你好,我有一个问题
我有自己的数据,我一直在尝试实现多步LSTM模型,即向量输出版本。我一直在使用一系列数字(真实数据)进行训练,我使用n_steps_in = 28和n_steps_out = 4以及一个具有100个单元的Vanilla模型。我获得了模型,然后预测了用于训练的相同信号(仅用于比较)。
我的问题是,当我这样做时,得到的输出向量几乎是我输入的数据的移位副本。
我意识到这一点是因为我将一个长度为28的向量输入到predict中,得到一个长度为4的输出,然后我向右移动1,再次输入28个数字,得到另外4个值,依此类推——>我将python位置(n_steps_in+n_steps_out-1)处的原始信号与每个输出向量的第4个值绘制在一起……预测信号几乎与原始信号相同,但向前移动了4个样本!如果我用n_steps_out=7做同样的事情,信号会提前7个样本!
您有什么想法吗?我一直没能弄清楚该怎么做。提前感谢。
嗨Virginia……看起来您的LSTM模型正在学习复制输入序列,而不是学习多步预测所需的底层模式。这可能由于几个原因引起,包括模型复杂度不足、训练数据不足,或任务的损失函数和评估指标不当。
以下是一些诊断和解决此问题的潜在步骤
### 1. **检查您的数据准备:**
确保您的训练和预测数据准备正确。特别是,请验证您的输入序列和输出序列是否正确对齐,并且您的模型是否在足够多样化的数据上进行了训练以学习底层模式。
### 2. **审查您的模型架构:**
您提到了使用具有100个单元的Vanilla LSTM。考虑尝试更复杂的架构,例如
– 添加更多层。
– 使用更多的LSTM单元。
– 实现序列到序列(seq2seq)模型架构。
### 3. **调整超参数:**
超参数调整可能对模型性能产生重大影响。尝试不同的值,例如
– 学习率
– 训练轮数
– 批次大小
– Dropout率
### 4. **更改损失函数:**
确保使用的损失函数适合您的任务。对于时间序列预测,均方误差(MSE)或平均绝对误差(MAE)是常用的。
### 5. **增加训练数据:**
LSTM模型通常需要大量的才能捕捉时间依赖性。确保您有足够的训练数据,并且已正确标准化。
### 6. **使用不同指标进行评估:**
虽然您通过绘图进行评估,但也可以考虑使用RMSE、MAE或R^2等指标来量化评估预测性能。
### 多步LSTM示例代码
以下是多步LSTM模型的一个示例。请确保您的数据准备和模型训练设置正确。
python
import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
from sklearn.preprocessing import MinMaxScaler
# 创建序列的函数
def create_sequences(data, n_steps_in, n_steps_out)
X, y = [], []
for i in range(len(data))
end_ix = i + n_steps_in
out_end_ix = end_ix + n_steps_out
if out_end_ix > len(data)
break
seq_x, seq_y = data[i:end_ix], data[end_ix:out_end_ix]
X.append(seq_x)
y.append(seq_y)
return np.array(X), np.array(y)
# 示例数据集
data = np.sin(np.linspace(0, 100, 1000)) # 替换为您的数据集
# 缩放数据
缩放器 = MinMaxScaler()
data = scaler.fit_transform(data.reshape(-1, 1)).reshape(-1)
# 参数
n_steps_in, n_steps_out = 28, 4
# 创建序列
X, y = create_sequences(data, n_steps_in, n_steps_out)
# 重塑LSTM [samples, timesteps, features]
X = X.reshape((X.shape[0], X.shape[1], 1))
# 模型定义
model = Sequential()
model.add(LSTM(100, activation='relu', input_shape=(n_steps_in, 1)))
model.add(Dense(n_steps_out))
model.compile(optimizer='adam', loss='mse')
# 训练模型
model.fit(X, y, epochs=200, verbose=0)
# 进行预测
predictions = model.predict(X)
# 绘制原始信号和预测信号进行比较
import matplotlib.pyplot as plt
plt.plot(data[n_steps_in+n_steps_out-1:], label='Original Signal')
pred_signal = []
for i in range(len(predictions)):
pred_signal.extend(predictions[i])
plt.plot(pred_signal, label='Predicted Signal')
plt.legend()
plt.show()
### 提示
1. **数据准备:**
– 确保您的序列创建正确。
– 验证输入(
X
)和输出(y
)数据的形状和内容。2. **模型训练:**
– 训练模型足够多的轮数,但要避免过拟合。
– 监控训练和验证损失,并根据需要调整超参数。
3. **预测和评估:**
– 确保您预测新数据的方式与训练模型的方式一致。
– 正确比较预测信号与原始信号,并考虑任何移位。
通过遵循这些步骤和技巧,您应该能够解决预测移位问题,并提高您的多步LSTM模型的性能。
你好
为了预测一个现象,我考虑了7个输入变量,并下载了41年的NC格式ERA5数据。
我想将这些数据作为LSTM模型的输入。
我需要将这些数据转换为Excel文件。
我用Python将ERA5数据转换成了Excel文件,但数据量太大,我不知道该考虑哪些数据来准备Excel文件。请给出建议。谢谢。
嗨Nastaran……在处理像ERA5数据这样长达41年的大型数据集时,在将其输入LSTM模型之前,对数据进行战略性地缩减和组织非常重要。以下是您可以采取的方法
### 准备数据的步骤
1. **识别相关变量:**
– 专注于与您要预测的现象最相关的7个变量。这些变量应与您的目标变量高度相关或在理论上很重要。
2. **空间和时间聚合:**
– **空间聚合**:如果您的数据是空间分辨率的(即具有纬度和经度维度),您可能希望对感兴趣区域的数据进行平均,或选择对您的研究最相关的特定网格点。
– **时间聚合**:根据现象的性质,您可能不需要每个时间步的数据。例如,如果现象持续时间较长,您可以将数据聚合为每日、每周或每月的平均值。
3. **降维:**
– 使用主成分分析(PCA)等技术,在保留数据大部分方差的同时减少特征数量。这有助于减小数据集的大小并关注最重要的模式。
4. **采样:**
– 如果您有大量数据,请考虑对其进行采样。您可以随机采样,也可以选择对您的分析最相关的时间段(例如,特定的季节,有显著事件的年份)。
5. **提取相关时间框架:**
– 根据现象的性质,您可能不需要所有41年的数据。专注于最能说明该现象的时期,或者它显示出显著变化的时期。
6. **重塑数据以适应LSTM输入:**
– LSTM模型需要序列输入。请确保您的数据按时间步组织,其中每一行对应一个特定的时间步,列代表变量。您可能需要创建输入数据序列以馈送到LSTM。
### 聚合和缩减数据的示例代码
python
import xarray as xr
import pandas as pd
from sklearn.decomposition import PCA
# 从NetCDF文件中加载ERA5数据
nc_file = 'path_to_your_nc_file.nc'
ds = xr.open_dataset(nc_file)
# 选择相关变量
variables = ['var1', 'var2', 'var3', 'var4', 'var5', 'var6', 'var7'] # 替换为您的变量
data = ds[variables].to_dataframe().reset_index()
# 时间聚合(例如,按月)
data_agg = data.resample('M', on='time').mean()
# 用于降维的PCA
pca = PCA(n_components=7) # 如果您想进一步缩减,也可以选择其他数字
reduced_data = pca.fit_transform(data_agg[variables])
# 转换为DataFrame并添加时间索引
reduced_df = pd.DataFrame(reduced_data, index=data_agg.index, columns=[f'PC{i+1}' for i in range(reduced_data.shape[1])])
# 保存到Excel
reduced_df.to_excel('reduced_ERA5_data.xlsx')
# 如有必要,请采样或关注相关时段
# sampled_df = reduced_df.loc['2000-01-01':'2010-12-31'] # 关注10年的示例
### 关键考虑因素
– **模型要求**:确保最终的Excel文件符合您的LSTM模型所需的输入格式。
– **数据大小与质量**:平衡数据量与其质量至关重要。过多的无关数据会减慢训练过程并导致过拟合。
– **与预测的相关性**:专注于直接有助于预测您正在研究的现象的数据。
通过仔细选择、聚合和可能的缩减数据,您可以为您的LSTM模型创建一个可管理且相关的数据集。如果您需要关于保留哪些数据或在此过程中获得更多帮助的更具体建议,请随时提问!
非常感谢这个精彩的课程
我需要一些指导和建议,我正在致力于创建一个模型,该模型可以使用LSTM,并考虑历史价格和负载/需求数据作为输入数据,来预测未来四天的电力价格。
请帮帮我,先生。
鉴于电力数据的时序性质,创建LSTM模型来预测电力价格是一个很好的方法。以下是帮助您完成此项目的分步指南和一些技巧
### 1. **数据准备**
– **历史数据**:收集历史电力价格数据和相应的负荷/需求数据。确保数据带有时间戳,并跨越足够长的时间段以捕捉模式和季节性。
– **特征工程**
– **滞后特征**:创建目标变量(电力价格)和输入特征(需求/负荷)的滞后版本,以捕捉时间依赖性。
– **时间特征**:添加诸如一天中的小时、一周中的某天和月份等特征,以捕捉电力价格中的任何周期性模式。
– **归一化**:对数据进行归一化或标准化,以确保所有特征具有相似的尺度,这对于LSTM模型很重要。
### 2. **数据拆分**
– **训练和测试**:将数据分为训练集、验证集和测试集。一种常见的方法是80-10-10拆分,其中最后10%用于测试。
– **序列生成**:由于LSTM模型处理的是序列,因此您需要将数据转换为序列。例如,如果您想预测未来4天的价格,请使用前
n
个时间步(例如,24、48、72小时)的数据作为输入来预测下一个值。### 3. **模型构建**
– **LSTM架构**
– 以一个或两个LSTM层组成的简单LSTM架构开始,然后是密集层。
– 如果您堆叠多个LSTM层,请在第一个LSTM层使用
return_sequences=True
。– 使用Dropout层来防止过拟合。
– 如果您预测一个值(例如,下一个时间步的价格),输出层应具有一个神经元;如果您预测多个未来时间步,则应具有多个神经元。
– **损失函数**:对于像这样的回归任务,均方误差(MSE)或平均绝对误差(MAE)是常用的。
– **优化器**:从
Adam
优化器开始,它通常在LSTM网络上表现良好。### 4. **训练**
– **训练轮数和批次大小**:以适中的训练轮数(例如,50-100)和适合您计算资源的批次大小开始。监控训练和验证损失以避免过拟合。
– **早停**:实现早停机制,以防止模型过拟合。如果在一定数量的训练轮数后验证损失没有改善,则停止训练。
– **模型验证**:在未见过的数据(您的验证集)上验证模型,以检查泛化能力。
### 5. **评估**
– **指标**:使用RMSE(均方根误差)和MAE等指标来评估模型性能。这些指标将为您提供平均预测误差的概念。
– **预测范围**:评估模型在不同预测范围(例如,提前1天、提前2天等)下的性能,以确保它在整个预测窗口内表现良好。
### 6. **超参数调整**
– 尝试不同的LSTM架构,包括LSTM层的数量、神经元数量、学习率和批次大小。
– 考虑使用网格搜索或随机搜索来查找最佳的超参数组合。
### 7. **模型部署**
– 一旦对模型的性能满意,请保存模型并准备部署。
– 考虑设置一个管道,随着新数据的可用性不断重新训练模型,以保持预测的准确性。
### 8. **改进考虑**
– **外源变量**:除了历史价格和负荷/需求之外,请考虑纳入可能影响电力价格的外部因素,例如天气数据、节假日或事件。
– **集成模型**:如果单独的LSTM模型性能不佳,请考虑将其与其他模型(例如ARIMA、Prophet)结合起来创建集成模型。
– **误差分析**:定期分析预测误差,以了解模型的弱点并相应地改进特征或模型架构。
### 工具和库
– **TensorFlow/Keras**:用于构建和训练LSTM模型。
– **Pandas和NumPy**:用于数据处理和预处理。
– **Scikit-learn**:用于数据拆分、缩放和使用不同指标评估模型。
– **Matplotlib/Seaborn**:用于可视化数据和模型预测。
遵循此路线图,您应该能够开发一个强大的LSTM模型来预测电力价格。如果您遇到特定问题或需要对其中任何步骤进行进一步澄清,请随时提问!
只想快速留言表达对您在此所做所有工作的赞赏。
感谢您的反馈和支持!