Я пытаюсь получить опыт работы с 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])
Поскольку вы можете видеть, что предсказание прекрасно подходит к реальным данным, оно просто как-то раздавлено и компенсируется, и я не могу понять, почему.