时序数据预处理

 

作者:Cyril-KI
链接:https://www.zhihu.com/question/532003877/answer/2581549999
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本科做了很长一段时间的负荷预测,我来说说正确的数据处理办法吧。

首先,你需要将所有数据分成三个部分(当然可以不要验证集,一般论文里我们是返回验证集上的最优模型):训练集、验证集和测试集,也就是把3000行数据分成三部分,一般是622或者712,这里以622为例,也就是说训练集中有1800条数据,验证集和测试集各600条数据。

然后你需要对训练集中的数据进行归一化,例如最大最小值归一化,然后假设你使用前100个数据预测接下来10个数据(比如你可以用前100个数据的300个特征预测接下来10个数据的某一个或者某几个特征,例如你可以用前100个时刻的ABCDE特征预测接下来10个时刻的A特征或者10个时刻的ABC特征,这里以10个A特征为例),那么此时你构建的第1个样本应该为(X=1...100,Y=101...110),第二个样本为(X=2...101,Y=102...111),最后一个样本为(X=1691...1790,Y=1791...1800)。

这样,你的训练集中一个包含了1691个样本,然后你就可以进一步进行分批处理。分批处理前你可以打乱这1691个样本,这种打乱是不会对LSTM的训练造成影响的,因为每个样本的内部是有序的,LSTM处理的是这100个数据间的时序关系。但是如果你用sgd或者minibatch,一般来讲靠前的batch会对模型梯度造成更大影响,为了公平起见,可以选择打乱数据。

打乱数据后就可以开始进行批次处理,比如batch_size=100,也就是将1691个样本每100个分为一组,这样你一共可以得到17个batch的数据,除了最后一个bacth的X为(batch_size=91,seq_len=100, input_size=5),Y为(batch=91, output_size=1)以外,其他16个batch的X为(batch_size=100,seq_len=100, input_size=5),Y为(batch=100, output_size=1)。

对验证集和测试集,你应该首先利用训练集的最值对这两个数据集进行归一化,然后按照训练集的处理方式依次进行样本构造、数据打乱以及分批处理三个步骤。

所有数据处理完之后,训练集中的17个batch将依次送入LSTM中进行训练。

需要注意的是:训练集和验证集打乱是为了模型训练得更好,但测试集不要进行打乱操作,因为这样你将无法按照时间顺序来得到正确的预测值!!

作者:Cyril-KI
链接:https://www.zhihu.com/question/532003877/answer/2581549999
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

def load_data(file_name):
    df = pd.read_csv('data/new_data/' + file_name, encoding='gbk')
    columns = df.columns
    df.fillna(df.mean(), inplace=True)
    return df


class MyDataset(Dataset):
    def __init__(self, data):
        self.data = data

    def __getitem__(self, item):
        return self.data[item]

    def __len__(self):
        return len(self.data)
    
    
def nn_seq_us(B):
    print('data processing...')
    dataset = load_data()
    # split
    train = dataset[:int(len(dataset) * 0.6)]
    val = dataset[int(len(dataset) * 0.6):int(len(dataset) * 0.8)]
    test = dataset[int(len(dataset) * 0.8):len(dataset)]
    m, n = np.max(train[train.columns[1]]), np.min(train[train.columns[1]])

    def process(data, batch_size, shuffle):
        load = data[data.columns[1]]
        load = load.tolist()
        data = data.values.tolist()
        load = (load - n) / (m - n)
        seq = []
        for i in range(len(data) - 24):
            train_seq = []
            train_label = []
            for j in range(i, i + 24):
                x = [load[j]]
                train_seq.append(x)
            # for c in range(2, 8):
            #     train_seq.append(data[i + 24][c])
            train_label.append(load[i + 24])
            train_seq = torch.FloatTensor(train_seq)
            train_label = torch.FloatTensor(train_label).view(-1)
            seq.append((train_seq, train_label))

        # print(seq[-1])
        seq = MyDataset(seq)
        seq = DataLoader(dataset=seq, batch_size=batch_size, shuffle=shuffle, num_workers=0, drop_last=False)

        return seq

    Dtr = process(train, B, True)
    Val = process(val, B, True)
    Dte = process(test, B, False)

    return Dtr, Val, Dte, m, n

  

上面的案例是利用前24小时的某一个特征预测接下来一个小时的该特征。

关于LSTM时间序列预测,我之前写过一个专栏:

https://www.zhihu.com/column/c_1527411172555223041

里面包含了单变量单步预测、单变量多步预测、多变量多步预测(五种实现方式:直接多输出、单步滚动预测、多模型单步预测、多模型滚动预测以及seq2seq)、多输入多输出预测(多任务学习)、CNN预测、ANN预测、CNN-LSTM混合模型预测以及Transformer预测等内容,希望对你有所帮助!

posted on 2022-09-06 13:21  lmqljt  阅读(427)  评论(0编辑  收藏  举报

导航