Consumo Energético – Universidad Surcolombiana (USCO) – Especialización en Estadística
Author
Sergio Andres Beltran, Juan Pablo Donato
Published
April 24, 2026
1 Descripción del Problema e Hipótesis
La Sede Central de la Universidad Surcolombiana (USCO) cuenta con cinco cuentas eléctricas activas (Central 1 a Central 5). La normativa eléctrica colombiana (CREG 015 de 2018) establece que la relación entre energía reactiva y energía activa no debe superar 0.48. El incumplimiento de esta norma genera recargos económicos directos en la factura eléctrica.
El análisis se aborda en dos niveles:
Nivel Sede: ¿El consumo total de energía activa de la sede predice si alguna cuenta incumplirá la norma ese mes?
Nivel Cuenta: ¿El consumo de energía activa de una cuenta individual predice si esa cuenta cumplirá o no la norma?
NoteHipótesis del Estudio
Modelo Simple — Nivel Sede:
\(H_0: \beta_1 = 0\) → La energía activa total NO predice el incumplimiento normativo de la sede.
\(H_1: \beta_1 \neq 0\) → La energía activa total SÍ predice el incumplimiento normativo.
Modelo Múltiple — Nivel Sede:
\(H_0: \beta_1 = \beta_2 = 0\) → Ni la energía activa total ni el período de vacaciones académicas explican el incumplimiento normativo de la sede.
\(H_1\): Al menos un \(\beta_k \neq 0\) → Alguna variable predice el incumplimiento.
Modelos por Cuenta Individual:
\(H_0: \beta_1 = 0\) → El consumo activo de la cuenta NO predice su propio cumplimiento.
\(H_1: \beta_1 \neq 0\) → El consumo activo SÍ predice el cumplimiento de la cuenta.
2 Descripción de Variables
Ver código
# Definición de directorios y carga de fuentes de datosRUTA_BASE <-"C:/Users/ESTUDIANTES/Documents/Working Holydays/"# ── Carga de las dos tablas exportadas por el script de unificación ─────────────dt_cuenta <-read.csv(paste0(RUTA_BASE, "Consumo_Central.csv"),header =TRUE, sep =",")dt_sede <-read.csv(paste0(RUTA_BASE, "Resumen_Sede.csv"),header =TRUE, sep =",")# ── Conversiones de tipo necesarias para los modelos ─────────────────────────dt_cuenta$Cuenta <-factor(dt_cuenta$Cuenta)dt_cuenta$Nombre_Cuenta<-factor(dt_cuenta$Nombre_Cuenta)dt_cuenta$Cumple <-factor(dt_cuenta$Cumple, levels =c("Sí", "No"))dt_sede$Sede_Incumple <-as.integer(dt_sede$Sede_Incumple)# ── Tabla resumen de datos cargados ─────────────────────────────────────resumen_datos <-data.frame(Concepto =c("Registros cuenta-período (Tabla 1)","Registros sede-período (Tabla 2)","Cuentas activas","Período cubierto","Períodos con incumplimiento (sede)"),Valor =c(as.character(nrow(dt_cuenta)),as.character(nrow(dt_sede)),as.character(length(unique(dt_cuenta$Cuenta))),paste(min(dt_cuenta$Ano), "–", max(dt_cuenta$Ano)),as.character(sum(dt_sede$Sede_Incumple))))apa_table(resumen_datos,col.names =c("Concepto", "Valor"),caption ="Resumen de los Datos Cargados",align =c("l", "r"))
tabla_vars <-data.frame(Tabla =c("Tabla 2", "Tabla 2", "Tabla 2","Tabla 1", "Tabla 1", "Tabla 1", "Tabla 1"),Variable =c("Sede_Incumple", "Activa_Total", "Cuentas_Incumplen","Cumple_bin", "Activa", "Cuenta", "Pago"),Tipo =c("Binaria (0/1)", "Continua", "Discreta (0–5)","Binaria (0/1)", "Continua", "Categórica (5 niveles)", "Continua"),Rol =c("**Y — Modelo Sede**", "X principal — Modelo Sede","Descriptiva","**Y — Modelo Central 2** (Sección 6.5)", "X principal — Modelo Cuenta","Covariable — Modelo Unificado", "Descriptiva"),Descripcion =c("1 = al menos una cuenta incumple ese mes; 0 = todas cumplen","Suma de energía activa de las 5 cuentas (kWh)","Número de cuentas con Reactiva/Activa > 0.48 ese mes","1 = cuenta cumple norma ese mes; 0 = incumple","Energía activa individual de la cuenta (kWh)","Identificador de cuenta (Central 1 a Central 5)","Valor pagado por la cuenta ese período (COP)" ))apa_table(tabla_vars,col.names =c("Tabla", "Variable", "Tipo", "Rol", "Descripción"),caption ="Diccionario de Variables del Estudio",align =c("l", "l", "l", "l", "l"))
Diccionario de Variables del Estudio
Tabla
Variable
Tipo
Rol
Descripción
Tabla 2
Sede_Incumple
Binaria (0/1)
**Y — Modelo Sede**
1 = al menos una cuenta incumple ese mes; 0 = todas cumplen
Tabla 2
Activa_Total
Continua
X principal — Modelo Sede
Suma de energía activa de las 5 cuentas (kWh)
Tabla 2
Cuentas_Incumplen
Discreta (0–5)
Descriptiva
Número de cuentas con Reactiva/Activa > 0.48 ese mes
Tabla 1
Cumple_bin
Binaria (0/1)
**Y — Modelo Central 2** (Sección 6.5)
1 = cuenta cumple norma ese mes; 0 = incumple
Tabla 1
Activa
Continua
X principal — Modelo Cuenta
Energía activa individual de la cuenta (kWh)
Tabla 1
Cuenta
Categórica (5 niveles)
Covariable — Modelo Unificado
Identificador de cuenta (Central 1 a Central 5)
Tabla 1
Pago
Continua
Descriptiva
Valor pagado por la cuenta ese período (COP)
WarningVariables excluidas del modelo — Razón metodológica
Relacion y Reactiva no se incluyen como predictoras porque Cumple se define directamente como Relacion ≤ 0.48, donde Relacion = Reactiva / Activa. Incluirlas sería tautológico: el modelo estaría explicando Y con la misma información usada para construir Y, generando coeficientes artificialmente perfectos sin valor predictivo real.
3 Exploración de Datos
3.1 Distribución del Cumplimiento Normativo
Ver código
# ── Período máximo de referencia ──────────────────────────────────────────────periodo_max <-max(dt_cuenta$Tiempo, na.rm =TRUE) # 291# ── Tabla EPV por cuenta con cobertura temporal ──────────────────────────────epv_tabla <- dt_cuenta %>%group_by(Cuenta, Nombre_Cuenta) %>%summarise(Inicio =min(Tiempo, na.rm =TRUE), Períodos =n(),Esperados = periodo_max - Inicio +1,Faltantes = Esperados - Períodos,Cumple =sum(Cumple =="Sí", na.rm =TRUE),No_Cumple = Períodos - Cumple,Pct_Cumple =round(Cumple / Períodos *100, 1),EPV_max_vars =floor(No_Cumple /10),.groups ="drop" )# ── Fila resumen sede ─────────────────────────────────────────────────────────epv_sede <- dt_sede %>%summarise(Inicio =min(Tiempo, na.rm =TRUE), Períodos =n(),Esperados = periodo_max - Inicio +1,Faltantes = Esperados - Períodos,Cumple =sum(Sede_Incumple ==0),No_Cumple =sum(Sede_Incumple ==1),Pct_Cumple =round(Cumple / Períodos *100, 1),EPV_max_vars =floor(No_Cumple /10) ) %>%mutate(Cuenta ="SEDE", Nombre_Cuenta ="Sede Central (todas)") %>%select(Cuenta, Nombre_Cuenta, everything())epv_completa <-bind_rows(epv_tabla, epv_sede)apa_table(epv_completa,col.names =c("Cuenta", "Nombre", "Inicio", "Períodos","Esperados", "Faltantes", "Cumple","Incumple", "% Cumple", "Máx. vars (EPV)"),caption ="Distribución del Cumplimiento Normativo, Cobertura Temporal y Capacidad del Modelo (EPV)",align =c("l", "l", "c", "c", "c", "c", "r", "r", "r", "c"),nota =paste0("Inicio: período secuencial en que la cuenta registra su primera medición. ","Esperados: períodos desde el inicio hasta el período ", periodo_max,". Faltantes: períodos sin registro desde el inicio (huecos en la serie)."))
Distribución del Cumplimiento Normativo, Cobertura Temporal y Capacidad del Modelo (EPV)
Cuenta
Nombre
Inicio
Períodos
Esperados
Faltantes
Cumple
Incumple
% Cumple
Máx. vars (EPV)
167382131
Central 1
1
286
291
5
282
4
98.6
0
167383918
Central 4
1
277
291
14
274
3
98.9
0
167385482
Central 2
1
286
291
5
147
139
51.4
13
357154485
Central 5
32
239
260
21
215
24
90.0
2
847747377
Central 3
265
24
27
3
17
7
70.8
0
SEDE
Sede Central (todas)
1
291
291
0
149
142
51.2
14
Nota. Inicio: período secuencial en que la cuenta registra su primera medición. Esperados: períodos desde el inicio hasta el período 291. Faltantes: períodos sin registro desde el inicio (huecos en la serie).
NoteRegla de los 10 Eventos por Variable (EPV)
La regla EPV del módulo establece: \(\text{Máx. variables} = \frac{\text{Total incumplimientos}}{10}\). Para el modelo a nivel sede (142 incumplimientos) el modelo soporta hasta 14 variables. A nivel de cuenta individual, Central 2 registra 147 incumplimientos (51.4% de sus períodos) y Central 5 registra 27 (11.3%), lo que las convierte en las únicas cuentas con eventos suficientes para modelado propio. La Sección 6 explora el impacto de cada cuenta sobre el incumplimiento de sede, y la Sección 6.5 construye un modelo propio para Central 2, aprovechando sus 147 eventos que soportan hasta 14 variables según la regla EPV.
3.2 Gráfico Principal: Pago, Cuentas Pagadas e Incumplimiento en el Tiempo
Ver código
# Escala de transformación para el eje secundario (0–5 → escala del pago)pago_max <-max(dt_sede$Pago_Total_Sede, na.rm =TRUE)escala_k <- pago_max /5# factor para llevar 0–5 a la escala del pagoggplot(dt_sede, aes(x = Tiempo)) +# ── Área: Cuentas pagadas (fondo) ──────────────────────────────────────────geom_area(aes(y = Cuentas_Pagadas * escala_k),fill ="#AED6F1", alpha =0.4) +# ── Barras: Cuentas que incumplen ──────────────────────────────────────────geom_col(aes(y = Cuentas_Incumplen * escala_k),fill ="#E74C3C", alpha =0.6, width =0.8) +# ── Línea: Pago Total Sede ─────────────────────────────────────────────────geom_line(aes(y = Pago_Total_Sede),color ="#2C3E50", linewidth =1.1) +geom_point(aes(y = Pago_Total_Sede,color =factor(Sede_Incumple)),size =1.8, alpha =0.8) +scale_color_manual(values =c("0"="#27AE60", "1"="#E74C3C"),labels =c("0"="Sede cumple", "1"="Sede incumple"),name ="Estado normativo" ) +# ── Eje secundario (derecho): escala 0–5 ──────────────────────────────────scale_y_continuous(name ="Pago Total Sede (COP)",labels =label_comma(big.mark =".", decimal.mark =","),sec.axis =sec_axis(transform =~ . / escala_k,name ="Número de cuentas (máx. 5)",breaks =0:5 ) ) +labs(title ="Pago Total, Cuentas Pagadas y Cuentas en Incumplimiento — Sede Central USCO",subtitle ="Línea: Pago total mensual | Área azul: cuentas pagadas | Barras rojas: cuentas que incumplen",x ="Período (meses)",caption ="Fuente: USCO — Consumo Sede Central 2000–2025" ) +theme_minimal(base_size =12) +theme(plot.title =element_text(face ="bold", color ="#2C3E50", size =13),plot.subtitle =element_text(color ="#555555", size =10),axis.title.y =element_text(color ="#2C3E50"),axis.title.y.right =element_text(color ="#E74C3C"),legend.position ="bottom",panel.grid.minor =element_blank() )
Interpretación: Los períodos donde las barras rojas son más altas (más cuentas incumpliendo) tienden a coincidir visualmente con picos en el valor del pago, lo que sugiere que el incumplimiento normativo tiene un efecto económico observable. Esta relación motiva la construcción del modelo logístico.
3.3 Consumo Activo por Cuenta en el Tiempo
Ver código
ggplot(dt_cuenta, aes(x = Tiempo, y = Activa /1000,color = Nombre_Cuenta, group = Nombre_Cuenta)) +geom_line(alpha =0.8, linewidth =0.9) +geom_point(aes(shape = Cumple), size =1.5, alpha =0.6) +scale_shape_manual(values =c("Sí"=19, "No"=4),name ="Cumple norma") +scale_color_brewer(palette ="Set1", name ="Cuenta") +labs(title ="Energía Activa por Cuenta — Sede Central USCO",subtitle ="Punto ✕ = período de incumplimiento normativo",x ="Período (meses)",y ="Energía Activa (miles de kWh)",caption ="Fuente: USCO — Consumo Sede Central 2000–2025" ) +theme_minimal(base_size =12) +theme(plot.title =element_text(face ="bold", color ="#2C3E50"),legend.position ="bottom",panel.grid.minor =element_blank() )
4 Modelo Logístico Simple — Nivel Sede
Variable Dependiente (\(Y\)):Sede_Incumple (0 = todas cumplen, 1 = al menos una incumple) Variable Predictora (\(X\)):Activa_Total (kWh totales de la sede ese mes)
4.1 La Función Logística
El modelo no estima directamente si la sede incumplirá, sino la probabilidad de que ocurra el incumplimiento, acotada estrictamente entre 0 y 1 mediante la función sigmoide:
metricas_s <-data.frame( Métrica =c("Exactitud global (Accuracy)","Sensibilidad (Recall — detectar incumplimientos)","Especificidad (descartar cumplimientos)"),Valor =paste0(round(c(acc_s, sens_s, esp_s) *100, 2), "%"),Interpretacion =c("Proporción total de clasificaciones correctas","De todos los meses que SÍ hubo incumplimiento, ¿cuántos detectó el modelo?","De todos los meses donde se cumplió la norma, ¿cuántos identificó correctamente?" ))apa_table(metricas_s,col.names =c("Métrica", "Valor", "Interpretación"),caption ="Métricas de Desempeño — Modelo Simple Sede",align =c("l", "r", "l"))
Métricas de Desempeño — Modelo Simple Sede
Métrica
Valor
Interpretación
Exactitud global (Accuracy)
68.04%
Proporción total de clasificaciones correctas
Sensibilidad (Recall — detectar incumplimientos)
56.34%
De todos los meses que SÍ hubo incumplimiento, ¿cuántos detectó el modelo?
Especificidad (descartar cumplimientos)
79.19%
De todos los meses donde se cumplió la norma, ¿cuántos identificó correctamente?
5 Modelo Logístico Múltiple — Nivel Sede
Se incorpora Vacaciones como covariable dicotómica para evaluar si los meses de receso académico (Enero, Junio, Julio y Diciembre) influyen en la probabilidad de incumplimiento normativo, controlando por el nivel de consumo activo. Al ser una sola dummy, el modelo es parsimonioso y responde directamente: ¿estar en vacaciones aumenta el riesgo de incumplimiento?
Indicadores de Ajuste — Modelo Logístico Múltiple (Sede)
Indicador
Valor
Devianza nula
403.24
Devianza residual
327.43
AIC
333.43
N observaciones
291.00
Los coeficientes del modelo revelan dos efectos simultáneos sobre el riesgo de incumplimiento normativo de la sede. El signo positivo de \(\hat{\beta}_1\) confirma que a mayor consumo de energía activa, mayor es la probabilidad de que alguna cuenta supere el umbral de 0.48 — consistente con lo observado en el gráfico exploratorio de la Sección 3, donde los períodos de mayor consumo coincidían visualmente con más cuentas en incumplimiento. El signo positivo de \(\hat{\beta}_2\) indica que los meses de vacaciones representan un riesgo adicional de incumplimiento incluso controlando por el nivel de consumo activo: en receso académico la demanda cae pero las cargas inductivas instaladas — transformadores, aires acondicionados, motores — permanecen energizadas, elevando la relación Reactiva/Activa por encima del límite normativo de 0.48 establecido por la CREG 015 de 2018.
\(\hat{\beta}_1\) = 0.00002714 → Por cada kWh adicional de energía activa total, el log-odds de incumplimiento cambia en 0.00002714 unidades, manteniendo constante el estado de vacaciones.
\(\hat{\beta}_2\) = 1.3859 (p = < 0.001) → Los meses de vacaciones (Ene, Jun, Jul, Dic) aumentan el log-odds de incumplimiento en 1.3859 unidades respecto a los meses de clases. En términos de Odds Ratio: \(OR = e^{1.3859} = 3.9984\) — el riesgo de incumplimiento es mayor en vacaciones.
Ver código
or_mult <-exp(cbind(OR =coef(modelo_sede_mult),confint(modelo_sede_mult)))or_mult_df <-as.data.frame(round(or_mult, 4))or_mult_df$Variable <-c("Intercepto", "Activa_Total", "Vacaciones")or_mult_df$p_valor <-round(resumen_m$coefficients[, 4], 6)or_mult_df$Interpretacion <-c("Punto de anclaje matemático",ifelse(exp(coef_m[2]) >1,"Mayor consumo activo → mayor riesgo de incumplir (Ceteris Paribus)","Mayor consumo activo → menor riesgo de incumplir (Ceteris Paribus)"),ifelse(exp(coef_m[3]) >1,"Vacaciones AUMENTAN el riesgo de incumplimiento vs. meses de clases","Vacaciones REDUCEN el riesgo de incumplimiento vs. meses de clases"))apa_table(or_mult_df[, c("Variable", "OR", "2.5 %", "97.5 %","p_valor", "Interpretacion")],col.names =c("Variable", "OR", "IC 2.5%", "IC 97.5%","p-valor", "Interpretación"),caption ="Odds Ratios — Modelo Logístico Múltiple (Sede: Activa + Vacaciones)",align =c("l", "r", "r", "r", "r", "l"),nota ="Vacaciones = 1 (Ene, Jun, Jul, Dic); 0 = meses de clases. OR > 1 = mayor riesgo en vacaciones.")
Comparación de Modelos por AIC — Nivel Sede (menor AIC = mejor)
Modelo
Parámetros
AIC
Devianza
Ranking
M3: ~ Activa_Total + Vacaciones
3
333.43
327.43
1
M1: ~ Activa_Total
2
349.72
345.72
2
M2: ~ Vacaciones
2
407.13
403.13
3
La comparación por AIC muestra que el modelo con Vacaciones supera al modelo simple en capacidad predictiva. Este resultado valida estadísticamente que el calendario académico no es un factor irrelevante: los meses de receso aportan información predictiva real que el consumo activo por sí solo no captura. El modelo seleccionado — Activa_Total + Vacaciones — es el referente de nivel sede contra el que se compararán los modelos de la Sección 6.
La incorporación de Vacaciones no solo mejora el AIC sino que se traduce en una mejora del poder diagnóstico del modelo. La sensibilidad — capacidad de detectar correctamente los meses con incumplimiento — es la métrica más relevante desde el punto de vista operativo: un modelo que falla en detectar el incumplimiento implica que la universidad no anticipa el recargo y llega a la factura sin haber tomado medidas correctivas. La comparación de ambos modelos permite cuantificar exactamente cuánto mejora esa capacidad de alerta al incorporar el factor estacional.
6 Modelo Logístico — Impacto por Cuenta Individual sobre el Incumplimiento de Sede
En las secciones anteriores se modeló el incumplimiento de sede usando el consumo activo agregado (total de las 5 cuentas). Ahora se evalúa una pregunta diferente: ¿el consumo de cuál cuenta individual es más informativo para predecir si la sede incumplirá la norma?
Para responderlo se construyen modelos logísticos simples — uno por cada cuenta (Activa individual → Sede_Incumple) — y se comparan por AIC. Con los mejores predictores se arma un modelo múltiple final.
6.1 Preparación: Consumo Individual en Formato Ancho
Descriptivos de Energía Activa Individual — Formato Ancho
Variable
N válidos
Media (MWh)
DE
Activa_k_Central.1
286
25.5
9.4
Activa_k_Central.4
277
26.3
10.9
Activa_k_Central.2
286
78.9
38.5
Activa_k_Central.5
239
1.3
1.2
Activa_k_Central.3
24
15.7
11.2
6.2 Modelos Simples: Cada Cuenta → Sede_Incumple
Ver código
# ── Lista de predictores candidatos ───────────────────────────────────────────predictores <- nombres_activaresultados_simples <-lapply(predictores, function(pred) { formula_i <-as.formula(paste("Sede_Incumple ~", pred)) datos_i <- dt_sede_ind[!is.na(dt_sede_ind[[pred]]), ] modelo_i <-tryCatch(glm(formula_i, data = datos_i, family =binomial(link ="logit")),error =function(e) NULL )if (is.null(modelo_i)) return(NULL) coef_i <-coef(modelo_i) pval_i <-summary(modelo_i)$coefficients[2, 4] or_i <-exp(coef_i[2]) aic_i <-AIC(modelo_i) n_i <-nrow(datos_i)data.frame(Predictor = pred,N = n_i,b1 =round(coef_i[2], 7),OR =round(or_i, 4),p_valor =round(pval_i, 6),AIC =round(aic_i, 2),Signif =ifelse(pval_i <0.05, "✓ Sí", "✗ No"),Efecto =ifelse(or_i >1,"Mayor consumo → mayor riesgo de incumplimiento sede","Mayor consumo → menor riesgo de incumplimiento sede") )})tabla_simples <-do.call(rbind, resultados_simples)tabla_simples <- tabla_simples[order(tabla_simples$AIC), ]tabla_simples$Ranking <-1:nrow(tabla_simples)apa_table(tabla_simples,col.names =c("Predictor", "N", "β₁", "OR", "p-valor","AIC", "Significativo", "Dirección del efecto", "Ranking"),caption ="Comparación de Modelos Simples — Predictor Individual → Incumplimiento Sede",align =c("l", "c", "r", "r", "r", "r", "c", "l", "c"),nota =paste0("Cada modelo es logístico simple: Sede_Incumple ~ Predictor. ","Central 3 tiene EPV = 0 (solo 24 períodos válidos); ","su resultado se reporta con fines descriptivos únicamente. ","Ordenado por AIC ascendente."))
Comparación de Modelos Simples — Predictor Individual → Incumplimiento Sede
Predictor
N
β₁
OR
p-valor
AIC
Significativo
Dirección del efecto
Ranking
Activa_k_Central.3
24
-0.0104329
0.9896
0.876231
17.74
✗ No
Mayor consumo → menor riesgo de incumplimiento sede
1
Activa_k_Central.2
286
0.0430661
1.0440
0.000000
284.77
✓ Sí
Mayor consumo → mayor riesgo de incumplimiento sede
2
Activa_k_Central.5
239
0.7063364
2.0266
0.000000
301.51
✓ Sí
Mayor consumo → mayor riesgo de incumplimiento sede
3
Activa_k_Central.4
277
-0.1010292
0.9039
0.000000
326.52
✓ Sí
Mayor consumo → menor riesgo de incumplimiento sede
4
Activa_k_Central.1
286
0.0183367
1.0185
0.150605
398.34
✗ No
Mayor consumo → mayor riesgo de incumplimiento sede
5
Nota. Cada modelo es logístico simple: Sede_Incumple ~ Predictor. Central 3 tiene EPV = 0 (solo 24 períodos válidos); su resultado se reporta con fines descriptivos únicamente. Ordenado por AIC ascendente.
Los predictores con menor AIC identifican las cuentas cuyo consumo activo individual aporta mayor información predictiva sobre el incumplimiento normativo de la sede. Estos predictores son seleccionados para construir el modelo múltiple final.
Central 2 lidera el ranking con el menor AIC individual, lo que indica que su consumo activo es el predictor más informativo del incumplimiento de sede entre las cinco cuentas. Esto tiene una explicación técnica directa: Central 2 es la cuenta de mayor consumo promedio de la sede (78.9 MWh/mes según la tabla descriptiva de la Sección 6.1), y su alta demanda de cargas inductivas — equipos de laboratorio, sistemas de climatización, motores — genera energía reactiva en mayor proporción que las demás cuentas. Central 5, pese a tener el menor consumo promedio (1.3 MWh/mes), ocupa el segundo lugar en poder predictivo, lo que sugiere que incluso pequeñas variaciones en su consumo son señal del estado normativo de la sede. Central 4 presenta efecto protector (OR < 1): su mayor consumo activo se asocia con menor riesgo de incumplimiento de sede, posiblemente porque es una cuenta con cargas predominantemente resistivas (iluminación, equipos de cómputo) que no generan reactiva en exceso.
Nota metodológica — Central 3 en el modelo múltiple: Aunque Central 3 se incluye en la tabla comparativa anterior, no se incorpora al modelo múltiple. Al combinarse con otras predictoras se detectó separación perfecta: clasificación casi determinista del incumplimiento que impide la convergencia del algoritmo de Máxima Verosimilitud (MLE), con OR = 0 o Inf, IC = [0, Inf] y p-valores de ~0.99 simultáneamente. Adicionalmente su EPV = 0 la hace inestable como predictora.
6.3 Modelo Múltiple Final — Central 2, Central 5 y Vacaciones
Ver código
# ── Filtrar períodos válidos para los dos predictores seleccionados ────────────dt_modelo_final <- dt_sede_ind %>%filter(!is.na(Activa_k_Central.2),!is.na(Activa_k_Central.5))cat("Períodos válidos para el modelo final:", nrow(dt_modelo_final), "\n")
Períodos válidos para el modelo final: 237
Ver código
# Modelo A: Central 2 + Central 5modelo_cuentas_a <-glm(Sede_Incumple ~ Activa_k_Central.2+ Activa_k_Central.5,data = dt_modelo_final,family =binomial(link ="logit"))# Modelo B: Central 2 + Central 5 + Vacacionesmodelo_cuentas_b <-glm(Sede_Incumple ~ Activa_k_Central.2+ Activa_k_Central.5+ Vacaciones,data = dt_modelo_final,family =binomial(link ="logit"))resumen_s7m <-summary(modelo_cuentas_b)# ── Tabla de coeficientes ──────────────────────────────────────────────────────coef_tabla_f <-data.frame( Parámetro =c("β₀ (Intercepto)", "Activa_k_Central.2","Activa_k_Central.5", "Vacaciones"),Estimador =round(resumen_s7m$coefficients[, 1], 6),Error_Std =round(resumen_s7m$coefficients[, 2], 6),z =round(resumen_s7m$coefficients[, 3], 4),p_valor =format(resumen_s7m$coefficients[, 4], scientific =TRUE))apa_table(coef_tabla_f,col.names =c("Parámetro", "Estimador", "Error Estándar", "z", "p-valor"),caption ="Coeficientes — Modelo Múltiple: Central 2 + Central 5 + Vacaciones",align =c("l", "r", "r", "r", "r"),nota =paste0("Categoría de referencia Vacaciones: meses de clases (0). ","Vacaciones = 1 para Enero, Junio, Julio y Diciembre."))
Coeficientes — Modelo Múltiple: Central 2 + Central 5 + Vacaciones
Parámetro
Estimador
Error Estándar
z
p-valor
β₀ (Intercepto)
-5.637072
0.735411
-7.6652
1.785565e-14
Activa_k_Central.2
0.069531
0.009970
6.9739
3.081965e-12
Activa_k_Central.5
-0.421437
0.240329
-1.7536
7.950137e-02
Vacaciones
1.859629
0.420108
4.4265
9.575326e-06
Nota. Categoría de referencia Vacaciones: meses de clases (0). Vacaciones = 1 para Enero, Junio, Julio y Diciembre.
Odds Ratios — Modelo Múltiple Final (Central 2 + Central 5 + Vacaciones)
OR
IC 2.5%
IC 97.5%
p-valor
Significativo
0.0036
0.0008
0.0137
0.000000
✓ Sí
1.0720
1.0529
1.0951
0.000000
✓ Sí
0.6561
0.3966
1.0229
0.079501
✗ No
6.4214
2.9067
15.1961
0.000010
✓ Sí
Nota. OR > 1 = mayor consumo/vacaciones aumenta riesgo de incumplimiento sede.
Los Odds Ratios del modelo múltiple final revelan un resultado metodológicamente relevante: Central 5 no resulta estadísticamente significativa (p > 0.05) cuando se controla simultáneamente por Central 2 y Vacaciones. Este fenómeno — denominado supresión en el contexto multivariante — indica que el efecto predictivo de Central 5 observado en el modelo simple de la Sección 6.2 estaba parcialmente mediado por su correlación con Central 2. En la práctica operativa esto significa que la atención debe concentrarse en Central 2 como el punto crítico primario de gestión, sin descartar el monitoreo de Central 5 como indicador secundario. Vacaciones mantiene su significancia y dirección en el modelo múltiple, confirmando la robustez del efecto estacional identificado en la Sección 5.
6.3.2 Matriz de Confusión y Métricas — Modelo Final
metricas_f <-data.frame( Métrica =c("Exactitud global (Accuracy)","Sensibilidad (detectar incumplimientos)","Especificidad (descartar cumplimientos)"),Valor =paste0(round(c(acc_f, sens_f, esp_f) *100, 2), "%"),Interpretacion =c("Proporción total de clasificaciones correctas","De todos los meses con incumplimiento, ¿cuántos detectó el modelo?","De todos los meses donde se cumplió la norma, ¿cuántos identificó correctamente?" ))apa_table(metricas_f,col.names =c("Métrica", "Valor", "Interpretación"),caption ="Métricas de Desempeño — Modelo Múltiple Final",align =c("l", "r", "l"))
Métricas de Desempeño — Modelo Múltiple Final
Métrica
Valor
Interpretación
Exactitud global (Accuracy)
85.65%
Proporción total de clasificaciones correctas
Sensibilidad (detectar incumplimientos)
85.94%
De todos los meses con incumplimiento, ¿cuántos detectó el modelo?
Especificidad (descartar cumplimientos)
85.32%
De todos los meses donde se cumplió la norma, ¿cuántos identificó correctamente?
6.4 Central 2: Modelo Logístico Propio
Central 2 registra 147 períodos de incumplimiento sobre 286 válidos — una frecuencia del 51.4% que la convierte en la cuenta con mayor inestabilidad normativa de la sede. Con 147 eventos, la regla EPV soporta hasta 14 variables predictoras, lo que permite construir un modelo propio robusto. A diferencia de la sección anterior donde Central 2 actuaba como predictor del incumplimiento de sede, aquí se modela su propio cumplimiento como variable dependiente.
El hallazgo de la Sección 6.2 — que Central 2 es el mejor predictor individual del incumplimiento de sede — plantea una pregunta natural: ¿puede predecirse el propio cumplimiento de Central 2 a partir de sus variables de consumo? A diferencia del análisis anterior donde Central 2 actuaba como variable independiente explicando el comportamiento de la sede, aquí se invierte el rol: Cumple_bin de Central 2 pasa a ser la variable dependiente, y Activa_k junto con Vacaciones son los predictores. Con 147 eventos de incumplimiento, la regla EPV autoriza hasta 14 variables — margen amplio para un modelo robusto.
Ver código
# ── Filtrar datos de Central 2 ────────────────────────────────────────────────# Cumple_bin y Vacaciones ya existen en Consumo_Central.csvdt_c2 <- dt_cuenta %>%filter(Nombre_Cuenta =="Central 2") %>%mutate(Activa_k = Activa /1000)# ── Tabla resumen ─────────────────────────────────────────────────────────────n_c2 <-nrow(dt_c2)incumple_c2 <-sum(dt_c2$Cumple_bin ==0)pct_inc_c2 <-round(incumple_c2 / n_c2 *100, 1)epv_max_c2 <-floor(incumple_c2 /10)resumen_c2 <-data.frame(Concepto =c("N períodos totales","Incumplimientos (Cumple = No)","Porcentaje de incumplimiento","EPV máximo (floor(incumplimientos / 10))"),Valor =c(as.character(n_c2),as.character(incumple_c2),paste0(pct_inc_c2, "%"),as.character(epv_max_c2)))apa_table(resumen_c2,col.names =c("Concepto", "Valor"),caption ="Distribución del Cumplimiento — Central 2",align =c("l", "r"))
# ── Matriz de confusión del modelo múltiple ───────────────────────────────────prob_c2 <-predict(modelo_c2_m, type ="response")pred_c2 <-ifelse(prob_c2 >0.5, 1, 0)mc_c2 <-table(Prediccion = pred_c2, Real = dt_c2$Cumple_bin)VN_c2 <- mc_c2["0", "0"]; FN_c2 <- mc_c2["0", "1"]FP_c2 <- mc_c2["1", "0"]; VP_c2 <- mc_c2["1", "1"]acc_c2 <- (VP_c2 + VN_c2) /sum(mc_c2)sens_c2 <- VP_c2 / (VP_c2 + FN_c2)esp_c2 <- VN_c2 / (VN_c2 + FP_c2)# ── Gráfico: Matriz de Confusión estilo heatmap ──────────────────────────────datos_mc_c2 <-data.frame(Predicho =factor(c("Cumple (1)", "Incumple (0)", "Cumple (1)", "Incumple (0)"),levels =c("Incumple (0)", "Cumple (1)")),Real =factor(c("Cumple (1)", "Cumple (1)", "Incumple (0)", "Incumple (0)"),levels =c("Incumple (0)", "Cumple (1)")),Frecuencia =c(VP_c2, FP_c2, FN_c2, VN_c2))ggplot(datos_mc_c2, aes(x = Predicho, y = Real, fill = Frecuencia)) +geom_tile(color ="black", linewidth =1) +geom_text(aes(label = Frecuencia), size =8, fontface ="bold") +scale_fill_gradient(low ="white", high ="#E74C3C") +labs(title ="Matriz de Confusión: Modelo Múltiple Central 2",subtitle =paste0("Evaluación empírica sobre n = ", sum(mc_c2), " períodos"),x ="Predicción del Modelo",y ="Realidad (Observada)") +theme_minimal() +theme(axis.text =element_text(size =12, face ="bold"),title =element_text(size =14, face ="bold"),legend.position ="none")
Ver código
# ── Tabla de métricas ─────────────────────────────────────────────────────────metricas_c2 <-data.frame( Métrica =c("Accuracy","Sensibilidad","Especificidad"),Valor =paste0(round(c(acc_c2, sens_c2, esp_c2) *100, 2), "%"),Interpretacion =c("Proporción total de clasificaciones correctas","De todos los períodos que SÍ cumplieron, ¿cuántos detectó el modelo?","De todos los períodos que NO cumplieron, ¿cuántos identificó correctamente?" ))apa_table(metricas_c2,col.names =c("Métrica", "Valor", "Interpretación"),caption ="Métricas de Desempeño — Modelo Múltiple Central 2",align =c("l", "r", "l"))
Métricas de Desempeño — Modelo Múltiple Central 2
Métrica
Valor
Interpretación
Accuracy
86.36%
Proporción total de clasificaciones correctas
Sensibilidad
89.12%
De todos los períodos que SÍ cumplieron, ¿cuántos detectó el modelo?
Especificidad
83.45%
De todos los períodos que NO cumplieron, ¿cuántos identificó correctamente?
Ver código
# ── Comparación AIC de los dos modelos de Central 2 ───────────────────────────modelos_c2 <-list("M1: ~ Activa_k"= modelo_c2_s,"M2: ~ Activa_k + Vacaciones"= modelo_c2_m)tabla_aic_c2 <-data.frame(Modelo =names(modelos_c2), Parámetros =sapply(modelos_c2, function(m) length(coef(m))),AIC =round(sapply(modelos_c2, AIC), 2),Devianza =round(sapply(modelos_c2, function(m) m$deviance), 2))tabla_aic_c2 <- tabla_aic_c2[order(tabla_aic_c2$AIC), ]apa_table(tabla_aic_c2,col.names =c("Modelo", "Parámetros", "AIC", "Devianza residual"),caption ="Comparación por AIC — Modelos Central 2",align =c("l", "c", "r", "r"),nota ="Menor AIC indica mejor balance entre ajuste y parsimonia.")
Comparación por AIC — Modelos Central 2
Modelo
Parámetros
AIC
Devianza residual
M2: ~ Activa_k + Vacaciones
3
251.75
245.75
M1: ~ Activa_k
2
274.56
270.56
Nota. Menor AIC indica mejor balance entre ajuste y parsimonia.
La comparación AIC dentro del nivel de Central 2 confirma que Vacaciones aporta información predictiva también a escala de cuenta individual — el mismo efecto estacional documentado a nivel sede en la Sección 5 se replica cuando se analiza exclusivamente el comportamiento de Central 2. Este resultado tiene implicaciones técnicas: el recargo por energía reactiva en Central 2 no obedece únicamente al nivel de consumo activo del edificio sino a la composición de sus cargas eléctricas durante el receso, cuando equipos inductivos permanecen activos sin la compensación que genera el consumo normal de laboratorios y oficinas en período académico. Desde el punto de vista de la gestión energética, esto señala que una intervención efectiva en Central 2 requiere tanto una revisión del inventario de cargas inductivas instaladas como un protocolo de apagado supervisado durante los meses de receso.
6.5 Comparación Global — Todos los Modelos
Ver código
modelos_global <-list("M1: Sede ~ Activa_Total"= modelo_sede_simple,"M2: Sede ~ Activa_Total + Vacaciones"= modelo_sede_mult,"M3: Sede ~ Central2 + Central5"= modelo_cuentas_a,"M4: Sede ~ Central2 + Central5 + Vacaciones"= modelo_cuentas_b,"M5: C2 ~ Activa_k"= modelo_c2_s,"M6: C2 ~ Activa_k + Vacaciones"= modelo_c2_m)tabla_global <-data.frame(Modelo =names(modelos_global), Parámetros =sapply(modelos_global, function(m) length(coef(m))),AIC =round(sapply(modelos_global, AIC), 2),Devianza =round(sapply(modelos_global,function(m) m$deviance), 2))tabla_global <- tabla_global[order(tabla_global$AIC), ]tabla_global$Ranking <-1:nrow(tabla_global)apa_table(tabla_global,col.names =c("Modelo", "Parámetros", "AIC","Devianza residual", "Ranking"),caption ="Comparación Global — Todos los Modelos (Sede + Central 2)",align =c("l", "c", "r", "r", "c"),nota =paste0("M1–M4: variable dependiente = Sede_Incumple. ","M5–M6: variable dependiente = Cumple_bin (Central 2). ","Ordenado por AIC ascendente; menor AIC = mejor balance ajuste-parsimonia. ","Los AIC de M1–M4 y M5–M6 no son directamente comparables entre sí ","por tener distinta variable dependiente y distinto N."))
Comparación Global — Todos los Modelos (Sede + Central 2)
Modelo
Parámetros
AIC
Devianza residual
Ranking
M4: Sede ~ Central2 + Central5 + Vacaciones
4
207.45
199.45
1
M3: Sede ~ Central2 + Central5
3
228.47
222.47
2
M6: C2 ~ Activa_k + Vacaciones
3
251.75
245.75
3
M5: C2 ~ Activa_k
2
274.56
270.56
4
M2: Sede ~ Activa_Total + Vacaciones
3
333.43
327.43
5
M1: Sede ~ Activa_Total
2
349.72
345.72
6
Nota. M1–M4: variable dependiente = Sede_Incumple. M5–M6: variable dependiente = Cumple_bin (Central 2). Ordenado por AIC ascendente; menor AIC = mejor balance ajuste-parsimonia. Los AIC de M1–M4 y M5–M6 no son directamente comparables entre sí por tener distinta variable dependiente y distinto N.
La comparación por AIC permite evaluar, dentro de cada nivel, si la incorporación de Vacaciones aporta información adicional más allá del consumo activo. Los modelos M1–M4 (nivel sede) y M5–M6 (Central 2 individual) no son directamente comparables entre sí por tener distinta variable dependiente y distinto tamaño muestral, pero su yuxtaposición facilita una lectura integrada del análisis.
7 Conclusiones
1. Datos y balance: El análisis cubre 291 períodos mensuales (2001–2025) de cinco cuentas eléctricas de la Sede Central de la USCO. El 48.8% de los períodos registran al menos una cuenta en incumplimiento normativo — un balance cercano al 50/50 que garantiza la confiabilidad estadística de los modelos construidos y evita el sesgo por desbalance de clases advertido en el módulo.
2. Nivel sede — modelo simple: La energía activa total de la sede es un predictor estadísticamente significativo (p < 0.05) del incumplimiento normativo. El gráfico de doble eje (Sección 3) ya anticipaba esta relación: los períodos con más cuentas incumpliendo coinciden visualmente con niveles elevados de consumo activo. El OR confirma que a mayor consumo activo total, mayor es la probabilidad de que alguna cuenta supere el umbral normativo de 0.48..
3. Nivel sede — variable Vacaciones y selección del modelo: La incorporación de Vacaciones como covariable (Enero, Junio, Julio y Diciembre) mejora el modelo según el criterio AIC. El modelo recomendado a nivel sede es M3: ~ Activa_Total + Vacaciones. El efecto de Vacaciones tiene una explicación técnica directa: en receso académico el consumo activo cae, pero las cargas inductivas instaladas — transformadores, aires acondicionados, motores — permanecen energizadas, elevando la relación Reactiva/Activa por encima del límite normativo de 0.48 establecido por la CREG 015 de 2018. Este efecto no es visible en el consumo agregado sin desagregar por período del año.
4. Nivel cuenta — impacto sobre la sede: El análisis de la Sección 6 revela que no todas las cuentas contribuyen igual al incumplimiento de sede. Central 2 presenta el menor AIC individual como predictor de Sede_Incumple, siendo la cuenta más informativa para anticipar el comportamiento normativo de la sede completa. Central 5 ocupa el segundo lugar. Central 3 fue excluida del modelo múltiple por separación perfecta y EPV = 0 — solo 24 períodos válidos — lo que la hace inestable como predictora. Este resultado dirige la atención operativa hacia edificios específicos en lugar de gestionar la sede como una unidad homogénea.
5. Central 2 como unidad de análisis propio: Con 147 incumplimientos en 286 períodos (51.4%), Central 2 es la cuenta con mayor inestabilidad normativa de la sede y la única con suficiente capacidad estadística para soportar un modelo propio robusto (EPV = 14 variables). El modelo múltiple Activa_k + Vacaciones explica su comportamiento con las mismas variables que el modelo de sede, confirmando que el patrón es consistente a ambos niveles de análisis. Desde el punto de vista técnico eléctrico, la frecuencia de incumplimiento del 51.4% sugiere un problema estructural de composición de cargas en ese edificio — no un evento ocasional sino una condición crónica que requiere intervención física: instalación de bancos de condensadores o revisión del inventario de cargas inductivas instaladas. El criterio AIC no es comparable entre M5–M6 y M1–M4 por tener distinta variable dependiente y distinto N; la comparación pertinente es interna: M6 supera a M5 dentro del nivel de Central 2, confirmando que Vacaciones aporta información predictiva también a escala de cuenta individual.
6. Limitaciones y perspectiva: Los modelos de regresión logística construidos identifican qué variables se asocian al incumplimiento y cuándo es más probable que ocurra, pero no predicen con precisión períodos futuros específicos. La estructura temporal de 291 meses consecutivos — evidenciada en las series del gráfico de la Sección 3 — requiere modelos de series de tiempo (ARIMA, SARIMA) para pronóstico. Este análisis constituye el fundamento exploratorio y explicativo que justifica esa extensión metodológica: la regresión logística respondió qué factores explican el incumplimiento; las series de tiempo responderán cuándo ocurrirá en el futuro.
Análisis desarrollado para la Universidad Surcolombiana (USCO) — Sede CentralHerramienta: R R version 4.5.3 (2026-03-11 ucrt)