Właśnie zbudowałem tę sieć neuronową LSTM za pomocą 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()
Po zbudowaniu i przeszkoleniu dobrego modelu na danych historycznych nie wiem, jak wygenerować prognozę dla przyszłych wartości? Na przykład zapotrzebowanie na następne 10 dni. Dane są codziennie.
Uwaga: jest to przykład kształtu danych, zielony to etykieta, a żółty to cechy.
po dropna()
(usuń wartości zerowe) pozostaje 100 wierszy danych, użyłem 80 w szkoleniu i 20 w teście.
Odpowiedzi:
Ponieważ używasz słowa horyzont , zakładam, że masz na myśli, że chcesz przewidzieć 10 dni w przyszłości na danym etapie czasu. Można to zrobić na kilka sposobów. W przypadku tego rodzaju problemu szeregów czasowych często przyjmuje się założenie, że tylko pewna historia wpłynie na kilka kolejnych kroków czasowych (pomijając efekty sezonowe).
Przykład słownie:
Więc w twoim przypadku możesz wykorzystać np. Poprzednie 60 dni i przewidzieć następne 10. Biorąc za przykład swoje 100 wierszy danych, oznacza to, że możesz faktycznie
(100 - 60 - 9) = 31
przewidywać każde przewidywanie 10 kroków w przód (będziemy potrzebować tych 31 przewidywania_bloki później). Ze 100 rzędów tracimy pierwsze 60 pasujących do pierwszego modelu. Z pozostałych 40 wierszy danych możemy przewidzieć 10 kroków do przodu (wiersze 61–70), a następnie przesuwać całość o jeden wiersz dalej i powtarzać. Ostatnia prognoza 10 przyszłych punktów dotyczyłaby rzędów 91–100. Po tym nie możemy już przewidzieć 10 kroków, więc przestajemy - i dlatego musimy odjąć te dodatkowe 9. [Istnieją oczywiście sposoby dalszego przewidywania, jak wykorzystać wszystkie dane]Przykład z tysiącem słów:
Pozwól mi pomalować obraz; aby wyjaśnić ideę przewidywania zmiany okna.
Dla każdego zestawu pociągów (np. Od
t=0
dot=5
na czerwono - zestaw 1) chcesz przewidzieć następujące kroki czasu H (odpowiadające t = 6 na pomarańczowo - zestaw testowy 1). W tym twój horyzont jest po prostu jeden tjH=1
.Z tego, co rozumiem, chciałbyś przewidzieć następne 10 dni, co oznacza, że potrzebujesz
H=10
.Aby wypróbować to na przykładzie, myślę, że musisz wprowadzić dwie zmiany.
Zmień nr 1
Kształt pociągu i zestawów testowych będzie musiał pasować do nowego horyzontu. Każda próbka danych wejściowych modelu (
x_train
ix_test
może pozostać taka sama jak poprzednio. Jednak każda próbka w zestawie testowym będzie musiała zawierać kolejneH=10
wartości etykiety, a nie tylko jedną wartość.Oto przybliżony przykład tego, jak możesz to zrobić:
Ponieważ wykonujesz testy poza próbą, twoje prognozy są już interesujące do analizy. Po uruchomieniu możesz utworzyć równoważne zestawy danych testowych z nowymi danymi, o których wspomniałeś.
Nie znając zbyt dobrze danych, nie wiem, czy powinieneś przewidywać wartości y tego samego wiersza, co danych wejściowych, czy następnego. Dodatkowo, w zależności od twoich danych, możesz dołączyć poprzednie wartości dla
y
każdego zx_train
bloków. W takim przypadku po prostu zamieniłbyśx
cały stół, tj .data[cols]
Gdzienew_cols = ['Demand'] + cols
.Zmień nr 2
Musisz zmusić model do odzwierciedlenia tego horyzontu, zmuszając go do uzyskania
H
wartości wyjściowych .Oto przykład, jak określić model:
Uwaga: W specyfikacji modelu nie trzeba dodawać końcowej linii liniowej
Activation
, ponieważ poprzednia gęsta warstwa domyślnie zawiera aktywację liniową. Zobacz doskonałą dokumentację tutaj .To duży temat i jest wiele rzeczy, które możesz wypróbować. Zgadzam się z komentarzami do twojego pytania, że będziesz potrzebował znacznie więcej danych, aby RNN mógł reprezentować znaczenie modelu.
Jeśli nie robisz tego tylko po to, aby dowiedzieć się o LSTM itp., Innym praktycznym podejściem może być przyjrzenie się prostszym modelom szeregów czasowych, takim jak model ARIMA (nie zastraszaj się skomplikowaną nazwą - jest znacznie prostszy niż LSTM) . Takie modele można dość łatwo zbudować za pomocą Pythona, używając pakietu statsmodels , który ma niezłą implementację .
źródło