python - 如何处理预测值的偏移

标签 python machine-learning keras deep-learning forecasting

我在 Keras 中使用 LSTM 实现了一个预测模型。数据集间隔 15 分钟,我预测 future 的 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)

我是这样预测的

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 是我需要预测的那个。我放弃了 future 的 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 学习吗?

最佳答案

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

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 美元,则预测 6340 美元或 t+1 时的收盘价将使误差最小化。但实际上算法并没有学习任何模式;它只是复制,所以它基本上除了完成其优化任务外什么都不做。

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

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

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

关于python - 如何处理预测值的偏移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52252442/

相关文章:

Python:访问列表中的多个元素

python - 如何使用 Keras 预训练 MLP 的最后一个隐藏层权重作为新 MLP(迁移学习)的输入?

performance - 什么是机器学习中的调优?

python - 使用CNN和两个输入进行预测

python - keras 分类报告中的正类精度为零

python - 正则表达式 - 要求在\d+ 中包含特定数字?

python - 我只想将 kivy 的 MapView 放入我的应用程序的屏幕中,通过初始菜单上的按钮进行访问

android - 如何在android中通过adb检测屏幕变化

matlab - 避免逻辑挤压函数中的无穷大

python - 无法恢复类 TextVectorization 的图层 - 文本分类