当前位置: 首页 > 知识库问答 >
问题:

多元输入多步LSTM时间序列预测模型的奇问题

窦国源
2023-03-14

根据教程,我为我的数据集开发了多元输入多步骤LSTM时间序列预测模型(https://machinelearningmastery.com/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/).

然而,我有一个非常奇怪的问题,那就是,当我使用较小的样本(50个样本用于训练,10个样本用于测试)运行代码时,预测是正确的。但是当我使用全样本(4000个样本用于训练,1000个样本用于测试)进行实验时,预测包含NaN值,这会导致错误。

然后,当我尝试缩放加上relu激活函数再加上正则化(如下代码)时,我可以得到全样本的预测(4000个样本用于训练,1000个样本用于测试),但预测仍然不正确,我想预测96个步骤,但我预测的所有步骤都是相同的数字。

你能提供一个有用的建议来处理预测的准确性问题吗?

import time
from math import sqrt
from numpy import split
from numpy import array
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from matplotlib import pyplot
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers import LSTM
from keras.layers import RepeatVector
from keras.layers import TimeDistributed
import csv
import numpy
from sklearn.preprocessing import MinMaxScaler
from numpy import save
from timeit import default_timer as timer

def scale(train, test):
    # fit scaler
    scaler = MinMaxScaler(feature_range=(-1, 1))
    train = train.astype(float)
    test = test.astype(float)
    scaler = scaler.fit(train)
    # transform train
    train = train.reshape(train.shape[0], train.shape[1])
    train_scaled = scaler.transform(train)
    # transform test
    test = test.reshape(test.shape[0], test.shape[1])
    test_scaled = scaler.transform(test)
    return scaler, train_scaled, test_scaled

# split a univariate dataset into train/test sets


def split_dataset(data):
    # split into standard weeks
    train, test = data[0:387030, 10:26], data[387030:433881, 10:26]
    # train, test = data[0:4850, 10:26], data[4850:5820, 10:26]
    # train, test = data[0:387030], data[387029:433880]
    # restructure into windows of weekly data
    # numpy.savetxt("test.csv", data[387030:433881, :], delimiter=",")
    # save('test.npy', data[387030:433881, :])
    scaler, train_scaled, test_scaled = scale(train, test)

    train_scaled = array(split(train_scaled, len(train_scaled) / 97))

    test_scaled = array(split(test_scaled, len(test_scaled) / 97))
    return scaler, train_scaled, test_scaled

# create a list of configs to try


def model_configs():
    # define scope of configs
    # n_input = [12]
    n_nodes = [100, 200, 300]
    n_epochs = [50, 100]
    n_batch = [64]
    # n_diff = [12]
    # create configs
    configs = list()
    # for i in n_input:
    for j in n_nodes:
        for k in n_epochs:
            for l in n_batch:
                cfg = [j, k, l]
                configs.append(cfg)
    print('Total configs: %d' % len(configs))
    return configs

# evaluate one or more weekly forecasts against expected values


def evaluate_forecasts(actual, predicted):
    scores = list()
    # calculate an RMSE score for each day
    for i in range(0, actual.shape[1], 97):
        # for i in range():
        # calculate mse
        mse = mean_squared_error(actual[:, i, :], predicted[:, i, :])
        # calculate rmse
        rmse = sqrt(mse)
        # store
        scores.append(rmse)
    # calculate overall RMSE
    s = 0
    for x in range(actual.shape[0]):
        for y in range(actual.shape[1]):
            for z in range(actual.shape[2]):
                s += (actual[x, y, z] - predicted[x, y, z])**2
    score = sqrt(s / (actual.shape[0] * actual.shape[1] * actual.shape[2]))
    return score, scores


# convert history into inputs and outputs


def to_supervised(train, n_steps_in, n_steps_out=97, overlop=97):
    # flatten data
    sequences = train.reshape(
        (train.shape[0] * train.shape[1], train.shape[2]))
    X, y = list(), list()
    for i in range(0, len(sequences), overlop):

        end_ix = i + n_steps_in

        out_end_ix = end_ix + n_steps_out
        # check if we are beyond the dataset
        if out_end_ix > len(sequences):
            break
        # gather input and output parts of the pattern
        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)

# train the model


def build_model(train, n_input, config):
    # unpack config
    n_nodes, n_epochs, n_batch = config
    # prepare data
    train_x, train_y = to_supervised(train, n_input)
    # define parameters
    verbose, epochs, batch_size = 0, n_epochs, n_batch
    n_timesteps, n_features, n_outputs = train_x.shape[1], train_x.shape[2], train_y.shape[1]
    # reshape output into [samples, timesteps, features]
    train_y = train_y.reshape((train_y.shape[0], train_y.shape[1], n_features))
    # define model
    model = Sequential()
    model.add(
        LSTM(
            n_nodes,
            activation='relu',
            input_shape=(
                n_timesteps,
                n_features), recurrent_dropout=0.6))
    model.add(RepeatVector(n_outputs))
    model.add(LSTM(n_nodes, activation='relu', return_sequences=True, recurrent_dropout=0.6))
    model.add(TimeDistributed(Dense(n_nodes, activation='relu')))
    model.add(TimeDistributed(Dense(n_features)))
    model.compile(loss='mse', optimizer='adam')
    # fit network
    model.fit(
        train_x,
        train_y,
        epochs=epochs,
        batch_size=batch_size,
        verbose=verbose)
    return model

# make a forecast


def forecast(model, history, n_input):
    # flatten data
    data = array(history)
    data = data.reshape((data.shape[0] * data.shape[1], data.shape[2]))
    # retrieve last observations for input data
    input_x = data[-n_input:, :]
    # reshape into [1, n_input, n]
    input_x = input_x.reshape((1, input_x.shape[0], input_x.shape[1]))
    # forecast the next week
    yhat = model.predict(input_x, verbose=0)
    # we only want the vector forecast
    yhat = yhat[0]
    return yhat

# evaluate a single model


def evaluate_model(train, test, n_input, cfg):

    start = timer()

    # fit model
    model = build_model(train, n_input, cfg)

    # print("--- %s seconds ---" % (time.time() - start_time))
    # history is a list of weekly data
    history = [x for x in train]
    # walk-forward validation over each week
    predictions = list()

    for i in range(len(test)):
        # predict the week
        yhat_sequence = forecast(model, history, n_input)
        # store the predictions
        predictions.append(yhat_sequence)
        # get real observation and add to history for predicting the next week
        history.append(test[i, :])
    # evaluate predictions days for each week
    predictions = array(predictions)

    # invert scaling

    predictions = predictions.reshape(
        (predictions.shape[0] *
         predictions.shape[1],
         predictions.shape[2]))
    predictions = scaler.inverse_transform(predictions)

    test = test.reshape((test.shape[0] * test.shape[1], test.shape[2]))
    test = scaler.inverse_transform(test)


    predictions = array(split(predictions, len(predictions) / 97))

    test = array(split(test, len(test) / 97))
    score, scores = evaluate_forecasts(test, predictions)
    run_time = timer() - start
    return cfg[0], cfg[1], cfg[2], score, scores, run_time


# load the new file
dataset = read_csv(
    'data_preproccess_5.csv',
    header=0,
    index_col=0)
# split into train and test
scaler, train_scaled, test_scaled = split_dataset(dataset.values)
# evaluate model and get scores
n_input = 7 * 97

# model configs
cfg_list = model_configs()

scores = [
    evaluate_model(
        train_scaled,
        test_scaled,
        n_input,
        cfg) for cfg in cfg_list]

提供一些示例数据示例数据

共有1个答案

翟永春
2023-03-14

如果你有多步输出,你可以很容易地重塑你的预测并计算它。

`trainX, trainY, testX, testY`
`trainPredict = model.predict(trainX)`
`testPredict = model.predict(testX)`
`trainY = trainY.reshape(-1, )`
`trainPredict = trainPredict.reshape(-1, )`

`testY = testY.reshape(-1, )`
`testPredict = testPredict.reshape(-1, )`
`print('Train Root mean squared error: {}'.format(math.sqrt(mean_squared_error(trainY, trainPredict))))`
`print('Test Root mean squared error: {}'.format(math.sqrt(mean_squared_error(testY, testPredict))))`
 类似资料:
  • 我试图使用LSTM对多元数据进行时间序列预测。我有50000个15维的样品。我想用10的回顾。输入到LSTM层的形状是什么。会吗 或 我正在使用Keras。

  • 我有一个包含一整年数据的时间序列数据集(日期是索引)。数据每15分钟测量一次(全年),结果是每天96个时间步。数据已规范化。这些变量是相关的。除VAR外的所有变量都是天气度量值。 VAR在一天期间和一周期间都是季节性的(因为它在周末看起来有点不同,但每个周末都不一样)。VAR值是固定的。我想预测未来两天(前192步)和未来七天(前672步)的VAR值。 以下是数据集的示例: 下面是我准备train

  • 我正在阅读Keras中关于使用LSTM进行多元时间序列预测的教程https://machinelearningmastery.com/multivariate-time-series-forecasting-lstms-keras/#comment-442845 我已经看完了整个教程,遇到了一个如下的问题- 在本教程中,在步骤“t-1”中,列车和测试拆分有8个功能,即“污染”、“露水”、“温度”、

  • 我想在Pytorch中实现多变量输入的LSTM。 在这篇使用keras的文章https://machinelearningmastery.com/how-to-develop-lstm-models-for-time-series-forecasting/之后,输入数据的形状是(样本数、时间步数、并行特征数) 在keras,这似乎很容易:

  • 我试图使用Keras对多个变量进行同时预测。在这里使用这个例子,我想预测所有特征的值,包括pm 2.5,DEWP,TEMP等,而不仅仅是污染(pm 2.5)。本质上,这是,给定所有变量,建立一个模型来预测所有变量作为时间序列,而不仅仅是预测一个变量。 我使用重塑后的3D数据修改了原始示例代码,但出现了一个错误。代码如下: 输出为: 数据集在这里可用。 我的问题是: Keras LSTM层不是为此设

  • 我是时间序列的新手,需要学科专家的帮助。所以我有一个有11个变量的实验室数据,报告了时间。10个变量是可控的,第11个变量是输出。我用LSTM预测了第11个变量的时间序列。结果比预期好得多。第11个变量预测为0.001 RMSE。训练数据有5000个样本,测试数据有4599个。我对预测很满意。现在我需要分析输入10个变量是如何影响第11个输出变量的。请建议一个好的库,类似问题的教程。