用LSTM进行时间序列预测(单步,多步,单变量,多变量)

0. LSTM用于时间序列预测

LSTM因其具有记忆的功能,可以利用很长的序列信息来建立学习模型,所以用它来进行时间序列的预测会很有优势。

在实际工程中用LSTM进行时间序列的预测主要有两个难点:一是前期对数据的处理二是初始模型的搭建

  • 对数据的处理无论是单步、多步、单变量还是多变量都会用到滑动窗口来处理数据,具体处理的方法后面会进行阐述;

  • 而对模型的搭建则要根据要解决的问题,原始数据的情况等,对模型的参数做相应的设定,如果单纯的LSTM无法满足要求,一般会加入全连接层来解决。

1. 单变量单步

单变量单步的预测是最简单的,比如说有一组数据为:

[1,2,3,4,5,6,7,8,9,10],然后要求利用这组数据训练一个模型,使其能对后面提供的数据做一个单步的预测。

我们先来对数据进行处理,处理的时候要根据不同框架所要求的LSTM的输入形式来处理,比如我们用Pytorch框架的时候输入要求是(seq_len, batch, input_size)

因为是单变量的数据,我们令input_size=3,然后设seq_len=7,然后batch为1,

处理后的数据变为:

[[1,2,3], =====> [4]

[2,3,4], =====> [5]

[3,4,5], =====> [6]

[4,5,6], =====> [7]

[5,6,7], =====> [8]

[6,7,8], =====> [9]

[7,8,9]] =====> [10]

前半部分是输入,箭头指向输出。也就是说将数据分批输入LSTM,没三个数据对应一个单步的预测目标。


数据处理好之后就是模型的搭建了,我们根据输入输出的形式来反推模型的结构

我们知道LSTM的结构是lstm = nn.LSTM(input_size, hidden_size, num_layers)。由上面给出的输入的形式可以确定input_size=3, hidden_size, num_layers这两个参数要自己设置,也就是隐藏层的大小和层数。我们的预计输出的形式为(7,1),但是LSTM的标准输出形式为:

output=(seq_len,batch,num_directionshidden_size)=(7,1,num_directionshidden_size),

当num_directionshidden_size不为1时我们需要在LSTM的后面加一个全连接层,并令全连接层的输入形式为num_directionshidden_size,输出为1 。这样我们的输出就变为了output=(7,1,1) ,然后用reshape方法(当out为numpy array时)或者view方法(当out为tensor时)将output整形为(7,1)。这样就可以用在后面的训练中了,即计算损失函数和反向传播。

2. 多变量多步

比如一组数据为:

[[1,11],[2,12],[3,13],[4,14],[5,15],[6,16],[7,17],[8,18],[9,19],[10,20]]

要求对其进行两步预测,则我们对其进行处理:

[[[1,11],[2,12],[3,13]], ======>[[4,14],[5,15]]

[[2,12],[3,13],[4,14]], ======>[[5,15],[6,16]]

[[3,13],[4,14],[5,15]], ======>[[6,16],[7,17]]

[[4,14],[5,15],[6,16]], ======>[[7,17],[8,18]]

[[5,15],[6,16],[7,17]], ======>[[8,18],[9,19]]

[[6,16],[7,17],[8,18]], ======>[[9,19],[10,20]]

前半部分是输入,箭头指向输出。seq_len=6,batch=3,input_size=2

搭建模型的部分跟上面的分析是一样的,output的形状跟target一样为(6,2,2),而输入的形状为(6,3,2),所以还是需要一个全连接层使其输入为(6,3,2)输出为(6,2,2),这样才能用在后面的训练中。

最后如果要画出输出的图像的话可以取out[:3, 0, :]和out[:,1,:]在axis=0上拼接出来。

下面是模型的建立:

class LSTM(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers):
        super(LSTM, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, 2)  # 2 for bidirection

    def forward(self, x):
        # Set initial states
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)  # 2 for bidirection
        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)

        # Forward propagate LSTM
        out, _ = self.lstm(x, (h0, c0))  # out: tensor of shape (batch_size, seq_length, hidden_size*2)
        # print("output_in=", out.shape)
        # print("fc_in_shape=", out[:, -1, :].shape)
        # Decode the hidden state of the last time step
        # out = torch.cat((out[:, 0, :], out[-1, :, :]), axis=0)
        # out = self.fc(out[:, -1, :])  # 取最后一列为out
        out = self.fc(out)
        return out

3. 其余情况

单变量多步和多变量单步的情况的处理方法跟上面两个是类似的。

基于LSTM的时间序列数据(多步)预测

如何进行多变量LSTM时间序列预测未来一周的数据?

用LSTM预测未来一个月航班数

多维多步预测

你可能感兴趣的:(lstm,lstm,深度学习,机器学习)