【问题标题】:How to handle Shift in Forecasted value如何处理预测值的变化
【发布时间】:2019-02-14 13:44:22
【问题描述】:

我在 Keras 中使用 LSTM 实现了一个预测模型。数据集间隔 15 分钟,我预测 12 个未来步骤。

该模型在该问题上表现良好。但是做出的预测存在一个小问题。它显示了一个小的移位效果。要获得更清晰的图片,请参见下图。

如何处理这个问题。?必须如何转换数据才能处理此类问题。

我使用的模型如下所示

init_lstm = RandomUniform(minval=-.05, maxval=.05)
init_dense_1 = RandomUniform(minval=-.03, maxval=.06)

model = Sequential()

model.add(LSTM(15, input_shape=(X.shape[1], X.shape[2]), kernel_initializer=init_lstm, recurrent_dropout=0.33))

model.add(Dense(1, kernel_initializer=init_dense_1, activation='linear'))

model.compile(loss='mae', optimizer=Adam(lr=1e-4))

history = model.fit(X, y, epochs=1000, batch_size=16, validation_data=(X_valid, y_valid), verbose=1, shuffle=False)

我做了这样的预测

my_forecasts = model.predict(X_valid, batch_size=16)

使用此函数将时间序列数据转换为有监督的数据以馈送 LSTM

# convert time series into supervised learning problem
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    # put it all together
    agg = concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg

super_data = series_to_supervised(data, 12, 1)

我的时间序列是多变量的。 var2 是我需要预测的。我放弃了未来var1 喜欢

del super_data['var1(t)']

分开的火车和这样有效

features = super_data[feat_names]
values = super_data[val_name]

ntest = 3444

train_feats, test_feats = features[0:-n_test], features[-n_test:]
train_vals, test_vals = values [0:-n_test], values [-n_test:]

X, y = train_feats.values, train_vals.values
X = X.reshape(X.shape[0], 1, X.shape[1])

X_valid, y_valid = test_feats .values, test_vals .values
X_valid = X_valid.reshape(X_valid.shape[0], 1, X_valid.shape[1])

我没有为这个预测制作固定的数据。我也尝试过差异化,尽可能让模型保持静止,但问题仍然存在。

我还尝试了 min-max 缩放器的不同缩放范围,希望它可以帮助模型。但预测越来越差。

Other Things I have tried

=> Tried other optimizers
=> Tried mse loss and custom log-mae loss functions
=> Tried varying batch_size
=> Tried adding more past timesteps
=> Tried training with sliding window and TimeSeriesSplit

我知道模型正在向它复制最后一个已知值,从而尽可能地减少损失

验证和训练损失在整个训练过程中保持足够低。这让我思考是否需要为此设计一个新的损失函数。

有必要吗?如果是这样,我应该使用什么损失函数?

我已经尝试了所有我偶然发现的方法。我根本找不到任何指向此类问题的资源。这是数据的问题吗?这是因为 LSTM 很难学习这个问题吗?

【问题讨论】:

  • 请出示您的代码,您可能使用了错误的 y_test 和 y_train 但不看您的代码很难知道。
  • @VegardKT 代码在某种意义上是模型的代码或我用于测试的代码。?
  • 两者都最好
  • 好的。给我一分钟
  • 到目前为止一切都很好,你能说明你是如何定义你的 x 和 y 的吗?

标签: python machine-learning keras deep-learning forecasting


【解决方案1】:

您在以下位置寻求我的帮助:

stock prediction : GRU model predicting same given values instead of future stock price

希望不会迟到。你可以尝试的是你可以转移你的特征的数字明确性。让我解释一下:

与我在上一个主题中的回答类似;回归算法将使用您提供的时间窗口中的值作为样本,以最小化错误。假设您试图预测 BTC 在时间 t 的收盘价。您的一项功能包括先前的收盘价,并且您提供了从 t-20 到 t-1 的最后 20 个输入的时间序列窗口。 在这种情况下,回归器可能会学习在时间步 t-1 或 t-2 选择收盘值或收盘值,即作弊。可以这样想:如果 t-1 的收盘价为 6340 美元,预测 t+1 时的收盘价为 6340 美元或接近的价格将使误差最小化。但实际上该算法并没有学习任何模式;它只是复制,所以它基本上除了完成它的优化任务之外什么都不做。

从我的例子中类似地思考:通过转移明确性,我的意思是:不要直接给出收盘价,而是缩放它们或根本不使用明确的价格。不要使用任何明确显示算法收盘价的特征,不要在每个时间步使用开盘价、最高价、最低价等。您需要在这里发挥创造力,设计功能以摆脱显式的功能;你可以给出平方接近的差异(回归量仍然可以从过去的线性差异中窃取,有经验),它与体积的比率。或者,可以通过以有意义的方式将特征数字化来使特征分类。 关键是不要直接直观地知道它应该预测什么,只提供算法工作的模式。

可能会根据您的任务建议更快的方法。如果预测你的标签有多少变化对你来说是足够的,你可以进行多类分类,只是要小心类不平衡的情况。如果只是上下波动对您来说就足够了,您可以直接进行二进制分类。 只有在回归任务中才会出现复制或移位问题,前提是您没有将数据从训练集泄漏到测试集。如果可能,请摆脱时间序列窗口应用程序的回归。

如果有任何误解或遗漏,我会在附近。希望我能帮上忙。祝你好运。

【讨论】:

  • 感谢您分享的信息。我不能对我的问题使用分类,因为我需要准确的预测值而不是它的方向。
  • 你能分享一些我可以尝试消除显性的方法吗?
  • 1) 不要给出一些直接对标签是什么进行数字直觉的特征。 2)尝试非线性特征,例如平方根、平方差等,而不是直接给出输入 3)你可以给出特征之间的比率(注意除数部分不能为零或太小)。 4)你可以尝试预测时间t和t-1的标签之间的差异,而不是直接预测它。然后你可以用它来创建你的标签,欺骗欺骗性的回归者。注意:您创建的特征必须有意义,您不能只是尝试随机比率;考虑模式。
  • 谢谢。我会尽力让你知道
  • @user5803658 我自己解决了这个问题,并用我所知道的轰炸了这里。有人也确实让我知道她/他在这里的帮助下解决了她/他的问题。但是,我不知道问题所有者是否解决了她/他的问题。
【解决方案2】:

您的 LSTM 很可能正在学习粗略地猜测其先前的输入值是什么(稍微调制)。这就是为什么你会看到“转变”。

假设您的数据如下所示:

x = [1, 1, 1, 4, 5, 4, 1, 1]

你的 LSTM 学会了只输出当前时间步的前一个输入。然后您的输出将如下所示:

y = [?, 1, 1, 1, 4, 5, 4, 1]

因为您的网络有一些复杂的机器,所以并不是那么简单,但原则上您看到的“转变”是由这种现象引起的。

【讨论】:

  • 我该如何处理这个问题?
  • 任何类型的转换或数据准备都可以在这种情况下提供帮助吗?
  • @SreeramTP 预测的标签应该具有单变量(季节性,趋势,周期性)或与其他特征的相关性以预测未来,如果两者都没有,网络无法学习预测,所以它只是遵循先前的数据以显示预测。请清理您的数据并进行必要的预处理,
  • @NagaKiran 我已经提到了我在问题中所做的预处理。请建议除此之外还能做什么。我试着让这个系列静止。 DF 检验给出的结果几乎是平稳的。我还使用了与目标相关的其他特征,那么问题仍然存在
  • @SreeramTP 我怀疑这是一个棘手的问题。 LSTM 没有足够的信号来学习——所以它最终只是预测了前一个时间步。您可以尝试更清晰的损失函数(例如立方平方误差),但我的猜测是它们只会使训练变得不稳定。您还可以预测输出的 a 分布。例如,如果您预测高斯的均值/对数标准差,您将能够看到预测的不确定性估计值如何随数据波动而变化。
猜你喜欢
  • 1970-01-01
  • 2018-08-02
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多