#!/usr/bin/env python # coding: utf-8 # # Predicción de Series Temporales NN - Multivariate # El artículo completo con la explicación detallada en el blog: http://www.aprendemachinelearning.com/ # ## Usaremos Keras y Tensorflow # Importamos las Librerías que vamos a utilizar # In[161]: import pandas as pd import numpy as np import matplotlib.pylab as plt get_ipython().run_line_magic('matplotlib', 'inline') plt.rcParams['figure.figsize'] = (16, 9) plt.style.use('fast') from keras.models import Sequential from keras.layers import Dense,Activation,Flatten from sklearn.preprocessing import MinMaxScaler # ### Cargamos nuestro Dataset # In[162]: df = pd.read_csv('time_series.csv', parse_dates=[0], header=None,index_col=0, names=['fecha','unidades']) df.head() # ### Cargamos Datos Categóricos: Día y Mes # In[163]: df['weekday']=[x.weekday() for x in df.index] df['month']=[x.month for x in df.index] df.head() # In[164]: df.describe() # # Preprocesado de los datos # In[ ]: # convert series to supervised learning def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): n_vars = 1 if type(data) is list else data.shape[1] df = pd.DataFrame(data) cols, names = list(), list() # input sequence (t-n, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) if i == 0: names += [('var%d(t)' % (j+1)) for j in range(n_vars)] else: names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)] # put it all together agg = pd.concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg # In[165]: PASOS=7 # load dataset values = df['unidades'].values # ensure all data is float values = values.astype('float32') # normalize features scaler = MinMaxScaler(feature_range=(-1, 1)) values=values.reshape(-1, 1) # esto lo hacemos porque tenemos 1 sola dimension scaled = scaler.fit_transform(values) df['scaled'] = scaled scaledMerge=df.drop('unidades',axis=1) #print(scaledMerge.values) # frame as supervised learning reframed = series_to_supervised(scaledMerge, PASOS, 1) reframed.head() # ## Dividimos en set de Entrenamiento y Validación # In[166]: newReframed=reframed.drop(['var1(t)','var2(t)'],axis=1) print(newReframed.shape) newReframed.head() # In[167]: # split into train and test sets values = newReframed.values n_train_days = 315+289 - (30+PASOS) train = values[:n_train_days, :] test = values[n_train_days:, :] # split into input and outputs x_train, y_train = train[:, :-1], train[:, -1] x_val, y_val = test[:, :-1], test[:, -1] # reshape input to be 3D [samples, timesteps, features] x_train = x_train.reshape((x_train.shape[0], 1, x_train.shape[1])) x_val = x_val.reshape((x_val.shape[0], 1, x_val.shape[1])) print(x_train.shape, y_train.shape, x_val.shape, y_val.shape) # # Creamos el Modelo de Red Neuronal # ## Utilizaremos una Red Feedforward # ### Como entradas son 21 columnas (7 pasos por 3 variables) # In[168]: def crear_modeloFF(): model = Sequential() model.add(Dense(PASOS, input_shape=(1,PASOS*3),activation='tanh')) model.add(Flatten()) model.add(Dense(1, activation='tanh')) model.compile(loss='mean_absolute_error',optimizer='Adam',metrics=["mse"]) model.summary() return model # ## Entrenamos nuestra máquina # In[169]: EPOCHS=40 model = crear_modeloFF() history=model.fit(x_train,y_train,epochs=EPOCHS,validation_data=(x_val,y_val),batch_size=PASOS) # ## Visualizamos Resultados # In[183]: results=model.predict(x_val) print( len(results) ) plt.scatter(range(len(y_val)),y_val,c='g') plt.scatter(range(len(results)),results,c='r') plt.title('validate') plt.show() # In[186]: plt.ylim(0.12, 0.35) plt.plot(history.history['loss']) plt.title('loss') plt.plot(history.history['val_loss']) plt.title('validate loss') plt.show() # In[191]: plt.ylim(0.01, 0.18) plt.title('Accuracy') plt.plot(history.history['mean_squared_error']) plt.show() # In[173]: compara = pd.DataFrame(np.array([y_val, [x[0] for x in results]])).transpose() compara.columns = ['real', 'prediccion'] inverted = scaler.inverse_transform(compara.values) compara2 = pd.DataFrame(inverted) compara2.columns = ['real', 'prediccion'] compara2['diferencia'] = compara2['real'] - compara2['prediccion'] compara2.head(10) # In[174]: compara2.describe() # In[192]: compara2['real'].plot() compara2['prediccion'].plot() # # Pronóstico # A partir de la última semana de noviembre 2018, intentaremos predecir la primer semana de diciembre. # In[150]: ultimosDias = df['2018-11-16':'2018-11-30'] ultimosDias # ## Preparamos los datos para Test # In[151]: scaledMerge=ultimosDias.drop('unidades',axis=1) print(scaledMerge.values) # frame as supervised learning reframed = series_to_supervised(scaledMerge, PASOS, 1) newReframed=reframed.drop(['var1(t)','var2(t)','var3(t)'],axis=1) newReframed.head(7) # In[153]: values = newReframed.values x_test = values[6:, :] x_test = x_test.reshape((x_test.shape[0], 1, x_test.shape[1])) print(x_test.shape) print(x_test) ultDiaSemana = newReframed.index[len(newReframed.index)-1].weekday() # In[154]: def agregarNuevoValor(x_test,nuevoValor,ultDiaSemana): for i in range(x_test.shape[2]-3): x_test[0][0][i] = x_test[0][0][i+3] ultDiaSemana=ultDiaSemana+1 if ultDiaSemana>6: ultDiaSemana=0 x_test[0][0][x_test.shape[2]-3]=ultDiaSemana x_test[0][0][x_test.shape[2]-2]=12 x_test[0][0][x_test.shape[2]-1]=nuevoValor return x_test,ultDiaSemana # ## Pronóstico para la "próxima semana" # In[155]: results=[] for i in range(7): parcial=model.predict(x_test) results.append(parcial[0]) print('pred',i,x_test) x_test,ultDiaSemana=agregarNuevoValor(x_test,parcial[0],ultDiaSemana) # ## Re-Convertimos los resultados # In[156]: adimen = [x for x in results] print(adimen) inverted = scaler.inverse_transform(adimen) inverted # ## Visualizamos el pronóstico # In[157]: prediccion1SemanaDiciembre = pd.DataFrame(inverted) prediccion1SemanaDiciembre.columns = ['pronostico'] prediccion1SemanaDiciembre.plot() prediccion1SemanaDiciembre.to_csv('pronostico_multivariate.csv') # In[158]: prediccion1SemanaDiciembre # El artículo completo en www.aprendemachinelearning.com