如何处理预测值中的Shift

11
我在Keras中使用LSTM实现了一个预测模型。数据集是15分钟分隔的,我正在预测未来12步。该模型对于这个问题表现良好。但是预测结果存在一个小偏移效应。要获得更清晰的图片,请参见下面附加的图表。

enter image description here

如何处理这个问题?数据必须如何转换以处理这种问题?

我使用的模型如下所示

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)

I made the forecasts like this

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])

我还没有为这个预测使数据平稳化。我也尝试过取差分并使模型尽可能平稳,但问题仍然存在。
我也尝试了不同的最小-最大缩放器比例,希望能改善模型。但预测结果变得更糟了。
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
@VegardKT 的代码是指模型的代码还是我用于测试的代码? - Sreeram TP
both preferably - VegardKT
好的,请给我一分钟。 - Sreeram TP
到目前为止还不错,你能展示一下如何定义你的x和y吗? - VegardKT
@VegardKT 我已经编辑了我的问题。 - Sreeram TP
2个回答

14
您在以下链接中寻求帮助:股票预测:GRU模型预测相同的给定值而不是未来的股票价格。建议您尝试将特征的数字明确性转移,以避免回归算法只是复制并欺骗的情况。例如,不要直接提供收盘价等显式信息给算法,可以通过比例或者使用分类特征等方式,提供算法可用的模式,但不要直接提供预测的直觉。对于时间序列窗口应用程序,如果可能的话,请避免回归任务。如果需要进一步帮助,请随时联系我。祝好运!

感谢您分享的信息。我不能使用分类来解决我的问题,因为我需要精确的预测值而不是它的方向。 - Sreeram TP
你能分享一些我可以尝试的去除显式性的方法吗? - Sreeram TP
1
  1. 不要直接给出一些特征,让人们对标签有数值上的直觉。2) 尝试非线性特征,如平方根、平方差等,而不是直接给出输入。3) 可以给出特征之间的比率(注意除数部分不应为零或太小)。4) 可以尝试预测时间t和t-1之间标签的差异,而不是直接预测它。然后可以使用它来创建标签,欺骗作弊的回归器。注意:您创建的特征必须有意义,不能随意尝试比率;考虑模式。
- Ugur MULUK
1
谢谢。我会尝试并让你知道。 - Sreeram TP
@user5803658 我已经在我的端解决了这个问题,并在此分享我的解决方案。有人也告诉我她/他通过这里得到了帮助解决了自己的问题。但是,我不知道问题的提出者是否已经解决了她/他的问题。 - Ugur MULUK

3
很可能你的LSTM正在学习猜测其先前输入值(略微调节)的大致情况。这就是为什么你会看到“偏移”的原因。
假设你的数据如下:
x = [1, 1, 1, 4, 5, 4, 1, 1]

如果你的LSTM只学会将前一个输入直接输出为当前时间步的输出,那么你的输出将如下所示:

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

因为您的网络拥有一些复杂的机制,所以这并不是很简单明了的,但原则上您看到的“移位”是由这种现象引起的。


我该如何处理这个问题? - Sreeram TP
@SreeramTP 预测标签应该具有单变量(季节性、趋势、周期性)或与其他特征的相关性,以预测未来。如果它没有这两个条件,网络就无法学习预测,因此只能跟随先前的数据显示预测结果。请清理您的数据并进行必要的预处理。 - Naga kiran
@SreeramTP 我怀疑这是一个棘手的问题。 LSTM没有足够的信号可供学习-因此最终会仅预测上一个时间步长。您可以尝试更锐利的损失函数(例如立方平方误差),但我猜想它们只会使训练不稳定。您还可以预测输出的分布。例如,如果您为高斯分布预测均值/对数标准差,您将能够看到随着数据波动性变化而预测的不确定性估计如何改变。 - Alex
@Alex,如果我能收集更高分辨率的数据,这会有帮助吗? - Sreeram TP
@SreeramTP 就学习而言,确实有更多的信号可以学习,但我猜这不会有太大的影响。 - Alex
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接