我想在节日期间亲身体验Keras的经验,我想我会从时间序列预测库存数据的教科书示例开始。所以我要做的是给出最后48小时的平均价格变化(自上次以来的百分比),预测未来一小时的平均价格差异。
然而,当针对测试集(或甚至训练集)进行验证时,预测序列的幅度偏离,有时会转变为总是正的或总是负的,即偏离0%的变化我觉得这种事情是正确的。
我想出了以下最小例子来说明问题:
df = pandas.DataFrame.from_csv('test-data-01.csv', header=0)
df['pct'] = df.value.pct_change(periods=1)
seq_len=48
vals = df.pct.values[1:] # First pct change is NaN, skip it
sequences = []
for i in range(0, len(vals) - seq_len):
sx = vals[i:i+seq_len].reshape(seq_len, 1)
sy = vals[i+seq_len]
sequences.append((sx, sy))
row = -24
trainSeqs = sequences[:row]
testSeqs = sequences[row:]
trainX = np.array([i[0] for i in trainSeqs])
trainy = np.array([i[1] for i in trainSeqs])
model = Sequential()
model.add(LSTM(25, batch_input_shape=(1, seq_len, 1)))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
model.fit(trainX, trainy, epochs=1, batch_size=1, verbose=1, shuffle=True)
pred = []
for s in trainSeqs:
pred.append(model.predict(s[0].reshape(1, seq_len, 1)))
pred = np.array(pred).flatten()
plot(pred)
plot([i[1] for i in trainSeqs])
axis([2500, 2550,-0.03, 0.03])
正如您所看到的,我创建了训练和测试序列,通过选择最近48小时,然后进入元组的下一步,然后提前1小时,重复该过程。该模型是一个非常简单的1 LSTM和1个密集层。
我原本预计个别预测点的图可以很好地重叠训练序列的图(毕竟这是他们训练过的相同集),以及测试序列的匹配类型。但是,我在培训数据:
上得到以下结果知道可能会发生什么吗?我误解了什么吗?
更新:为了更好地显示移位和压扁的含义,我还通过将其移回以匹配实际数据并乘以匹配幅度来绘制预测值。
plot(pred*12-0.03)
plot([i[1] for i in trainSeqs])
axis([2500, 2550,-0.03, 0.03])
正如你所看到的那样,预测非常适合真实的数据,它只是被压扁并以某种方式偏移,我无法弄清楚原因。
答案 0 :(得分:8)
我认为你过度拟合,因为数据的维数是1,而25个单位的LSTM对于这样的低维数据集来说似乎相当复杂。这是我要尝试的一系列事项:
更新。让我总结一下我们在评论部分讨论过的内容。
为了澄清,第一个图不显示验证集的预测序列,但是针对训练集。因此,我的第一个过度拟合解释可能不准确。我认为一个恰当的问题是:实际上是否有可能从这样的低维数据集中预测未来的价格变化?机器学习算法并不神奇:它们只有在数据存在的情况下才会在数据中找到模式。
如果仅过去价格变化确实没有提供未来价格变动的信息,那么:
如果在时间步长t和t + 1的值一般更加相关,那么我假设模型对这种相关性更有信心,并且预测的幅度会更大。
答案 1 :(得分:2)
尝试所有这些并尝试过度拟合(mse应该在真实数据集上大约为零)。然后应用正规化。
更新
让我解释一下你为什么选择
plot(pred*12-0.03)
很合适。
好的,我们将LSTM图层视为黑盒而忘记它。它返回了25个值 - 这就是全部。 该值前进到Dense图层,我们将其应用于25个值函数的向量:
y = w * x + b
这里 w 和 b - 由NN定义并且在开头的向量通常接近于零。 x - LSTM图层后的值和 y - 目标(单个值)。
虽然您只有1个纪元:w和b根本不适合您的数据(实际上它们大约为零)。但是,如果你申请
怎么办?plot(pred*12-0.03)
到你的预测值?您(某种程度上)适用于目标变量 w 和 b 。现在 w 和 b 是单个值,而不是矢量,它们应用于单个值。但它们(几乎)与密集层完成相同的工作。
因此,增加时代数量以获得更好的拟合。
UPDATE2 顺便说一下,我在数据中看到了一些异常值。您也可以尝试将MAE用作损失/准确度指标。
答案 2 :(得分:0)
这周我遇到了同样的问题,并且找到了解决方案。唯一对我有用的方法是使用如下所述的窗口标准化方法:
https://www.altumintelligence.com/articles/a/Time-Series-Prediction-Using-LSTM-Deep-Neural-Networks
(检查有关sp500预测的部分)
祝你有美好的一天:)
答案 3 :(得分:0)
因为我在这一点上以及增加batch_size有助于SimpleRNN完全修复LSTM问题,relu,elu作为激活,学习率必须从默认增加,并尝试配置一些SmoteRNN的灵魂以获得更多过去的数据,或者更改行之间的时间段以获取更多数据供模型查找模式,似乎对我有用,atm,仍在尝试将准确度提高到 80% 以上, 准确率 = (mean_abosule_error / test.mean()) * 100