多变量LSTM模型

多变量时间序列数据是指每个时间步长有多个观察值的数据。

对于多变量时间序列数据,我们可能需要两种主要模型; 他们是:

  1. 多输入系列。
  2. 多个并联系列。

1、多输入系列

问题可能有两个或更多并行输入时间序列和输出时间序列,这取决于输入时间序列。

输入时间序列是平行的,因为每个系列在同一时间步骤具有观察。

我们可以通过两个并行输入时间序列的简单示例来演示这一点,其中输出序列是输入序列的简单添加。

# define input sequence
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))])

打印出来的输出如下:

[10, 20, 30, 40, 50, 60, 70, 80, 90]
[15, 25, 35, 45, 55, 65, 75, 85, 95]
[25, 45, 65, 85, 105, 125, 145, 165, 185]

我们可以将这三个数据数组重新整形为单个数据集,其中每一行都是一个时间步,每列都是一个单独的时间序列。这是将并行时间序列存储在CSV文件中的标准方法。

from numpy import array
from numpy import hstack

# convert to [rows, columns] structure
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))
# horizontally stack columns
dataset = hstack((in_seq1, in_seq2, out_seq))

下面列出了完整的示例:

# multivariate data preparation
from numpy import array
from numpy import hstack
# define input sequence
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))])
# convert to [rows, columns] structure
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))
# horizontally stack columns
dataset = hstack((in_seq1, in_seq2, out_seq))
print(dataset)

运行该示例将打印数据集,每个时间步长为一行,两个输入和一个输出并行时间序列分别为一列。

[[ 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可以支持并行输入时间序列作为单独的变量或特征。因此,我们需要将数据分成样本,保持两个输入序列的观察顺序。

如果我们选择三个输入时间步长,那么第一个样本将如下所示:

输入:

10, 15
20, 25
30, 35

输出:

65

也就是说,每个并行系列的前三个时间步长被提供作为模型的输入,并且模型将其与第三时间步骤(在这种情况下为65)的输出系列中的值相关联。

我们可以看到,在将时间序列转换为输入/输出样本以训练模型时,我们将不得不从输出时间序列中丢弃一些值,其中我们在先前时间步骤中没有输入时间序列中的值。反过来,选择输入时间步数的大小将对使用多少训练数据产生重要影响。

我们可以定义一个名为split_sequences()的函数,该函数将采用数据集,因为我们已经定义了时间步长的行和并行系列的列以及返回输入/输出样本。

# split a multivariate sequence into samples
def split_sequences(sequences, n_steps):
    X, y = list(), list()
    for i in range(len(sequences)):
	# find the end of this pattern
	end_ix = i + n_steps
	# check if we are beyond the dataset
	if end_ix > len(sequences):
	    break
	# gather input and output parts of the pattern
	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)

我们可以使用每个输入时间序列的三个时间步长作为输入在我们的数据集上测试此函数。

下面列出了完整的示例。

# multivariate data preparation
from numpy import array
from numpy import hstack

# split a multivariate sequence into samples
def split_sequences(sequences, n_steps):
    X, y = list(), list()
    for i in range(len(sequences)):
	# find the end of this pattern
	end_ix = i + n_steps
	# check if we are beyond the dataset
	if end_ix > len(sequences):
	    break
	# gather input and output parts of the pattern
	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)

# define input sequence
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))])
# convert to [rows, columns] structure
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))
# horizontally stack columns
dataset = hstack((in_seq1, in_seq2, out_seq))
# choose a number of time steps
n_steps = 3
# convert into input/output
X, y = split_sequences(dataset, n_steps)
print(X.shape, y.shape)
# summarize the data
for i in range(len(X)):
    print(X[i], y[i])

首先运行该示例将打印X和y组件的形状。

我们可以看到X组件具有三维结构。

第一个维度是样本数,在本例中为7.第二个维度是每个样本的时间步数,在这种情况下为3,即为函数指定的值。最后,最后一个维度指定并行时间序列的数量或变量的数量,在这种情况下,两个并行序列为2。

这是LSTM作为输入所期望的精确三维结构。数据即可使用而无需进一步重塑。

然后我们可以看到每个样本的输入和输出都被打印出来,显示了两个输入序列中每个样本的三个时间步长以及每个样本的相关输出

(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,例如香草,堆叠,双向,CNN或ConvLSTM模型。

我们将使用Vanilla LSTM,其中通过input_shape参数为输入层指定时间步数和并行系列(特征)。

# define model
model = Sequential()
model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features)))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')

在进行预测时,模型需要两个输入时间序列的三个时间步长。

我们可以预测输出系列中的下一个值,提供以下输入值:

80,	 85
90,	 95
100, 105

具有三个时间步长和两个变量的一个样本的形状必须是[1,3,2]。

我们希望序列中的下一个值为100 + 105或205。

# demonstrate prediction
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)

下面列出了完整的示例。

# multivariate lstm example
from numpy import array
from numpy import hstack
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense

# split a multivariate sequence into samples
def split_sequences(sequences, n_steps):
	X, y = list(), list()
	for i in range(len(sequences)):
		# find the end of this pattern
		end_ix = i + n_steps
		# check if we are beyond the dataset
		if end_ix > len(sequences):
			break
		# gather input and output parts of the pattern
		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)

# define input sequence
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))])
# convert to [rows, columns] structure
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))
# horizontally stack columns
dataset = hstack((in_seq1, in_seq2, out_seq))
# choose a number of time steps
n_steps = 3
# convert into input/output
X, y = split_sequences(dataset, n_steps)
# the dataset knows the number of features, e.g. 2
n_features = X.shape[2]
# define model
model = Sequential()
model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features)))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
# fit model
model.fit(X, y, epochs=200, verbose=0)
# demonstrate prediction
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)

运行该示例准备数据,拟合模型并进行预测。

[[208.13531]]

还有另一种更精细的方法来模拟问题。

每个输入序列可以由单独的MLP处理,并且可以在对输出序列进行预测之前组合这些子模型中的每一个的输出。

我们可以将其称为多头输入MLP模型。根据正在建模的问题的具体情况,它可以提供更大的灵活性或更好的性能。

可以使用Keras功能API在Keras中定义此类型的模型。

首先,我们可以将第一个输入模型定义为MLP,其输入层需要具有n_steps特征的向量。

还有另一种更精细的方法来模拟问题。

每个输入序列可以由单独的MLP处理,并且可以在对输出序列进行预测之前组合这些子模型中的每一个的输出。

我们可以将其称为多头输入MLP模型。根据正在建模的问题的具体情况,它可以提供更大的灵活性或更好的性能。

可以使用Keras功能API在Keras中定义此类型的模型。

首先,我们可以将第一个输入模型定义为MLP,其输入层需要具有n_steps特征的向量。

# first input model
visible1 = Input(shape=(n_steps,))
dense1 = Dense(100, activation='relu')(visible1)

 我们可以以相同的方式定义第二个输入子模型。

# second input model
visible2 = Input(shape=(n_steps,))
dense2 = Dense(100, activation='relu')(visible2)

既然已经定义了两个输入子模型,我们可以将每个模型的输出合并为一个长向量,可以在对输出序列进行预测之前对其进行解释。

# merge input models
merge = concatenate([dense1, dense2])
output = Dense(1)(merge)

然后我们可以将输入和输出联系在一起。

model = Model(inputs=[visible1, visible2], outputs=output)

下图提供了该模型外观的示意图,包括每层输入和输出的形状。

此模型要求输入作为两个元素的列表提供,其中列表中的每个元素包含一个子模型的数据。

为了实现这一点,我们可以将3D输入数据分成两个独立的输入数据阵列:即从一个形状为[7,3,2]的阵列到两个形状为[7,3]的2D阵列

# separate input data
X1 = X[:, :, 0]
X2 = X[:, :, 1]

然后可以提供这些数据以适合模型。

# fit model
model.fit([X1, X2], y, epochs=2000, verbose=0)

类似地,我们必须在进行单个一步预测时将单个样本的数据准备为两个单独的二维数组。

x_input = array([[80, 85], [90, 95], [100, 105]])
x1 = x_input[:, 0].reshape((1, n_steps))
x2 = x_input[:, 1].reshape((1, n_steps))

我们可以将所有这些结合在一起; 下面列出了完整的示例。

# multivariate mlp example
from numpy import array
from numpy import hstack
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.merge import concatenate

# split a multivariate sequence into samples
def split_sequences(sequences, n_steps):
	X, y = list(), list()
	for i in range(len(sequences)):
		# find the end of this pattern
		end_ix = i + n_steps
		# check if we are beyond the dataset
		if end_ix > len(sequences):
			break
		# gather input and output parts of the pattern
		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)

# define input sequence
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))])
# convert to [rows, columns] structure
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))
# horizontally stack columns
dataset = hstack((in_seq1, in_seq2, out_seq))
# choose a number of time steps
n_steps = 3
# convert into input/output
X, y = split_sequences(dataset, n_steps)
# separate input data
X1 = X[:, :, 0]
X2 = X[:, :, 1]
# first input model
visible1 = Input(shape=(n_steps,))
dense1 = Dense(100, activation='relu')(visible1)
# second input model
visible2 = Input(shape=(n_steps,))
dense2 = Dense(100, activation='relu')(visible2)
# merge input models
merge = concatenate([dense1, dense2])
output = Dense(1)(merge)
model = Model(inputs=[visible1, visible2], outputs=output)
model.compile(optimizer='adam', loss='mse')
# fit model
model.fit([X1, X2], y, epochs=2000, verbose=0)
# demonstrate prediction
x_input = array([[80, 85], [90, 95], [100, 105]])
x1 = x_input[:, 0].reshape((1, n_steps))
x2 = x_input[:, 1].reshape((1, n_steps))
yhat = model.predict([x1, x2], verbose=0)
print(yhat)

运行该示例准备数据,拟合模型并进行预测。

[[205.7405]]

好像更精确了耶

  • 23
    点赞
  • 116
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
LSTM变量预测流程图是用于预测多个变量的长短期记忆神经网络的流程图。该流程图主要包括数据准备、模型构建和预测三个主要步骤。 首先,在数据准备阶段,我们需要准备用于训练和预测的多个变量的数据。这些变量可以是时间序列数据,例如股票价格、天气数据等。我们可以使用历史数据来构建训练集和测试集,并进行数据预处理,如归一化、平滑等。 然后,我们进入模型构建阶段。在该阶段,我们使用LSTM神经网络模型来进行多变量预测。LSTM模型输入层、隐藏层和输出层组成。输入层接收多个变量的数据作为输入,隐藏层通过记忆单元和门控单元来学习和记忆数据的长期和短期依赖关系。最后,输出层将预测结果输出。 在LSTM模型的训练阶段,我们使用训练集来训练模型。通过迭代训练,模型逐渐调整权重和偏差,以最小化预测值与实际值之间的误差。在训练过程中,我们可以使用损失函数来衡量预测误差,并使用优化器来更新模型的参数。 最后,在预测阶段,我们使用训练好的LSTM模型来进行多变量的预测。将测试集或新的数据输入模型中,通过前向传播得到预测结果。可以通过逆归一化等方法将预测结果转化为实际值,并与实际观测值进行比较以评估预测的准确性。 综上所述,LSTM变量预测流程图包括数据准备、模型构建和预测三个步骤,通过这个流程图,我们可以了解并应用LSTM神经网络进行多变量预测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值