%pip install numpy==1.19.5
%pip install tensorflow==2.1
%matplotlib inline
# Importamos TensorFlow y Keras
import tensorflow as tf
import tensorflow.keras as keras
# Importamos el modelo Sequential
from tensorflow.keras.models import Sequential
# Importamos las capas que utilizaremos
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv1D, MaxPool1D, LSTM, GRU
# Importamos el normalizador de los datos
from sklearn.preprocessing import MinMaxScaler, StandardScaler
#importamos los optimizadores
from tensorflow.keras.optimizers import RMSprop, Adam
# Importamos el evaluador de la predicción
from sklearn.metrics import mean_absolute_error, mean_squared_error
# Importamos las librerias de análisis de datos
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import datetime, random, math
# Dependencia necesaria para descomponer las graficas y corroborar su estacionalidad.
from statsmodels.tsa.seasonal import seasonal_decompose
# Controlamos la aleatoriedad con una semilla
np.random.seed(42)
tf.random.set_seed(42)
# Controlamos los warning
import warnings
warnings.filterwarnings('ignore')
from google.colab import drive
drive.mount('/content/drive/')
%cd 'drive/MyDrive/data'
df = pd.read_csv('demanda_electrica_diaria.csv')
data_electrica = df[['fecha','sistema','dmin','dmax']]
data_electrica
data_electrica.info()
# Transformaremos la columna fecha que se encuentra en formato "string" (object) a formato "fecha" (datetime)
data_electrica['fecha'] = pd.to_datetime(data_electrica['fecha'], format='%d/%m/%Y')
# Luego dejaremos nuestra columna fecha como indice del DataFrame
data_electrica = data_electrica.set_index('fecha')
# Transformaremos la columna sistema que se encuentra en formato "string" (object) a formato "categorico" (category)
data_electrica['sistema'] = data_electrica['sistema'].astype('category')
# Luego tenemos los formatos que queremos.
data_electrica.info()
# Veremos que tenemos 3 categorias en la columna sistema
data_electrica['sistema'].unique()
sns.boxplot(data = df, x = 'sistema', y='dmin')
plt.show()
sns.boxplot(data = df, x = 'sistema', y='dmax')
plt.show()
# Dividimos la data según los sitemas
data_sic = data_electrica[data_electrica['sistema'] == 'SIC']
data_sing = data_electrica[data_electrica['sistema'] == 'SING']
data_sen = data_electrica[data_electrica['sistema'] == 'SEN']
print(f'Tenemos un total de {data_sic.shape[0]} datos en el sistema SIC')
print(f'Tenemos un total de {data_sing.shape[0]} datos en el sistema SING')
print(f'Tenemos un total de {data_sen.shape[0]} datos en el sistema SEN')
print(f'El sistema SIC dispone de {data_sic.index.min()} hasta {data_sic.index.max()}')
print(f'El sistema SING dispone de {data_sing.index.min()} hasta {data_sing.index.max()}')
print(f'El sistema SEN dispone de {data_sen.index.min()} hasta {data_sen.index.max()}')
data_sic
# Comenzamos por ver la demanda mínima del SIC
plt.figure(figsize=(10,5))
plt.plot(data_sic['dmin'], c='b', label = 'SIC')
plt.title('Demanda mínima diaria SIC', fontsize = 20)
plt.xlabel('años', fontsize = 18)
plt.ylabel('MW', fontsize = 18)
plt.legend(loc = 'lower right', fontsize = 14)
plt.show()
data_sic_mes = data_sic.resample('M').sum()
data_sic_mes
plt.figure(figsize=(10,5))
plt.plot(data_sic_mes['dmin'], c='r', label = 'dmin')
#plt.plot(data_sic_mes['dmean'], c='b', label = 'dmean')
plt.plot(data_sic_mes['dmax'], c = 'g', label = 'dmax')
plt.title('Demanda mensual SIC', fontsize = 20)
plt.xlabel('años', fontsize = 18)
plt.ylabel('MW', fontsize = 18)
plt.legend(loc = 'lower right', fontsize = 11)
plt.show()
fig = plt.figure(figsize=(10,10))
ax = plt.subplot(2,1,1)
ax.plot(data_sic_mes['dmin'].loc['2015'].values, label = 'dmin 2015')
ax.plot(data_sic_mes['dmin'].loc['2016'].values, label = 'dmin 2016')
ax.plot(data_sic_mes['dmin'].loc['2017'].values, label = 'dmin 2017')
plt.title('Últimos 3 años demanda mínima SIC', fontsize = 18)
plt.ylabel('MW', fontsize = 16)
plt.legend(loc = 'lower right', fontsize = 11)
ax = plt.subplot(2,1,2)
ax.plot(data_sic_mes['dmax'].loc['2015'].values, label = 'dmax 2015')
ax.plot(data_sic_mes['dmax'].loc['2016'].values, label = 'dmax 2016')
ax.plot(data_sic_mes['dmax'].loc['2017'].values, label = 'dmax 2017')
plt.title('Últimos 3 años demanda máxima SIC', fontsize = 16)
plt.xlabel('Mes', fontsize = 16)
plt.ylabel('MW', fontsize = 16)
plt.legend(loc = 'lower right', fontsize = 11)
plt.show()
print(seasonal_decompose(data_sic_mes['dmin']).plot())
print(seasonal_decompose(data_sic_mes['dmax']).plot())
data_sing
# Comenzamos por ver la demanda mínima del SING
plt.figure(figsize=(10,5))
plt.plot(data_sing['dmin'], c='b', label = 'SING')
plt.title('Demanda mínima diaria SING', fontsize = 20)
plt.xlabel('años', fontsize = 18)
plt.ylabel('MW', fontsize = 18)
plt.legend(loc = 'lower right', fontsize = 14)
plt.show()
data_sing_mes = data_sing.resample('M').sum()
data_sing_mes
plt.figure(figsize=(10,5))
plt.plot(data_sing_mes['dmin'], c='r', label = 'dmin')
plt.plot(data_sing_mes['dmax'], c = 'g', label = 'dmax')
plt.title('Demanda mensual SING', fontsize = 20)
plt.xlabel('años', fontsize = 18)
plt.ylabel('MW', fontsize = 18)
plt.legend(loc = 'lower right', fontsize = 11)
plt.show()
fig = plt.figure(figsize=(10,10))
ax = plt.subplot(2,1,1)
ax.plot(data_sing_mes['dmin'].loc['2015'].values, label = 'dmin 2015')
ax.plot(data_sing_mes['dmin'].loc['2016'].values, label = 'dmin 2016')
ax.plot(data_sing_mes['dmin'].loc['2017'].values, label = 'dmin 2017')
plt.title('Últimos 3 años demanda mínima SING', fontsize = 18)
plt.ylabel('MW', fontsize = 16)
plt.legend(loc = 'lower right', fontsize = 11)
ax = plt.subplot(2,1,2)
ax.plot(data_sing_mes['dmax'].loc['2015'].values, label = 'dmax 2015')
ax.plot(data_sing_mes['dmax'].loc['2016'].values, label = 'dmax 2016')
ax.plot(data_sing_mes['dmax'].loc['2017'].values, label = 'dmax 2017')
plt.title('Últimos 3 años demanda máxima SING', fontsize = 16)
plt.xlabel('Mes', fontsize = 16)
plt.ylabel('MW', fontsize = 16)
plt.legend(loc = 'lower right', fontsize = 11)
plt.show()
print(seasonal_decompose(data_sing_mes['dmin']).plot())
print(seasonal_decompose(data_sing_mes['dmax']).plot())
data_sen
# Graficaremos la data para poder visualizar su comportamiento (dmin)
plt.figure(figsize=(10,5))
plt.plot(data_sen['dmin'], c='b', label = 'SEN')
plt.title('Demanda mínima diaria SEN', fontsize = 20)
plt.xlabel('años', fontsize = 18)
plt.ylabel('MW', fontsize = 18)
plt.legend(loc = 'lower right', fontsize = 14)
plt.show()
data_sen_mes = data_sen.resample('M').sum()
data_sen_mes.head() # Mostramos los primeros 5 meses de SEN
plt.figure(figsize=(10,5))
plt.plot(data_sen_mes['dmin'], c='r', label = 'dmin')
plt.plot(data_sen_mes['dmax'], c = 'g', label = 'dmax')
plt.title('Demanda mínima mensual SEN', fontsize = 20)
plt.xlabel('años', fontsize = 18)
plt.ylabel('MW', fontsize = 18)
plt.legend(loc = 'lower right', fontsize = 11)
plt.show()
fig = plt.figure(figsize=(10,10))
ax = plt.subplot(2,1,1)
ax.plot(data_sen_mes['dmin'].loc['2018'].values, label = 'dmin 2018')
ax.plot(data_sen_mes['dmin'].loc['2019'].values, label = 'dmin 2019')
ax.plot(data_sen_mes['dmin'].loc['2020'].values, label = 'dmin 2020')
plt.title('Últimos 3 años demanda mínima SEN', fontsize = 18)
plt.ylabel('MW', fontsize = 16)
plt.legend(loc = 'lower right', fontsize = 9)
ax = plt.subplot(2,1,2)
ax.plot(data_sen_mes['dmax'].loc['2018'].values, label = 'dmax 2018')
ax.plot(data_sen_mes['dmax'].loc['2019'].values, label = 'dmax 2019')
ax.plot(data_sen_mes['dmax'].loc['2020'].values, label = 'dmax 2020')
plt.title('Últimos 3 años demanda máxima SEN', fontsize = 16)
plt.xlabel('Mes', fontsize = 16)
plt.ylabel('MW', fontsize = 16)
plt.legend(loc = 'lower right', fontsize = 9)
plt.show()
print(seasonal_decompose(data_sen_mes['dmin']).plot())
print(seasonal_decompose(data_sen_mes['dmax']).plot())
## FUNCIONES PARA EL AJUSTE
# Con esta función obtendremos información numérica del dataset
def info_data(data, dmand:str):
rango = round((data[dmand].max() - data[dmand].min()),2)
min = data[dmand].min()
Q1 = data[dmand].quantile(q=0.25)
Q2 = data[dmand].quantile(q=0.50)
Q3 = data[dmand].quantile(q=0.75)
max = data[dmand].max()
iqr = round((Q3 - Q1),2)
count = data[dmand].count()
mean = round(data[dmand].mean(),2)
std = round(data[dmand].std(),2)
print(f'Count: {count}\nMinimo: {min}\nMaximo: {max}\nRango: {rango}')
print(f'Q1: {Q1}\nQ2: {Q2}\nQ3: {Q3}\nIQR: {iqr}\nMean: {mean}\nStd: {std}')
# En esta función ajustamos la data dado el rango intercuartil de esta, presentando además una tabla de los
# datos outliers que fueron reemplazados por una media movil de 3 periodos anteriores.
def ajust_media_movil(data, dmand:str):
Q1 = data[dmand].quantile(q=0.25)
Q3 = data[dmand].quantile(q=0.75)
iqr = Q3 - Q1 # Rango intercuartil (IQR)
new_min = round(Q1 - 1.5*iqr,2) # limite inferir -> Q1 - 1.5IQR
new_max = round(Q3 + 1.5*iqr,2) # limite superior -> Q3 + 1.5IQR
# Aquí quitamos la fecha de indice y la pasamos a columna, reseteando el indice a numeros.
data_ajust = data[[dmand]].rename_axis('fecha').reset_index()
lista = []
for index, valor in enumerate(data_ajust[dmand]):
if (valor < new_min) or (valor > new_max):
new_valor = round((data_ajust[[dmand]].loc[index-1][0]+data_ajust[[dmand]].loc[index-2][0]+data_ajust[[dmand]].loc[index-3][0])/3,2)
lista.append([data_ajust['fecha'].loc[index], valor, new_valor])
data_ajust[dmand][index] = new_valor
changes = pd.DataFrame(lista, columns=['fecha','outlier','new_valor'])
data_ajust = data_ajust.set_index('fecha')
return data_ajust, changes
def graph_new_distribution(data_ajust, data, dmand:str):
limit = (0,6000)
if dmand == 'dmin':
limit = (0,9000)
else:
limit = (6000,11500)
figura = plt.figure(figsize=(20,10))
ax = plt.subplot(1,2,1)
ax.plot(data[[dmand]])
plt.xlabel('Fecha', fontsize = 15)
plt.ylabel('Distribución Original', fontsize =15)
plt.ylim(limit)
ax = plt.subplot(1,2,2)
plt.xlabel('Fecha', fontsize = 15)
plt.ylabel('Distribución Ajustada', fontsize = 15)
ax.plot(data_ajust)
plt.ylim(limit)
plt.show()
## FUNCIONES PARA PODER APLICAR LOS MODELOS
# La función encargada de transformar nuestra Serie Temporal en un problema de tipo supervisado.
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
# Función encargada de normalizar y transformar los datos a aprendizaje supervisado
def normalize_and_supervised(pronostic_mes):
values = pronostic_mes.values
values = values.astype('float32')
# normalize features
values=values.reshape(-1, 1) # esto lo hacemos porque tenemos 1 sola dimension
scaled = SCALER.fit_transform(values)
transform_data = series_to_supervised(scaled, PAST_HISTORY,PREDICTION)
return transform_data
# Función encargada de gráficar el proceso de entrenamiento del modelo
def plot_history(history):
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
fig = plt.figure(figsize=(20,5))
ax = plt.subplot(1,2,1)
plt.ylabel('Loss - Mean Squared Error')
ax.plot(hist['epoch'], hist['loss'], label= 'Train loss')
ax.plot(hist['epoch'], hist['val_loss'], label='Validation loss')
#plt.ylim(0.03,0.08)
plt.legend()
ax = plt.subplot(1,2,2)
plt.ylabel('Mean Absolute Error')
ax.plot(hist['epoch'], hist['mae'], label= 'Train Error')
ax.plot(hist['epoch'], hist['val_mae'], label='Validation Error')
#plt.ylim(0.0,0.025)
plt.legend()
plt.show()
# Función encargada de gráficar las predicciónes del modelo
def graph_prediction(index, test, predict):
fig = plt.figure(figsize=(15,10))
ax = plt.subplot(1,1,1)
ax.plot(index ,test, c='b', label='Datos_test')
ax.plot(index ,predict, '.-r', label='Predicción')
plt.ylabel('MW', fontsize = 16)
plt.xlabel('Fecha', fontsize = 16)
plt.xticks(rotation=35, fontsize=14)
plt.yticks(fontsize=14)
ax.legend()
plt.show()
############## CONFIGURACIÓN GENERAL DE LOS MODELOS ########################################################
# Seleccionamos el rango para el aprendizaje supervisado ( t-n, t-(n-1), ... , t-2, t-1, t)
PAST_HISTORY = 30
PREDICTION = 1
# Generando el escalador de los datos.
SCALER = MinMaxScaler(feature_range=(0,1))
# Como se entrenara el modelo
LOSS ='mean_squared_error'
OPTIMIZER_1 = Adam(learning_rate=0.0003)
OPTIMIZER_2 = RMSprop(learning_rate=0.0003) # un segundo optimizador para hacer pruebas
METRICS = ["mae"]
############# CONFIGURACIÓN MODELO ################################################################
# Función de activación
ACTIVATION = 'relu'
# Seleccionamos la cantidad de repeticiones que se entrenará (cantidad de EPOCH)
EPOCHS_1 = 40
EPOCHS_2 = 10
BATCH_SIZE = 32
plt.figure(figsize=(10,5))
plt.plot(data_sen[['dmin']])
plt.title('Demanda mínima diaria SEN', fontsize=14)
plt.ylabel('MW', fontsize = 14)
plt.xlabel('Fecha', fontsize= 14)
plt.show()
# Vemos la distrubución de la demanda minima de SEN con un histograma
sns.histplot(data_sen['dmin'])
plt.show()
# Veremos un diagrama de caja para ver la mediana, los quartiles y datos outliers de SEN dmin
sns.boxplot(data_sen['dmin'])
plt.show()
# Veremos un poco de información de los datos (todos los valores estan en MW, menos Count)
info_data(data_sen, 'dmin')
tratamiento_sen_dmin = ajust_media_movil(data_sen, 'dmin')
sen_dmin_ajust = tratamiento_sen_dmin[0]
changes_sen_dmin = tratamiento_sen_dmin[1]
# Veremos los datos outliers con su correspondiente fecha y el valor por el que fueron reemplazados
changes_sen_dmin
# Vemos la distribución de los datos de SEN dmin ajustados
sns.histplot(sen_dmin_ajust['dmin'])
plt.show()
# Podemos ver el gráfico de caja sin datos outliers.
sns.boxplot(sen_dmin_ajust['dmin'])
plt.show()
# Vemos un cambio en la información con los datos ajustados.
info_data(sen_dmin_ajust,'dmin')
# Hacemos una comparación de los datos antes (izquierda) y despues del ajuste intercuartil (derecha)
graph_new_distribution(sen_dmin_ajust, data_sen,'dmin')
plt.figure(figsize=(10,5))
plt.plot(data_sen[['dmax']])
plt.title('Demanda máxima diaria SEN', fontsize=14)
plt.ylabel('MW', fontsize = 14)
plt.xlabel('Fecha', fontsize= 14)
plt.show()
# Vemos la distribución de los datos de SEN dmax con un histograma
sns.histplot(data_sen['dmax'])
plt.show()
# Veremos un diagrama de caja para ver la mediana, los cuartiles y datos outliers de SEN dmax
sns.boxplot(data_sen['dmax'])
plt.show()
# Veremos un poco de información de los datos (todos los valores estan en MW, menos Count)
info_data(data_sen, 'dmax')
# Se realiza el ajuste de los datos y se rescata el df con los datos outliers y sus nuevos valores.
tratamiento_sen_dmax = ajust_media_movil(data_sen, 'dmax')
sen_dmax_ajust = tratamiento_sen_dmax[0]
changes_sen_dmax = tratamiento_sen_dmax[1]
# Veremos los datos outliers con su correspondiente fecha y el valor por el que fueron reemplazados
changes_sen_dmax
# Vemos la distribución de los datos ajustados
sns.histplot(sen_dmax_ajust['dmax'])
plt.show()
# Vemos el gráfico de caja sin datos outliers.
sns.boxplot(sen_dmax_ajust['dmax'])
plt.show()
# Vemos un cambio en la información con los datos ajustados.
info_data(sen_dmax_ajust,'dmax')
# Hacemos una comparación de los datos antes (izquierda) y despues del ajuste intercuartil (derecha)
graph_new_distribution(sen_dmax_ajust, data_sen,'dmax')
# Seleccionamos el rango de fecha en el que miraremos hacia atras para predecir
end_train_sen = '2021-07'
start_test_sen = '2021-08'
# Separando los datos de SIC
sen_train_dmin, sen_test_dmin = sen_dmin_ajust.loc[:end_train_sen], sen_dmin_ajust.loc[start_test_sen:]
sen_train_dmax, sen_test_dmax = sen_dmax_ajust.loc[:end_train_sen], sen_dmax_ajust.loc[start_test_sen:]
#################### OBTENIENDO MÁS INTERVALOS DE PRUEBA #####################################################
# PARA SEN DMIN
sen_test_dmin_aug = sen_dmin_ajust.loc['2021-07':'2021-08'] # Agosto
sen_test_dmin_as = sen_dmin_ajust.loc['2021-07':] # Agosto y septiembre
# PARA SEN DMAX
sen_test_dmax_aug = sen_dmax_ajust.loc['2021-07':'2021-08']
sen_test_dmax_as = sen_dmax_ajust.loc['2021-07':]
##############################################################################################################
print(f'SEN\nDatos Train: {sen_train_dmin.shape}\nDatos Test: {sen_test_dmin.shape}')
transform_sen_train_dmax = normalize_and_supervised(sen_train_dmax)
transform_sen_train_dmax.shape
# x_train e y_train de sen dmax
x_train_sen_dmax = transform_sen_train_dmax.iloc[:,:-1]
y_train_sen_dmax = transform_sen_train_dmax.iloc[:,-1]
# Vemos las dimensiones de los datos de entrenamiento
x_train_sen_dmax.shape, y_train_sen_dmax.shape
def model_MLP_sen():
model = Sequential()
model.add(Dense(64, input_dim = x_train_sen_dmax.shape[1], activation = ACTIVATION))
model.add(Dense(128, activation=ACTIVATION))
model.add(Dense(PREDICTION, activation=ACTIVATION))
model.compile(loss= LOSS,
optimizer= OPTIMIZER_1,
metrics= METRICS)
return model
model_sen_dmax_mlp = model_MLP_sen()
# Mostramos la estructura del modelo para la dmax
model_sen_dmax_mlp.summary()
# Entrenamos el modelo de dmax
history_sen_dmax_mlp = model_sen_dmax_mlp.fit(x_train_sen_dmax, y_train_sen_dmax,
epochs=EPOCHS_1,
batch_size = BATCH_SIZE,
validation_split=0.1,
shuffle= False,
verbose = 0)
hist_sen_dmax_mlp = pd.DataFrame(history_sen_dmax_mlp.history)
hist_sen_dmax_mlp['epoch'] = history_sen_dmax_mlp.epoch
# Mostramos las últimas 5 filas del total de epoch de entrenamiento
hist_sen_dmax_mlp.tail()
# Redimensionando los datos de x_train para el modelo LSTM
x_train_sen_dmax = x_train_sen_dmax.values.reshape((x_train_sen_dmax.shape[0], x_train_sen_dmax.shape[1],1))
x_train_sen_dmax.shape
def model_LSTM_sen():
model = Sequential()
model.add(LSTM(60, input_shape = (x_train_sen_dmax.shape[1],x_train_sen_dmax.shape[2]), return_sequences=True))
model.add(LSTM(60, return_sequences=True))
model.add(Flatten())
model.add(Dense(PREDICTION))
model.compile(loss= LOSS,
optimizer= OPTIMIZER_1,
metrics= METRICS)
return model
model_sen_dmax_lstm = model_LSTM_sen()
# Mostramos la estructura del modelo para la dmax
model_sen_dmax_lstm.summary()
# Entrenamos el modelo de dmax
history_sen_dmax_lstm = model_sen_dmax_lstm.fit(x_train_sen_dmax, y_train_sen_dmax,
epochs=70,
batch_size = BATCH_SIZE,
validation_split = 0.1,
shuffle= False,
verbose = 0)
hist_sen_dmax_lstm = pd.DataFrame(history_sen_dmax_lstm.history)
hist_sen_dmax_lstm['epoch'] = history_sen_dmax_lstm.epoch
# Mostramos las ultimas 5 filas del total de epoch de entrenamiento
hist_sen_dmax_lstm.tail()
x_train_sen_dmax.shape, y_train_sen_dmax.shape
def model_GRU():
model = Sequential()
model.add(GRU(64, input_shape = (x_train_sen_dmax.shape[1],x_train_sen_dmax.shape[2]), return_sequences=True))
model.add(GRU(64, return_sequences = True))
model.add(Flatten())
model.add(Dense(PREDICTION))
model.compile(loss= LOSS,
optimizer= OPTIMIZER_1,
metrics= METRICS)
return model
model_sen_dmax_gru = model_GRU()
# Mostramos la estructura del modelo para la dmax
model_sen_dmax_gru.summary()
# Entrenamos el modelo de dmax
history_sen_dmax_gru = model_sen_dmax_gru.fit(x_train_sen_dmax, y_train_sen_dmax,
epochs= 60,
batch_size = BATCH_SIZE,
validation_split = 0.1,
shuffle= False,
verbose = 0)
hist_sen_dmax_gru = pd.DataFrame(history_sen_dmax_gru.history)
hist_sen_dmax_gru['epoch'] = history_sen_dmax_gru.epoch
# Mostramos las ultimas 5 filas del total de epoch de entrenamiento
hist_sen_dmax_gru.tail()
x_train_sen_dmax.shape, y_train_sen_dmax.shape
def model_hibrido():
model = Sequential()
model.add(Conv1D(32,8, input_shape = (x_train_sen_dmax.shape[1],x_train_sen_dmax.shape[2]),activation='relu',padding='same'))
model.add(MaxPool1D())
model.add(Conv1D(32,8, activation=ACTIVATION, padding='same'))
model.add(MaxPool1D())
model.add(LSTM(32, return_sequences=True))
model.add(Flatten())
model.add(Dense(PREDICTION))
model.compile(loss= LOSS,
optimizer= OPTIMIZER_1,
metrics= METRICS)
return model
model_sen_dmax_hibrido = model_hibrido()
# Mostramos la estructura del modelo para la dmax
model_sen_dmax_hibrido.summary()
# Entrenamos el modelo de dmax
history_sen_dmax_hibrido = model_sen_dmax_hibrido.fit(x_train_sen_dmax, y_train_sen_dmax,
epochs= 40,
batch_size = BATCH_SIZE,
validation_split = 0.1,
shuffle= False,
verbose = 0)
hist_sen_dmax_hibrido = pd.DataFrame(history_sen_dmax_hibrido.history)
hist_sen_dmax_hibrido['epoch'] = history_sen_dmax_hibrido.epoch
# Mostramos las ultimas 5 filas del total de epoch de entrenamiento
hist_sen_dmax_hibrido.tail()
x_train_sen_dmax.shape, y_train_sen_dmax.shape
def model_hibrido2():
model = Sequential()
model.add(Conv1D(32,9, input_shape = (x_train_sen_dmax.shape[1],x_train_sen_dmax.shape[2]),activation='relu',padding='same'))
model.add(MaxPool1D())
model.add(Conv1D(32,9, activation=ACTIVATION, padding='same'))
model.add(MaxPool1D())
model.add(GRU(32, return_sequences=True))
model.add(Flatten())
model.add(Dense(PREDICTION))
model.compile(loss= LOSS,
optimizer= OPTIMIZER_1,
metrics= METRICS)
return model
model_sen_dmax_hibrido2 = model_hibrido2()
# Mostramos la estructura del modelo para la dmax
model_sen_dmax_hibrido2.summary()
# Entrenamos el modelo de dmax
history_sen_dmax_hibrido2 = model_sen_dmax_hibrido2.fit(x_train_sen_dmax, y_train_sen_dmax,
epochs= 40,
batch_size = BATCH_SIZE,
validation_split = 0.1,
shuffle= False,
verbose = 0)
hist_sen_dmax_hibrido2 = pd.DataFrame(history_sen_dmax_hibrido2.history)
hist_sen_dmax_hibrido2['epoch'] = history_sen_dmax_hibrido2.epoch
# Mostramos las ultimas 5 filas del total de epoch de entrenamiento
hist_sen_dmax_hibrido2.tail()
# Transformando a aprendizaje supervisado y normalizando los datos de prueba (test) de SEN
transform_test_sen_dmax_as = normalize_and_supervised(sen_test_dmax_as) # Agosto y Septiembre
# Datos de x_test e y_test de SEN dmin
# Agosto y Septiembre
x_test_sen_dmax_as = transform_test_sen_dmax_as.iloc[:,:-1]
y_test_sen_dmax_as = transform_test_sen_dmax_as.iloc[:,-1]
# Evaluando el modelo con los datos de prueba
evaluate_model_sen_dmax_mlp_as = model_sen_dmax_mlp.evaluate(x_test_sen_dmax_as, y_test_sen_dmax_as)
predict_model_sen_dmax_mlp_as = model_sen_dmax_mlp.predict(x_test_sen_dmax_as)
# Calculando el error de la predicción
results_predict_model_sen_dmax_mlp_as = [round(float(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_mlp_as)),6),
round(float(mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_mlp_as)),6),
round(float(math.sqrt(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_mlp_as))),6),
round(float((mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_mlp_as))*100),6)]
print(f'mse: {results_predict_model_sen_dmax_mlp_as[0]}\nmae: {results_predict_model_sen_dmax_mlp_as[1]}')
print(f'rmse: {results_predict_model_sen_dmax_mlp_as[2]}\nmape: {results_predict_model_sen_dmax_mlp_as[3]}')
index_as = sen_test_dmax_as.iloc[30:].index
# Escalamos la predicción a su escala original
predict_model_sen_dmax_mlp_as = SCALER.inverse_transform(predict_model_sen_dmax_mlp_as)
# Redimensionando los datos de x_test de SEN dmin
x_test_sen_dmax_as = x_test_sen_dmax_as.values.reshape((x_test_sen_dmax_as.shape[0], x_test_sen_dmax_as.shape[1],1))
# Evaluando el modelo con los datos de prueba
evaluate_model_sen_dmax_lstm_as = model_sen_dmax_lstm.evaluate(x_test_sen_dmax_as, y_test_sen_dmax_as)
predict_model_sen_dmax_lstm_as = model_sen_dmax_lstm.predict(x_test_sen_dmax_as)
# Calculando el error de la predicción
results_predict_model_sen_dmax_lstm_as = [round(float(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_lstm_as)),6),
round(float(mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_lstm_as)),6),
round(float(math.sqrt(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_lstm_as))),6),
round(float((mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_lstm_as))*100),6)]
print(f'mse: {results_predict_model_sen_dmax_lstm_as[0]}\nmae: {results_predict_model_sen_dmax_lstm_as[1]}')
print(f'rmse: {results_predict_model_sen_dmax_lstm_as[2]}\nmape: {results_predict_model_sen_dmax_lstm_as[3]}')
# Escalamos la predicción a su escala original
predict_model_sen_dmax_lstm_as = SCALER.inverse_transform(predict_model_sen_dmax_lstm_as)
# Evaluando el modelo con los datos de prueba
evaluate_model_sen_dmax_gru_as = model_sen_dmax_gru.evaluate(x_test_sen_dmax_as, y_test_sen_dmax_as)
predict_model_sen_dmax_gru_as = model_sen_dmax_gru.predict(x_test_sen_dmax_as)
# Calculando el error de la predicción
results_predict_model_sen_dmax_gru_as = [round(float(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_gru_as)),6),
round(float(mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_gru_as)),6),
round(float(math.sqrt(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_gru_as))),6),
round(float((mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_gru_as))*100),6)]
print(f'mse: {results_predict_model_sen_dmax_gru_as[0]}\nmae: {results_predict_model_sen_dmax_gru_as[1]}')
print(f'rmse: {results_predict_model_sen_dmax_gru_as[2]}\nmape: {results_predict_model_sen_dmax_gru_as[3]}')
# Escalamos la predicción a su escala original
predict_model_sen_dmax_gru_as = SCALER.inverse_transform(predict_model_sen_dmax_gru_as)
# Evaluando el modelo con los datos de prueba
evaluate_model_sen_dmax_hibrido_as = model_sen_dmax_hibrido.evaluate(x_test_sen_dmax_as, y_test_sen_dmax_as)
predict_model_sen_dmax_hibrido_as = model_sen_dmax_hibrido.predict(x_test_sen_dmax_as)
# Calculando el error de la predicción
results_predict_model_sen_dmax_hibrido_as = [round(float(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido_as)),6),
round(float(mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido_as)),6),
round(float(math.sqrt(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido_as))),6),
round(float((mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido_as))*100),6)]
print(f'mse: {results_predict_model_sen_dmax_hibrido_as[0]}\nmae: {results_predict_model_sen_dmax_hibrido_as[1]}')
print(f'rmse: {results_predict_model_sen_dmax_hibrido_as[2]}\nmape: {results_predict_model_sen_dmax_hibrido_as[3]}')
# Escalamos la predicción a su escala original
predict_model_sen_dmax_hibrido_as = SCALER.inverse_transform(predict_model_sen_dmax_hibrido_as)
# Evaluando el modelo con los datos de prueba
evaluate_model_sen_dmax_hibrido2_as = model_sen_dmax_hibrido2.evaluate(x_test_sen_dmax_as, y_test_sen_dmax_as)
predict_model_sen_dmax_hibrido2_as = model_sen_dmax_hibrido2.predict(x_test_sen_dmax_as)
# Calculando el error de la predicción
results_predict_model_sen_dmax_hibrido2_as = [round(float(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido2_as)),6),
round(float(mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido2_as)),6),
round(float(math.sqrt(mean_squared_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido2_as))),6),
round(float((mean_absolute_error(y_test_sen_dmax_as, predict_model_sen_dmax_hibrido2_as))*100),6)]
print(f'mse: {results_predict_model_sen_dmax_hibrido2_as[0]}\nmae: {results_predict_model_sen_dmax_hibrido2_as[1]}')
print(f'rmse: {results_predict_model_sen_dmax_hibrido2_as[2]}\nmape: {results_predict_model_sen_dmax_hibrido2_as[3]}')
# Escalamos la predicción a su escala original
predict_model_sen_dmax_hibrido2_as = SCALER.inverse_transform(predict_model_sen_dmax_hibrido2_as)
# Creamos un df con los resultados del entrenamiento de los modelos
results_train = pd.concat([hist_sen_dmax_mlp.tail(1).iloc[:,:-1],
hist_sen_dmax_lstm.tail(1).iloc[:,:-1],
hist_sen_dmax_gru.tail(1).iloc[:,:-1],
hist_sen_dmax_hibrido.tail(1).iloc[:,:-1],
hist_sen_dmax_hibrido2.tail(1).iloc[:,:-1]],ignore_index=True)
# Renombramos el nombre de los indices y columnas para una mejor comprensión
results_train.rename(index = {0:'MLP',
1:'LSTM',
2:'GRU',
3:'HYBRID_1',
4:'HYBRID_2'},
columns = {'loss':'MSE_TRAIN',
'mae':'MAE_TRAIN',
'val_loss':'MSE_VAL',
'val_mae':'MAE_VAL'},
inplace = True)
# Creamos un df con los resultados de las predicciones de los modelos
results_predicts = [results_predict_model_sen_dmax_mlp_as,
results_predict_model_sen_dmax_lstm_as,
results_predict_model_sen_dmax_gru_as,
results_predict_model_sen_dmax_hibrido_as,
results_predict_model_sen_dmax_hibrido2_as]
# Le asignamos indices y columnas
results_predicts = pd.DataFrame(results_predicts, index = ['MLP','LSTM','GRU','HYBRID_1','HYBRID_2'],
columns=['MSE_PREDICT','MAE_PREDICT','RMSE_PREDICT','MAPE_PREDICT'])
# Concatenaremos los df
df_results = pd.concat([results_train, results_predicts], axis = 1)
df_results
# Ordenando los resultados de menor a mayor por MSE_PREDICT
df_results.sort_values('MSE_PREDICT')
# Ordenando los resultados de menor a mayor por MAE_PREDICT
df_results.sort_values('MAE_PREDICT')