Я только что построил эту нейронную сеть LSTM с Keras
import numpy as np
import pandas as pd
from sklearn import preprocessing
from keras.layers.core import Dense, Dropout, Activation
from keras.activations import linear
from keras.layers.recurrent import LSTM
from keras.models import Sequential
from matplotlib import pyplot
#read and prepare data from datafile
data_file_name = "DailyDemand.csv"
data_csv = pd.read_csv(data_file_name, delimiter = ';',header=None, usecols=[1,2,3,4,5])
yt = data_csv[1:]
data = yt
data.columns = ['MoyenneTransactHier', 'MaxTransaction', 'MinTransaction','CountTransaction','Demand']
# print (data.head(10))
pd.options.display.float_format = '{:,.0f}'.format
data = data.dropna ()
y=data['Demand'].astype(int)
cols=['MoyenneTransactHier', 'MaxTransaction', 'MinTransaction','CountTransaction']
x=data[cols].astype(int)
#scaling data
scaler_x = preprocessing.MinMaxScaler(feature_range =(-1, 1))
x = np.array(x).reshape ((len(x),4 ))
x = scaler_x.fit_transform(x)
scaler_y = preprocessing.MinMaxScaler(feature_range =(-1, 1))
y = np.array(y).reshape ((len(y), 1))
y = scaler_y.fit_transform(y)
print("longeur de y",len(y))
# Split train and test data
train_end = 80
x_train=x[0: train_end ,]
x_test=x[train_end +1: ,]
y_train=y[0: train_end]
y_test=y[train_end +1:]
x_train=x_train.reshape(x_train.shape +(1,))
x_test=x_test.reshape(x_test.shape + (1,))
print("Data well prepared")
print ('x_train shape ', x_train.shape)
print ('y_train', y_train.shape)
#Design the model - LSTM Network
seed = 2016
np.random.seed(seed)
fit1 = Sequential ()
fit1.add(LSTM(
output_dim = 4,
activation='tanh',
input_shape =(4, 1)))
fit1.add(Dense(output_dim =1))
fit1.add(Activation(linear))
#rmsprop or sgd
batchsize = 1
fit1.compile(loss="mean_squared_error",optimizer="rmsprop")
#train the model
fit1.fit(x_train , y_train , batch_size = batchsize, nb_epoch =20, shuffle=True)
print(fit1.summary ())
#Model error
score_train = fit1.evaluate(x_train ,y_train ,batch_size =batchsize)
score_test = fit1.evaluate(x_test , y_test ,batch_size =batchsize)
print("in train MSE = ",round(score_train,4))
print("in test MSE = ",round(score_test ,4))
#Make prediction
pred1=fit1.predict(x_test)
pred1 = scaler_y.inverse_transform(np.array(pred1).reshape ((len(pred1), 1)))
real_test = scaler_y.inverse_transform(np.array(y_test).reshape ((len(y_test), 1))).astype(int)
#save prediction
testData = pd.DataFrame(real_test)
preddData = pd.DataFrame(pred1)
dataF = pd.concat([testData,preddData], axis=1)
dataF.columns =['Real demand','Predicted Demand']
dataF.to_csv('Demandprediction.csv')
pyplot.plot(pred1, label='Forecast')
pyplot.plot(real_test,label='Actual')
pyplot.legend()
pyplot.show()
тогда это генерирует этот результат:
После построения и обучения хорошей модели на исторических данных, я не знаю, как я могу сгенерировать прогноз для будущих значений? Например спрос на ближайшие 10 дней. Данные ежедневно.
NB: это пример того, как данные формируются, зеленый - это метка, а желтый - это особенности.
после dropna()
(удалить нулевые значения) остается 100 строк данных, я использовал 80 в обучении и 20 в тесте.
Ответы:
Поскольку вы используете слово « горизонт» , я предполагаю, что вы имеете в виду, что вы хотели бы предсказать 10 дней в будущем с заданным временным шагом. Есть несколько способов сделать это. При такой проблеме временных рядов принято делать предположение о том, что только следующие данные будут влиять на следующие несколько временных шагов (без учета сезонных эффектов).
Пример на словах:
Таким образом, в вашем случае вы можете использовать, например, предыдущие 60 дней и прогнозировать следующие 10. Если взять в качестве примера 100 строк данных, это означает, что вы можете делать
(100 - 60 - 9) = 31
прогнозы, каждый прогноз на 10 временных шагов вперед (нам понадобятся эти 31 предсказательный_блок позже). Из 100 рядов мы теряем первые 60, чтобы соответствовать первой модели. Из оставшихся 40 строк данных мы можем предсказать 10 шагов вперед (строки 61-70), затем мы сдвигаем все на одну строку дальше и повторяем. Последний прогноз 10 будущих точек будет для строк 91-100. После этого мы больше не можем прогнозировать 10 шагов, поэтому мы останавливаемся - и именно поэтому мы должны вычесть эти дополнительные 9. [Конечно, есть способы продолжить делать прогноз, используя все данные]Пример с тысячей слов:
Позвольте мне нарисовать картину; чтобы помочь объяснить идею предсказания сдвига окна.
Для каждого набора поездов (например, с
t=0
поt=5
в красный - набор поездов 1) вы хотите предсказать следующие H временных шагов (соответствующих t = 6 в оранжевом - тестовый набор 1). В этом, ваш горизонт просто один естьH=1
.Насколько я понимаю, вы хотели бы, чтобы предсказать , в ближайшие 10 дней, то есть вам нужно
H=10
.Для того, чтобы попробовать это с вашим примером, я думаю, что вам нужно будет сделать два изменения.
Изменение № 1
Форма вашего поезда и тестовых наборов должна соответствовать новому горизонту. Каждый образец ввода вашей модели (
x_train
иx_test
может оставаться прежним. Однако каждый образец в вашем наборе тестов должен содержать следующиеH=10
значения метки, а не только одно значение.Вот грубый пример того, как вы могли бы сделать это:
Поскольку вы проводите внеплановое тестирование, ваши прогнозы уже интересны для анализа. После этого вы можете создать эквивалентные наборы тестовых данных с новыми данными, которые вы упомянули.
Не зная ваших данных слишком хорошо, я не знаю, должны ли вы предсказывать значения y той же строки, что и входные данные, или следующей строки. Кроме того, в зависимости от ваших данных, вы можете включить прошлые значения
y
в каждый изx_train
блоков. В этом случае вы бы просто поменялиx
всю таблицу, т.е.data[cols]
гдеnew_cols = ['Demand'] + cols
.Изменение № 2
Вам нужно будет заставить модель отражать этот горизонт, заставляя ее выводить
H
значения.Вот пример того, как указать модель:
Примечание. В спецификации модели не требуется добавлять конечную линейную
Activation
линию, поскольку предыдущий слой Dense по умолчанию включает линейную активацию. Смотрите отличную документацию здесь .Это большая тема, и есть много вещей, которые вы можете попробовать. Я согласен с комментариями по вашему вопросу, что вам понадобится намного больше данных, чтобы RNN мог представить смысл модели.
Если вы не просто делаете это, чтобы узнать о LSTM и т. Д., Другим практическим подходом может быть изучение более простых моделей временных рядов, таких как модель ARIMA (не пугайтесь сложного имени - это намного проще, чем LSTM) , Такие модели можно легко построить с помощью Python, используя пакет statsmodels , который имеет хорошую реализацию .
источник