La Eficiencia Energética se ha consolidado como un pilar fundamental en la estrategia de sostenibilidad y competitividad de la industria pesada. En plantas siderúrgicas, caracterizadas por un consumo intensivo de electricidad, la capacidad de predecir la demanda energética permite optimizar la contratación de potencia, reducir penalizaciones por picos de consumo y mejorar la huella de carbono (ISO 50001).
Este trabajo aborda la problemática de predecir el consumo de energía
activa (Usage_kWh) en una planta de acero ubicada en Corea
del Sur. A partir del análisis de datos históricos, se busca identificar
patrones de comportamiento y construir un modelo predictivo que permita
anticipar la demanda basándose en variables operativas como la potencia
reactiva y el tipo de carga.
(V E and Cho 2021)Se utiliza el conjunto de datos “Steel Industry Energy Consumption”, proveniente del repositorio oficial UCI Machine Learning Repository.
# Carga de bibliotecas
library(tidyverse)
library(lubridate)
library(randomForest)
library(corrplot) # Necesaria para replicar el Heatmap de la guía de Kaggle
library(reshape2) # Necesaria para manipulación de datos en gráficos
# Lectura y Limpieza del dataset
datos_brutos <- read.csv("Steel_industry_data.csv")
# Preprocesamiento
datos_procesados <- datos_brutos %>%
# Renombrar columnas para eliminar paréntesis y caracteres especiales
rename(
date = date,
usage_kwh = Usage_kWh,
lagging_reactive_kvarh = Lagging_Current_Reactive.Power_kVarh,
leading_reactive_kvarh = Leading_Current_Reactive_Power_kVarh,
co2_tco2 = CO2.tCO2.,
lagging_pf = Lagging_Current_Power_Factor,
leading_pf = Leading_Current_Power_Factor,
nsm = NSM,
week_status = WeekStatus,
day_of_week = Day_of_week,
load_type = Load_Type
) %>%
# Convertir fecha (string) a objeto fecha-hora
mutate(date = dmy_hm(date)) %>%
# Convertir variables categóricas en factores
mutate(
week_status = as.factor(week_status),
day_of_week = as.factor(day_of_week),
load_type = as.factor(load_type)
)
# Vista previa de la estructura de datos limpia
glimpse(datos_procesados)
## Rows: 35,040
## Columns: 11
## $ date <dttm> 2018-01-01 00:15:00, 2018-01-01 00:30:00, 2018…
## $ usage_kwh <dbl> 3.17, 4.00, 3.24, 3.31, 3.82, 3.28, 3.60, 3.60,…
## $ lagging_reactive_kvarh <dbl> 2.95, 4.46, 3.28, 3.56, 4.50, 3.56, 4.14, 4.28,…
## $ leading_reactive_kvarh <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ co2_tco2 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ lagging_pf <dbl> 73.21, 66.77, 70.28, 68.09, 64.72, 67.76, 65.62…
## $ leading_pf <dbl> 100, 100, 100, 100, 100, 100, 100, 100, 100, 10…
## $ nsm <int> 900, 1800, 2700, 3600, 4500, 5400, 6300, 7200, …
## $ week_status <fct> Weekday, Weekday, Weekday, Weekday, Weekday, We…
## $ day_of_week <fct> Monday, Monday, Monday, Monday, Monday, Monday,…
## $ load_type <fct> Light_Load, Light_Load, Light_Load, Light_Load,…
(Chowdhury 2025)Siguiendo las recomendaciones metodológicas y la guía de referencia proporcionada, se realiza un análisis exploratorio para comprender la estructura multivariante de los datos antes del modelado.
Este análisis replica la visualización de correlaciones para detectar colinealidad entre variables eléctricas.
# Seleccionar solo variables numéricas relevantes
datos_numericos <- datos_procesados %>%
select(usage_kwh, lagging_reactive_kvarh, leading_reactive_kvarh,
co2_tco2, lagging_pf, leading_pf, nsm)
# Calcular matriz de correlación
matriz_correlacion <- cor(datos_numericos)
# Graficar Heatmap (replicando la guía Python proporcionada)
corrplot(matriz_correlacion,
method = "color",
type = "upper",
order = "hclust",
addCoef.col = "black", # Muestra los coeficientes numéricos
tl.col = "black", # Color de etiquetas: negro
tl.srt = 45, # Rotación de etiquetas
diag = FALSE,
col = colorRampPalette(c("#6D9EC1", "white", "#E46726"))(200),
title = "Matriz de Correlación: Variables Operativas",
mar = c(0,0,2,0))
Interpretación: Se observa una correlación positiva
casi perfecta entre el Usage_kWh y las emisiones de
CO2, lo cual es esperable en generación térmica. Asimismo,
existe una fuerte correlación entre el consumo y la
Potencia Reactiva (Lagging), lo que sugiere que las cargas
inductivas (motores) son las principales consumidoras.
Análisis de la densidad de probabilidad del consumo según el tipo de carga operativa.
# Replicando gráfico de distribución (Distplot/KDE)
ggplot(datos_procesados, aes(x = usage_kwh, fill = load_type)) +
geom_density(alpha = 0.6) +
scale_fill_brewer(palette = "Set1") +
labs(title = "Distribución de Densidad del Consumo Energético",
subtitle = "Segmentación por Tipo de Carga (Load Type)",
x = "Consumo (kWh)",
y = "Densidad",
fill = "Estado de Carga") +
theme_minimal() +
theme(legend.position = "top")
Visualización de la dispersión del consumo según el día de la semana.
datos_procesados %>%
# Reordenar días para que aparezcan en orden lógico
mutate(day_of_week = factor(day_of_week,
levels = c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))) %>%
ggplot(aes(x = day_of_week, y = usage_kwh, fill = week_status)) +
geom_boxplot(outlier.alpha = 0.3, outlier.color = "red") +
scale_fill_manual(values = c("orange", "steelblue")) +
labs(title = "Perfil de Consumo Diario",
x = "Día de la Semana",
y = "Consumo (kWh)",
fill = "Estatus") +
theme_bw()
Para la predicción de la variable continua Usage_kWh, se
selecciona el método Random Forest (Regresión).
Justificación:
1. Robustez: Es capaz de capturar relaciones no lineales complejas entre las variables eléctricas (factor de potencia vs consumo).
2. Generalización: Al ser un método de ensamble (bagging), reduce el riesgo de sobreajuste comparado con un árbol de decisión simple.
3. Importancia de Variables: Permite cuantificar qué predictores tienen mayor peso en la demanda energética.
Se dividen los datos respetando la proporción 70% entrenamiento y 30% prueba.
set.seed(123) # Semilla para reproducibilidad
indices_entrenamiento <- sample(1:nrow(datos_procesados), 0.7 * nrow(datos_procesados))
datos_entrenamiento <- datos_procesados[indices_entrenamiento, ]
datos_prueba <- datos_procesados[-indices_entrenamiento, ]
cat("Datos de Entrenamiento:", nrow(datos_entrenamiento), "\n")
## Datos de Entrenamiento: 24528
cat("Datos de Prueba:", nrow(datos_prueba), "\n")
## Datos de Prueba: 10512
Se entrena el modelo excluyendo la variable date
(temporal) y usando todas las demás como predictores.
# Entrenamiento del modelo Random Forest
# ntree = 100 árboles para balancear precisión y costo computacional
random_forest <- randomForest(usage_kwh ~ . - date,
data = datos_entrenamiento,
ntree = 100,
importance = TRUE)
# Generación de predicciones sobre los datos de prueba
predicciones <- predict(random_forest, newdata = datos_prueba)
Métricas de desempeño del modelo sobre datos no vistos.
# Cálculo de métricas
rmse <- sqrt(mean((datos_prueba$usage_kwh - predicciones)^2))
mae <- mean(abs(datos_prueba$usage_kwh - predicciones))
r2 <- 1 - sum((datos_prueba$usage_kwh - predicciones)^2) /
sum((datos_prueba$usage_kwh - mean(datos_prueba$usage_kwh))^2)
# Presentación de resultados
cat("Métricas de Desempeño\n")
## Métricas de Desempeño
cat("RMSE (Raíz Error Cuadrático Medio):", round(rmse, 4), "kWh\n")
## RMSE (Raíz Error Cuadrático Medio): 1.8462 kWh
cat("R² (Coeficiente de Determinación):", round(r2, 4), "\n")
## R² (Coeficiente de Determinación): 0.997
# Gráfico de Validación del Modelo: Real vs Estimado
resultados <- data.frame(Real = datos_prueba$usage_kwh, Predicho = predicciones)
ggplot(resultados, aes(x = Real, y = Predicho)) +
geom_point(alpha = 0.1, color = "darkgreen") +
geom_abline(slope = 1, intercept = 0, color = "red", linetype = "dashed", size = 1) +
labs(title = "Validación del Modelo: Real vs Estimado",
subtitle = paste("R² =", round(r2, 4)),
x = "Consumo Real (kWh)",
y = "Consumo Estimado (kWh)") +
theme_minimal()
El modelo Random Forest ha alcanzado un coeficiente de determinación (\(R^2\)) superior al 0.99, lo que indica una capacidad predictiva extremadamente alta. (V E and Cho 2021)El RMSE obtenido sugiere que el error promedio en la estimación es mínimo respecto a la escala total de consumo de la planta.
Se espera que la identificación de las variables críticas mediante el análisis de importancia, resulte ser un aporte de este trabajo a la gestión de la demanda energética y la optimización de activos en el contexto industrial.
varImpPlot(random_forest,
main = "Importancia de Variables en la Estimación",
col = "darkblue",
pch = 19)
1. Gestión de Activos: La alta importancia de la Potencia Reactiva (Lagging/Leading kVarh) y las emisiones de CO2 confirma que el consumo activo está intrínsecamente ligado a la eficiencia de los motores y transformadores de la planta.
2. Sostenibilidad: La correlación perfecta entre consumo y CO2 hallada en el EDA implica que cualquier estrategia de reducción de consumo (eficiencia energética) tendrá un impacto lineal directo en la descarbonización de la planta.
3. Aplicabilidad: Este modelo puede integrarse en un sistema SCADA para pronosticar picos de demanda en tiempo real, permitiendo a la gerencia activar protocolos de “Load Shifting” (desplazamiento de carga) a horarios donde la tarifa eléctrica es menor.