Skip to content

Instantly share code, notes, and snippets.

@johnfelipe
Created September 4, 2024 02:29
Show Gist options
  • Save johnfelipe/f6d5083629d383fab733d2d22b37c385 to your computer and use it in GitHub Desktop.
Save johnfelipe/f6d5083629d383fab733d2d22b37c385 to your computer and use it in GitHub Desktop.

Explicación del Notebook: Predicción de Consumo de Energía con RNN-GRU

Este notebook presenta un prototipo de modelo de aprendizaje automático para predecir patrones de consumo de energía utilizando una Red Neuronal Recurrente (RNN) con una Unidad Recurrente Cerrada (GRU). El modelo se entrena con una serie temporal singular de datos de consumo energético durante 15 meses y luego predice los siguientes 12 meses.

A continuación, se describe el notebook paso a paso:

1. Importación de Librerías:

import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
%matplotlib inline
  • Se importan las librerías necesarias para el análisis de datos, el aprendizaje automático y la visualización.
  • numpy se utiliza para operaciones numéricas.
  • pandas se utiliza para la manipulación y análisis de datos.
  • tensorflow se utiliza para construir y entrenar el modelo RNN-GRU.
  • matplotlib.pyplot se utiliza para la visualización de datos.
  • MinMaxScaler de sklearn.preprocessing se utiliza para escalar los datos a un rango específico.

2. Carga y Preparación de Datos:

# import data and set DateTime column as index
energy_data_frame = pd.read_csv('./data/Power-Networks-LCL-June2015(withAcornGps)v2_1.csv', index_col='DateTime')

# set index for timeseries
energy_data_frame.index = pd.to_datetime(energy_data_frame.index)

# remove unused columns
energy_data_frame = energy_data_frame.drop(['stdorToU', 'Acorn', 'Acorn_grouped'], axis=1)

# convert consumption data to numeric and append as consumption
energy_data_frame['consumption'] = pd.to_numeric(energy_data_frame['KWH/hh (per half hour) '], errors='coerce')

# remove old consumption data
energy_data_frame = energy_data_frame.drop(['KWH/hh (per half hour) '], axis=1)

# rotate to make each id into a series
energy_data_frame = energy_data_frame.pivot_table(values='consumption', index=['DateTime'], columns=['LCLid'] )

# convert to monthly sum
energy_data_frame = energy_data_frame.resample('m').sum()

# a view of the head
pd.set_option('display.max_columns', 36)
energy_data_frame.head()
  • Se carga el conjunto de datos de consumo energético desde un archivo CSV.
  • Se establece la columna 'DateTime' como índice y se convierte a formato de fecha y hora.
  • Se eliminan las columnas irrelevantes para el modelo.
  • Se convierte la columna de consumo a tipo numérico y se renombra como 'consumption'.
  • Se pivotea el DataFrame para tener cada 'LCLid' (identificador de cliente) como una serie temporal.
  • Se remuestrea el DataFrame para obtener la suma mensual de consumo.

3. Selección de un LCLid y División de Datos:

# retrict data set to a single LCLid
energy_data_id34 = pd.DataFrame(index=energy_data_frame.index, columns=['MAC000034'])

# create data frame from single id
energy_data_id34['MAC000034']  = energy_data_frame['MAC000034']

# training and test set
training_set = energy_data_id34.head(15)
test_set = energy_data_id34.tail(12)
  • Se selecciona un único LCLid ('MAC000034') para este ejemplo.
  • Se divide el conjunto de datos en un conjunto de entrenamiento (15 meses) y un conjunto de prueba (12 meses).

4. Escalado de Datos:

# scale data, fit is only performed on the training data
train_scaled = scaler.fit_transform(training_set)
test_scaled = scaler.transform(test_set)
  • Se escala el conjunto de entrenamiento utilizando MinMaxScaler para que los valores estén en un rango de 0 a 1.
  • Se aplica la misma transformación de escalado al conjunto de prueba utilizando los parámetros aprendidos del conjunto de entrenamiento.

5. Definición del Modelo RNN-GRU:

# set hyper parameters
num_inputs = 1
num_time_steps = 6
num_neurons = 300
num_pred = 2
num_outputs = 1
learning_rate = 0.02
num_train_iterations = 10000
batch_size = 1

# Definir el modelo usando la API de Keras
model = tf.keras.Sequential([
    tf.keras.layers.GRU(num_neurons,
                        activation='relu',
                        return_sequences=True,
                        input_shape=[num_time_steps, num_inputs]),
    tf.keras.layers.Dense(num_outputs)
])

# Compilar el modelo
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
model.compile(optimizer=optimizer, loss='mse')
  • Se definen los hiperparámetros del modelo, como el número de neuronas, la tasa de aprendizaje y el tamaño del lote.
  • Se crea un modelo secuencial utilizando la API de Keras con una capa GRU y una capa Dense.
  • Se compila el modelo con el optimizador Adam y la función de pérdida de error cuadrático medio (MSE).

6. Entrenamiento del Modelo:

# Cargar y preparar los datos
# Asumiendo que energy_data_id34 es tu DataFrame
scaler = MinMaxScaler()
train_scaled = scaler.fit_transform(energy_data_id34.values)

'''
# Entrenar el modelo (descomenta esto si necesitas reentrenar)

for iteration in range(num_train_iterations):
    X_batch, y_batch = next_batch(train_scaled, batch_size, num_time_steps)
    loss = model.train_on_batch(X_batch, y_batch)

    if iteration % 1000 == 0:
        print(f"Iteración {iteration}, Pérdida: {loss}")

# Guardar el modelo
model.save('./energy_consumption_model')
'''
  • Se entrena el modelo con el conjunto de entrenamiento escalado utilizando el método train_on_batch.
  • Se imprime la pérdida cada 1000 iteraciones.
  • Se guarda el modelo entrenado en un archivo.

7. Carga del Modelo y Predicción:

# Cargar el modelo guardado
model = tf.keras.models.load_model('./energy_consumption_model.keras')

# Assuming energy_data_id34 is your DataFrame
scaler = MinMaxScaler()
train_scaled = scaler.fit_transform(energy_data_id34.values)

# Assuming you have already defined and trained your model
# model = ...

# Prepare the data for prediction
train_seed = list(train_scaled.flatten())  # Flatten the array to ensure 1D
num_time_steps = 6  # Adjust this based on your model's input shape

results = []

for _ in range(len(test_set)):
    # Ensure we have at least num_time_steps elements
    if len(train_seed) < num_time_steps:
        break

    # Convert the last num_time_steps elements to a numpy array
    X_batch = np.array(train_seed[-num_time_steps:], dtype=np.float32).reshape(1, num_time_steps, 1)

    y_pred = model.predict(X_batch)
    pred_value = y_pred[0, -1, 0]  # Extract the predicted value

    train_seed.append(pred_value)
    results.append(pred_value)

# Convert results to a numpy array
results = np.array(results).reshape(-1, 1)

# Inverse transform the results
results = scaler.inverse_transform(results)

# Create a copy of test_set to avoid the SettingWithCopyWarning
test_set_copy = test_set.copy()

# Add the predictions to the copy
test_set_copy['Predicted'] = results

# If you need to update the original test_set, you can do:
# test_set = test_set_copy

# Make sure test_set is a copy to avoid SettingWithCopyWarning
test_set = test_set.copy()

# Add the 'Predicted' column to test_set
test_set['Predicted'] = results

# Now let's plot
fig = plt.figure(figsize=(16, 6))
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8])

# Plot actual values
axes.plot(energy_data_id34.index, energy_data_id34['MAC000034'], label='Actual')

# Plot predicted values
axes.plot(test_set.index, test_set['Predicted'], label='Predicted')

axes.legend()
axes.set_xlabel('Date')
axes.set_ylabel('Energy Consumption')
axes.set_title('Actual vs Predicted Energy Consumption')

plt.show()
  • Se carga el modelo entrenado desde el archivo.
  • Se genera una secuencia de predicciones para el conjunto de prueba utilizando el modelo.
  • Se invierte la transformación de escalado para obtener las predicciones en la escala original.
  • Se grafican las predicciones junto con los valores reales para visualizar el rendimiento del modelo.

Aplicaciones para el GRUPO VANTI Colombia

Este modelo de predicción de consumo de energía puede ser muy útil para el GRUPO VANTI Colombia en diversas áreas:

  • Planificación de la Demanda: Predecir la demanda futura de energía permite a VANTI optimizar la generación, distribución y compra de energía, evitando sobrecostos y asegurando un suministro estable.
  • Gestión de Recursos: Conocer los patrones de consumo ayuda a VANTI a gestionar mejor sus recursos, como personal, infraestructura y equipos, para responder eficientemente a la demanda.
  • Detección de Anomalías: El modelo puede identificar patrones inusuales de consumo, lo que podría indicar fugas, fraudes o problemas técnicos en la red.
  • Eficiencia Energética: Al comprender los patrones de consumo, VANTI puede ofrecer a sus clientes recomendaciones personalizadas para mejorar su eficiencia energética, lo que a su vez reduce el consumo total y los costos.
  • Tarifas Dinámicas: VANTI podría implementar tarifas dinámicas que varíen según la demanda predicha, incentivando el consumo en horas de baja demanda y reduciendo el estrés en la red durante las horas pico.

En resumen, este modelo de predicción de consumo de energía basado en RNN-GRU ofrece a VANTI una herramienta poderosa para la toma de decisiones estratégicas, la optimización de sus operaciones y la mejora de la calidad del servicio a sus clientes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment