Acabei de construir esta rede neural LSTM com 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()
Depois de criar e treinar um bom modelo com os dados históricos, não sei como posso gerar a previsão de valores futuros? Por exemplo, a demanda dos próximos 10 dias. Os dados são diários.
Nota: este é um exemplo de como os dados são modelados, o verde é o rótulo e o amarelo são os recursos.
depois de dropna()
(excluir valores nulos) permanecerem 100 linhas de dados, usei 80 no treinamento e 20 no teste.
Respostas:
Como você usa a palavra horizonte , assumirei que você quer dizer que gostaria de prever 10 dias no futuro em um determinado momento. Existem algumas maneiras de fazer isso. Com esse tipo de problema de série temporal, é comum supor que apenas uma determinada história influenciará os próximos passos (negligenciando os efeitos sazonais).
Exemplo em palavras:
Portanto, no seu caso, você pode usar, por exemplo, os 60 dias anteriores e prever os próximos 10. Tomando suas 100 linhas de dados como exemplo, isso significa que você pode realmente fazer
(100 - 60 - 9) = 31
previsões, cada previsão de 10 passos à frente (precisaremos destes 31 predictive_blocks mais tarde). De 100 linhas, perdemos os 60 primeiros para caber no primeiro modelo. Das 40 linhas de dados restantes, podemos prever 10 etapas à frente (linhas 61 a 70); depois, mudamos a coisa toda uma linha ainda mais e repetimos. A última previsão de 10 pontos futuros seria para as linhas 91-100. Depois disso, não podemos mais prever 10 etapas, então paramos - e é por isso que temos que subtrair esses 9. extras. [É claro que existem maneiras de continuar fazendo previsões, para usar todos os dados]Exemplo com mil palavras:
Deixe-me pintar a imagem; para ajudar a explicar a ideia de uma previsão de mudança de janela.
Para cada conjunto de trens (por exemplo, de
t=0
parat=5
no conjunto de trens vermelho 1), você deseja prever os seguintes intervalos de tempo H (correspondentes a t = 6 no conjunto de testes laranja 1). Neste, o seu horizonte é simplesmente um ieH=1
.Pelo que entendi, você gostaria de prever os próximos 10 dias, o que significa que precisa
H=10
.Para tentar fazer isso com o seu exemplo, acho que você precisará fazer duas alterações.
Alteração # 1
A forma do seu trem e conjuntos de teste precisará corresponder ao novo horizonte. Cada amostra da entrada do seu modelo (
x_train
ex_test
pode permanecer a mesma de antes. No entanto, cada amostra no seu conjunto de testes precisará conter os próximosH=10
valores do rótulo, não apenas um valor único.Aqui está um exemplo aproximado de como você pode fazer isso:
Como você está testando fora da amostra, suas previsões já são interessantes para analisar. Depois que isso for executado, você poderá criar os conjuntos de dados de teste equivalentes com os novos dados mencionados.
Sem conhecer seus dados muito bem, não sei se você deve prever os valores y da mesma linha que a entrada ou da linha seguinte. Além disso, dependendo dos seus dados, você pode incluir os valores passados de
y
em cada um dosx_train
blocos. Nesse caso, você simplesmente trocariax
a tabela inteiradata[cols]
, ou seja , ondenew_cols = ['Demand'] + cols
.Alteração 2
Você precisará fazer o modelo refletir esse horizonte, forçando-o a gerar
H
valores.Aqui está um exemplo de como especificar o modelo:
Nota: Na especificação do modelo, você não precisa adicionar o linear final
Activation
, pois a camada Densa anterior, por padrão, inclui uma ativação linear. Veja a excelente documentação aqui .Este é um tópico importante e há muitas coisas que você pode experimentar. Concordo com os comentários da sua pergunta, de que você precisará de muito mais dados para permitir que uma RNN faça uma representação significativa do modelo.
Se você não está apenas fazendo isso para aprender sobre LSTMs etc., outra abordagem prática pode ser procurar modelos mais simples de séries temporais , como um modelo ARIMA (não se deixe intimidar pelo nome complicado - é muito mais simples que um LSTM) . Tais modelos podem ser construídos facilmente com o Python, usando o pacote statsmodels , que possui uma boa implementação .
fonte