Je viens de construire ce réseau neuronal LSTM avec 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()
Après avoir construit et formé un bon modèle sur les données historiques, je ne sais pas comment générer la prédiction pour les valeurs futures? Par exemple, la demande des 10 prochains jours. Les données sont quotidiennes.
NB: ceci est un exemple de la forme des données, le vert est l'étiquette et le jaune les caractéristiques.
après dropna()
(supprimer les valeurs nulles), il reste 100 lignes de données, j'en ai utilisé 80 dans la formation et les 20 dans le test.
Réponses:
Parce que vous utilisez le mot horizon , je suppose que vous voulez dire que vous aimeriez prévoir 10 jours dans le futur à un pas de temps donné. Il y a plusieurs façons de procéder. Avec ce type de problème de séries chronologiques, il est courant de supposer que seule une certaine histoire influencera les prochaines étapes temporelles (en négligeant les effets saisonniers).
Exemple en mots:
Donc, dans votre cas, vous pouvez utiliser, par exemple, les 60 derniers jours et prédire les 10 prochains. En prenant vos 100 lignes de données comme exemple, cela signifie que vous pouvez réellement faire des
(100 - 60 - 9) = 31
prédictions, chaque prédiction de 10 pas de temps à l'avance (nous en aurons besoin 31 blocs prédictifs plus tard). À partir de 100 rangs, nous perdons les 60 premiers pour s'adapter au premier modèle. Sur les 40 lignes de données restantes, nous pouvons prédire 10 pas en avant (lignes 61 à 70), puis nous déplaçons le tout une ligne plus loin et répétons. La dernière prédiction de 10 futurs points serait pour les lignes 91-100. Après cela, nous ne pouvons plus prédire 10 étapes, alors nous nous arrêtons - et c'est pourquoi nous devons soustraire ce 9. supplémentaire. [Il y a bien sûr des moyens de continuer à faire des prédictions, comme d'utiliser toutes les données]Exemple avec mille mots:
Permettez-moi de peindre l'image; pour aider à expliquer l'idée d'une prédiction de fenêtre mobile.
Pour chaque train (par exemple de
t=0
àt=5
en rouge - train 1), vous voulez prédire les pas de temps H suivants (correspondant à t = 6 en orange - jeu de test 1). En cela, votre horizon est simplement un ieH=1
.D'après ce que je comprends, vous souhaitez prédire les 10 prochains jours, ce qui signifie que vous avez besoin
H=10
.Pour essayer cela avec votre exemple, je pense que vous devrez apporter deux modifications.
Changement # 1
La forme de votre train et de vos ensembles de tests devra correspondre au nouvel horizon. Chaque échantillon de votre entrée de modèle (le
x_train
etx_test
peut rester le même qu'auparavant. Cependant, chaque échantillon de votre ensemble de test devra contenir lesH=10
valeurs suivantes de l'étiquette, pas seulement une seule valeur.Voici un exemple approximatif de la façon dont vous pouvez procéder:
Parce que vous effectuez des tests hors échantillon, vos prévisions sont déjà intéressantes à regarder. Une fois que cela s'exécute, vous pouvez ensuite créer les jeux de données de test équivalents avec les nouvelles données que vous avez mentionnées.
Sans trop bien connaître vos données, je ne sais pas si vous devez prédire les valeurs y de la même ligne que l'entrée ou de la ligne suivante. De plus, en fonction de vos données, vous pouvez inclure les valeurs passées de
y
dans chacun desx_train
blocs. Dans ce cas, vous échangeriez simplementx
la table entière, c'est-à-diredata[cols]
oùnew_cols = ['Demand'] + cols
.Changement # 2
Vous devrez faire en sorte que le modèle reflète cet horizon, en le forçant à afficher des
H
valeurs.Voici un exemple de la façon de spécifier le modèle:
Remarque: Dans la spécification de votre modèle, vous n'avez pas besoin d'ajouter le linéaire final
Activation
, car la couche dense précédente comprend par défaut une activation linéaire. Voir l'excellente documentation ici .C'est un gros sujet et il y a beaucoup de choses que vous pourriez essayer. Je suis d'accord avec les commentaires sur votre question, selon lesquels vous aurez besoin de beaucoup plus de données pour permettre à un RNN de faire une représentation significative du modèle.
Si vous ne faites pas cela uniquement pour en savoir plus sur les LSTM, etc., une autre approche pratique pourrait consister à étudier des modèles de séries chronologiques plus simples tels qu'un modèle ARIMA (ne vous laissez pas intimider par le nom compliqué - c'est beaucoup plus simple qu'un LSTM) . De tels modèles peuvent être construits assez facilement avec Python, en utilisant le package statsmodels , qui a une belle implémentation .
la source