El estudio de la relación entre la compra pública y el Índice de Calidad de Vida (ICV) es esencial para evaluar el impacto de las políticas de inversión pública en el bienestar de los ciudadanos. La compra pública es un mecanismo mediante el cual los gobiernos adquieren bienes y servicios, y su eficiencia es clave para el desarrollo socioeconómico.
El Índice de Calidad de Vida (ICV) mide el bienestar de una población considerando factores como salud, educación, ingresos y vivienda. Este índice está directamente influenciado por la efectividad de la inversión pública.
Metodologías como el Análisis de Conglomerados y modelos predictivos como Regresión Lineal y ARIMA para series de tiempo son herramientas clave para explorar patrones en los datos y tomar decisiones informadas sobre políticas de inversión. La implementación de la metodología CRISP-DM asegura un análisis estructurado y orientado a resultados.
Este análisis tiene como objetivo explorar cómo las inversiones públicas impactan el ICV en los departamentos, utilizando técnicas de minería de datos y modelado predictivo. La investigación está estructurada en tres fases:
El objetivo principal de este estudio es analizar y modelar la relación entre la compra pública y el Índice de Calidad de Vida (ICV) en los departamentos, con el fin de proporcionar información valiosa que pueda guiar las decisiones de políticas públicas y estrategias de inversión. Para alcanzar este objetivo general, se plantean los siguientes objetivos específicos:
La metodología CRISP-DM (Cross-Industry Standard Process for Data Mining) consta de seis fases para estructurar proyectos de minería de datos:
tabla_cluster_departamento.xlsx
: Variables
socioeconómicas y de compra pública por departamento.secop_cali.csv
: Historial de compras públicas en
Santiago de Cali.Durante una semana, las fases de CRISP-DM pueden desarrollarse así:
La metodología aplicada en este estudio se detalla a continuación, enfocándose en los procedimientos específicos realizados para alcanzar los objetivos planteados.
Se recopilaron datos de diferentes fuentes para asegurar una visión integral de la relación entre la compra pública y el ICV:
Datos socioeconómicos y de compra pública por
departamento: Archivo
tabla_cluster_departamento.xlsx
, que contiene variables
como el Índice de Calidad de Vida (ICV), tasa de urbanización (TURB),
necesidades básicas insatisfechas (NBI), desempeño fiscal (IDESFISCAL),
generación de recursos propios (GENREPRO) y montos invertidos en
diferentes sectores (educación, salud, transporte, entre
otros).
Datos de compras públicas históricas: Archivo
secop_cali.csv
, que incluye registros detallados de las
compras públicas realizadas en Santiago de Cali, con información sobre
fechas y valores de los contratos.
Se utilizaron las siguientes herramientas y procesos para la preparación de los datos:
Librerías de R utilizadas:
readxl
: Para cargar datos desde archivos Excel.dplyr
y tidyr
: Para manipulación y
limpieza de datos.lubridate
: Para manejo y transformación de fechas.ggplot2
: Para visualizaciones.factoextra
y cluster
: Para análisis de
conglomerados.forecast
y tseries
: Para análisis de
series de tiempo.Procesos realizados:
Análisis de Conglomerados:
Análisis de Regresión Lineal:
Análisis de Series de Tiempo:
En esta fase, utilizamos técnicas de aprendizaje no supervisado para
agrupar los departamentos con características similares en cuanto a cómo
distribuyen e invierten en compra pública, excluyendo la variable
objetivo ICV
. Posteriormente, analizaremos cómo varía
ICV
entre los clústeres.
Cargamos las librerías necesarias para el análisis.
library(readxl)
library(dplyr)
library(ggplot2)
library(factoextra)
library(cluster)
library(tidyr)
Cargamos el archivo tabla_cluster_departamento.xlsx
que
contiene los datos.
<- read_excel("tabla_cluster_departamento.xlsx") datos
Visualizamos una descripción general de los datos.
# Mostrar las primeras filas
head(datos)
# Dimensiones del dataset
dim(datos)
## [1] 32 30
Verificamos y manejamos valores faltantes.
# Verificar valores faltantes
sum(is.na(datos))
## [1] 0
# Si hay valores faltantes, se pueden eliminar o imputar
# datos <- na.omit(datos)
Aseguramos que todas las variables numéricas estén en el tipo de dato correcto.
# Convertir variables numéricas si es necesario
<- datos %>%
datos mutate(across(ICV:`Vivienda, Ciudad y Territorio`, ~as.numeric(gsub(",", ".", .))))
Seleccionamos las variables relevantes excluyendo ICV
para el análisis de conglomerados.
# Seleccionar variables de interés excluyendo "ICV" y "Departamento"
<- datos[, -c(1, 2)] variables_cluster
Estandarizamos las variables para evitar sesgos por diferencias de escala.
# Estandarizar las variables
<- scale(variables_cluster) datos_estandarizados
Utilizamos métodos estadísticos para determinar el número óptimo de clústeres.
# Método del codo
fviz_nbclust(datos_estandarizados, kmeans, method = "wss") +
geom_vline(xintercept = 3, linetype = 2) +
labs(subtitle = "El método del codo")
El método del codo sugiere que el número óptimo de clústeres es 3, ya que a partir de este punto la disminución en la variación interna de los clústeres se vuelve marginal.
Aplicamos el algoritmo K-Means con el número óptimo de clústeres.
set.seed(123)
<- kmeans(datos_estandarizados, centers = 3, nstart = 25)
km_res
# Mostrar resultados del clustering
print(km_res)
## K-means clustering with 3 clusters of sizes 3, 1, 28
##
## Cluster means:
## TURB NBI GENREPRO IDESFISCAL agricultura
## 1 -1.88666056 1.823046 -1.1232476 -2.7749858 -0.1796288
## 2 2.96594744 -2.100848 3.7550424 1.2411300 5.4775706
## 3 0.09621551 -0.120296 -0.0137607 0.2529938 -0.1763816
## Ambiente y Desarrollo Sostenible Ciencia Tecnología Cultura defensa
## 1 -0.3578629 -0.1892923 -0.2396391 -0.1962218
## 2 5.1313325 5.4767317 5.3228964 5.4768147
## 3 -0.1449194 -0.1753162 -0.1644278 -0.1745768
## deportes Educación Nacional Hacienda y Crédito Público
## 1 -0.4032183 -0.2660367 -0.2481191
## 2 4.6983267 5.2833254 5.2365050
## 3 -0.1245954 -0.1601863 -0.1604338
## Inclusión Social y Reconciliación Industria Información Estadística
## 1 -0.1860485 -0.2311568 -0.2050525
## 2 5.4732560 5.3834472 5.4638547
## 3 -0.1755397 -0.1674992 -0.1731678
## Inteligencia Estratégica y Contrainteligencia interior Ley de Justicia
## 1 -0.17677670 -0.1904135 -0.2239949
## 2 -0.17677670 5.4714527 5.4681949
## 3 0.02525381 -0.1750076 -0.1712932
## Minas y Energía Planeación Presidencia de la República Relaciones Exteriores
## 1 -0.2049967 -0.1968878 -0.1806823 -0.1767767
## 2 5.4399753 5.4736069 5.4797221 5.4800776
## 3 -0.1723209 -0.1743908 -0.1763455 -0.1767767
## Salud y Protección Social Servicio Público
## 1 -0.4651440 -0.57978772
## 2 5.1903264 1.23749054
## 3 -0.1355319 0.01792402
## Tecnologías de la Información y las Comunicaciones Trabajo Transporte
## 1 -0.1857205 -0.2823153 -0.1834167
## 2 5.4781463 5.4208402 5.4795480
## 3 -0.1757495 -0.1633534 -0.1760464
## Vivienda, Ciudad y Territorio
## 1 -0.3176166
## 2 4.9298308
## 3 -0.1420350
##
## Clustering vector:
## [1] 1 3 3 3 3 3 3 3 3 3 3 3 3 3 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 3
##
## Within cluster sum of squares by cluster:
## [1] 2.56599 0.00000 131.72271
## (between_SS / total_SS = 84.5 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
Visualizamos los clústeres obtenidos.
# Visualización de los clústeres en dos dimensiones principales
fviz_cluster(km_res, data = datos_estandarizados,
palette = c("#2E9FDF", "#00AFBB", "#E7B800", 'red'),
ellipse.type = "euclid",
star.plot = TRUE,
repel = TRUE,
ggtheme = theme_minimal())
Añadimos la asignación de clúster a los datos originales.
$Cluster <- factor(km_res$cluster) datos
Analizamos cómo varía ICV
entre los clústeres
obtenidos.
# Calcular el ICV promedio por clúster
<- datos %>%
icv_cluster group_by(Cluster) %>%
summarise(ICV_Promedio = mean(ICV, na.rm = TRUE))
# Mostrar resultados
icv_cluster
Resultados:
Gráfico de ICV Promedio por Clúster
# Gráfico de barras de ICV promedio por clúster
ggplot(icv_cluster, aes(x = Cluster, y = ICV_Promedio, fill = Cluster)) +
geom_bar(stat = "identity") +
labs(title = "ICV Promedio por Clúster", x = "Clúster", y = "ICV Promedio") +
theme_minimal()
Calculamos estadísticas descriptivas para cada clúster en las variables utilizadas.
library(dplyr)
# Características promedio de las variables por clúster
<- datos %>%
caracteristicas_cluster group_by(Cluster) %>%
summarise(across(TURB:`Vivienda, Ciudad y Territorio`, mean, na.rm = TRUE))
# Mostrar las primeras variables para simplificar
%>% dplyr::select('Cluster', 'TURB', 'NBI', 'GENREPRO', 'IDESFISCAL') caracteristicas_cluster
Resultados:
Clúster 1:
Clúster 2:
Clúster 3:
Composición: 3 departamentos.
Características:
TURB baja (0.0952):
Baja tasa de
urbanización.
NBI alta (85.6):
Alto porcentaje de Necesidades
Básicas Insatisfechas.
GENREPRO baja (3.24):
Baja generación de recursos
propios.
IDESFISCAL baja (15.8):
Bajo desempeño
fiscal.
ICV Promedio:
37.3 (el más bajo entre los
clústeres).
Interpretación
: Este clúster agrupa departamentos
con altos niveles de pobreza y bajos indicadores económicos,
reflejándose en una baja calidad de vida.
Composición: 1 departamento.
Características:
TURB muy alta (0.998):
Altísima tasa de
urbanización.
NBI baja (9):
Bajo porcentaje de NBI.
GENREPRO alta (40.1):
Alta generación de recursos
propios.
IDESFISCAL alta (70.1):
Alto desempeño
fiscal.
ICV Promedio:
86.9 (el más alto).
Interpretación:
Representa un departamento altamente
desarrollado, con excelentes indicadores económicos y sociales,
resultando en una alta calidad de vida.
Composición: 28 departamentos.
Características:
TURB media (0.464):
Tasa de urbanización
moderada.
NBI media (47.7):
Porcentaje intermedio de
NBI.
GENREPRO moderada (11.6):
Generación de recursos
propios intermedia.
IDESFISCAL alta (56.7):
Buen desempeño
fiscal.
ICV Promedio:
61.5.
Interpretación:
Este clúster agrupa la mayoría de
los departamentos, con indicadores económicos y sociales intermedios,
reflejándose en una calidad de vida moderada.
Relación entre Compra Pública y Calidad de Vida: Los resultados indican que la forma en que los departamentos distribuyen e invierten en compra pública está relacionada con la calidad de vida.
Clúster 1: Departamentos con altos niveles de pobreza y bajos indicadores económicos y fiscales, reflejándose en un bajo ICV.
Clúster 2: Departamento altamente desarrollado, con excelentes indicadores económicos y sociales, resultando en un ICV muy alto.
Clúster 3: La mayoría de los departamentos, con indicadores intermedios y un ICV moderado.
En esta fase, desarrollaremos modelos de aprendizaje supervisado para
predecir el Índice de Calidad de Vida (ICV)
en función de
las variables relacionadas con la compra pública y otros indicadores
socioeconómicos.
El objetivo es construir y evaluar modelos de regresión lineal que expliquen y predigan el ICV de los departamentos, basándose en cómo distribuyen e invierten en compra pública, así como en otros indicadores relevantes.
Excluimos la columna Departamento
y Cluster
ya que es categórica y no numérica, y preparamos el conjunto de datos
para el modelado.
# Quitar la columna "Departamento" y 'Cluster'
<- datos[, -1]
datos_sin_departamento <- datos_sin_departamento[, !names(datos_sin_departamento) %in% "Cluster"] datos_sin_departamento
Ajustamos una regresión lineal utilizando todas las variables disponibles en el conjunto de datos, excepto Departamento.
# Ajustar el modelo de regresión lineal con todas las variables
<- lm(ICV ~ ., data = datos_sin_departamento)
modelo_todas
# Resumen del modelo
summary(modelo_todas)
##
## Call:
## lm(formula = ICV ~ ., data = datos_sin_departamento)
##
## Residuals:
## 1 2 3 4 5 6 7
## 3.431e+00 5.578e-02 -1.539e-01 -5.384e-02 -3.067e-01 -7.573e-02 -1.237e+00
## 8 9 10 11 12 13 14
## -4.197e-02 6.313e-01 -1.201e-01 4.190e-01 1.683e-04 -8.650e-02 6.901e-03
## 15 16 17 18 19 20 21
## 0.000e+00 -2.951e+00 -5.838e-01 -6.041e-01 -8.705e-01 4.517e-02 -3.683e-01
## 22 23 24 25 26 27 28
## 1.778e-01 2.161e-01 -6.442e-01 4.259e-01 -1.981e-01 1.431e-01 1.110e-16
## 29 30 31 32
## 8.630e-01 6.089e-05 -1.452e-01 2.026e+00
##
## Coefficients:
## Estimate Std. Error
## (Intercept) 6.423e+01 1.373e+01
## TURB 4.697e+01 1.576e+01
## NBI -3.181e-01 1.443e-01
## GENREPRO -1.844e-01 5.922e-01
## IDESFISCAL -8.380e-02 1.670e-01
## agricultura 4.246e-06 1.628e-04
## `Ambiente y Desarrollo Sostenible` 4.343e-06 4.322e-06
## `Ciencia Tecnología` 1.326e-04 3.869e-04
## Cultura 3.887e-06 6.436e-05
## defensa -1.007e-05 7.254e-06
## deportes 4.424e-06 1.702e-05
## `Educación Nacional` -2.568e-05 1.520e-05
## `Hacienda y Crédito Público` 3.663e-05 2.649e-05
## `Inclusión Social y Reconciliación` -5.174e-06 7.557e-05
## Industria 1.503e-05 2.918e-05
## `Información Estadística` -1.750e-04 5.829e-04
## `Inteligencia Estratégica y Contrainteligencia` -9.787e-02 1.201e-01
## interior 4.154e-05 4.974e-05
## `Ley de Justicia` 8.591e-06 1.310e-05
## `Minas y Energía` -7.586e-06 9.831e-06
## Planeación 8.083e-06 1.918e-05
## `Presidencia de la República` -2.084e-04 3.351e-04
## `Relaciones Exteriores` -1.399e-03 2.412e-03
## `Salud y Protección Social` -4.722e-07 2.123e-06
## `Servicio Público` 1.402e-06 1.010e-06
## `Tecnologías de la Información y las Comunicaciones` 2.783e-04 4.326e-04
## Trabajo -3.421e-05 2.454e-05
## Transporte 2.610e-05 1.179e-05
## `Vivienda, Ciudad y Territorio` -1.010e-05 1.792e-05
## t value Pr(>|t|)
## (Intercept) 4.677 0.0185 *
## TURB 2.980 0.0586 .
## NBI -2.205 0.1147
## GENREPRO -0.311 0.7759
## IDESFISCAL -0.502 0.6503
## agricultura 0.026 0.9808
## `Ambiente y Desarrollo Sostenible` 1.005 0.3891
## `Ciencia Tecnología` 0.343 0.7544
## Cultura 0.060 0.9556
## defensa -1.389 0.2591
## deportes 0.260 0.8117
## `Educación Nacional` -1.690 0.1896
## `Hacienda y Crédito Público` 1.383 0.2606
## `Inclusión Social y Reconciliación` -0.068 0.9497
## Industria 0.515 0.6420
## `Información Estadística` -0.300 0.7836
## `Inteligencia Estratégica y Contrainteligencia` -0.815 0.4747
## interior 0.835 0.4650
## `Ley de Justicia` 0.656 0.5587
## `Minas y Energía` -0.772 0.4965
## Planeación 0.421 0.7019
## `Presidencia de la República` -0.622 0.5782
## `Relaciones Exteriores` -0.580 0.6027
## `Salud y Protección Social` -0.222 0.8382
## `Servicio Público` 1.389 0.2590
## `Tecnologías de la Información y las Comunicaciones` 0.643 0.5658
## Trabajo -1.394 0.2576
## Transporte 2.214 0.1137
## `Vivienda, Ciudad y Territorio` -0.564 0.6123
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.159 on 3 degrees of freedom
## Multiple R-squared: 0.9918, Adjusted R-squared: 0.9157
## F-statistic: 13.02 on 28 and 3 DF, p-value: 0.02798
R-cuadrado:
0.9918, indicando que el modelo explica
el 99.18% de la variabilidad en el ICV.
R-cuadrado ajustado:
0.9157, lo que sigue siendo
alto.
Grados de libertad residuales:
Solo 3, sugiriendo un
posible sobreajuste.
Conclusión:
Aunque el modelo parece ajustarse bien,
la cantidad de variables en comparación con el número de observaciones
puede causar problemas de sobreajuste y multicolinealidad.
Este modelo utiliza solo las variables a partir de
agricultura
, que representan inversiones en diferentes
sectores.
# Encontrar el índice de la columna "agricultura"
<- which(names(datos_sin_departamento) == "agricultura")
indice_agricultura
# Seleccionar las columnas desde "agricultura" en adelante, incluyendo ICV
<- datos_sin_departamento[, c("ICV", names(datos_sin_departamento)[indice_agricultura:ncol(datos_sin_departamento)])]
datos_agricultura
# Ajustar el modelo de regresión lineal
<- lm(ICV ~ ., data = datos_agricultura)
modelo_agricultura
# Resumen del modelo
summary(modelo_agricultura)
##
## Call:
## lm(formula = ICV ~ ., data = datos_agricultura)
##
## Residuals:
## Min 1Q Median 3Q Max
## -23.294 -2.894 0.000 1.667 18.577
##
## Coefficients:
## Estimate Std. Error
## (Intercept) 4.675e+01 1.460e+01
## agricultura -3.212e-05 5.495e-04
## `Ambiente y Desarrollo Sostenible` -1.236e-05 1.813e-05
## `Ciencia Tecnología` -1.018e-03 1.514e-03
## Cultura -9.511e-05 1.959e-04
## defensa 7.660e-06 2.976e-05
## deportes -4.853e-05 6.541e-05
## `Educación Nacional` 2.771e-05 5.774e-05
## `Hacienda y Crédito Público` -4.222e-05 9.768e-05
## `Inclusión Social y Reconciliación` 1.605e-04 3.125e-04
## Industria 1.075e-04 1.085e-04
## `Información Estadística` -1.250e-04 1.810e-03
## `Inteligencia Estratégica y Contrainteligencia` 2.149e-01 5.409e-01
## interior -1.942e-04 1.856e-04
## `Ley de Justicia` -1.990e-05 5.941e-05
## `Minas y Energía` 1.969e-05 3.310e-05
## Planeación 2.649e-05 6.522e-05
## `Presidencia de la República` -4.133e-04 1.207e-03
## `Relaciones Exteriores` 1.641e-03 7.333e-03
## `Salud y Protección Social` 4.140e-06 9.365e-06
## `Servicio Público` 1.783e-06 4.169e-06
## `Tecnologías de la Información y las Comunicaciones` -2.603e-04 1.369e-03
## Trabajo 6.725e-05 9.806e-05
## Transporte -1.327e-05 4.452e-05
## `Vivienda, Ciudad y Territorio` 1.205e-05 6.366e-05
## t value Pr(>|t|)
## (Intercept) 3.202 0.015 *
## agricultura -0.058 0.955
## `Ambiente y Desarrollo Sostenible` -0.682 0.517
## `Ciencia Tecnología` -0.672 0.523
## Cultura -0.486 0.642
## defensa 0.257 0.804
## deportes -0.742 0.482
## `Educación Nacional` 0.480 0.646
## `Hacienda y Crédito Público` -0.432 0.679
## `Inclusión Social y Reconciliación` 0.513 0.623
## Industria 0.991 0.355
## `Información Estadística` -0.069 0.947
## `Inteligencia Estratégica y Contrainteligencia` 0.397 0.703
## interior -1.046 0.330
## `Ley de Justicia` -0.335 0.747
## `Minas y Energía` 0.595 0.571
## Planeación 0.406 0.697
## `Presidencia de la República` -0.342 0.742
## `Relaciones Exteriores` 0.224 0.829
## `Salud y Protección Social` 0.442 0.672
## `Servicio Público` 0.428 0.682
## `Tecnologías de la Información y las Comunicaciones` -0.190 0.855
## Trabajo 0.686 0.515
## Transporte -0.298 0.774
## `Vivienda, Ciudad y Territorio` 0.189 0.855
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 15.24 on 7 degrees of freedom
## Multiple R-squared: 0.5571, Adjusted R-squared: -0.9615
## F-statistic: 0.3669 on 24 and 7 DF, p-value: 0.9687
R-cuadrado:
0.5571, indicando que el modelo explica
el 55.71% de la variabilidad en el ICV.
R-cuadrado ajustado:
-0.9615, negativo, lo que
indica un mal ajuste del modelo.
P-valor del modelo:
0.9687, no es estadísticamente
significativo.
Conclusión:
Este modelo no es adecuado para predecir
el ICV debido a su bajo rendimiento y falta de significancia
estadística.
Aplicamos la técnica de selección paso a paso (stepwise)
utilizando el criterio de Akaike (AIC)
para identificar el
mejor subconjunto de variables.
library(MASS) # Para la función stepAIC
# Ajustar el modelo inicial con todas las variables
<- lm(ICV ~ ., data = datos_sin_departamento)
modelo_inicial
# Aplicar selección paso a paso usando AIC
<- stepAIC(modelo_inicial, direction = "both", trace = FALSE)
modelo_stepwise
# Mostrar el resumen del modelo
summary(modelo_stepwise)
##
## Call:
## lm(formula = ICV ~ TURB + NBI + IDESFISCAL + `Ambiente y Desarrollo Sostenible` +
## defensa + `Educación Nacional` + `Hacienda y Crédito Público` +
## Industria + `Información Estadística` + `Inteligencia Estratégica y Contrainteligencia` +
## interior + `Ley de Justicia` + `Minas y Energía` + Planeación +
## `Presidencia de la República` + `Relaciones Exteriores` +
## `Servicio Público` + `Tecnologías de la Información y las Comunicaciones` +
## Trabajo + Transporte + `Vivienda, Ciudad y Territorio`, data = datos_sin_departamento)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.8977 -0.2088 -0.0181 0.0959 3.7171
##
## Coefficients:
## Estimate Std. Error
## (Intercept) 5.981e+01 3.671e+00
## TURB 4.759e+01 6.226e+00
## NBI -2.750e-01 3.552e-02
## IDESFISCAL -9.033e-02 6.611e-02
## `Ambiente y Desarrollo Sostenible` 4.154e-06 1.735e-06
## defensa -9.837e-06 2.560e-06
## `Educación Nacional` -2.368e-05 4.442e-06
## `Hacienda y Crédito Público` 3.454e-05 6.391e-06
## Industria 1.921e-05 6.742e-06
## `Información Estadística` -1.913e-04 5.694e-05
## `Inteligencia Estratégica y Contrainteligencia` -8.747e-02 6.389e-02
## interior 2.683e-05 1.775e-05
## `Ley de Justicia` 5.550e-06 5.404e-06
## `Minas y Energía` -7.519e-06 2.757e-06
## Planeación 7.030e-06 7.772e-06
## `Presidencia de la República` -2.884e-04 1.065e-04
## `Relaciones Exteriores` -1.138e-03 3.743e-04
## `Servicio Público` 1.607e-06 4.476e-07
## `Tecnologías de la Información y las Comunicaciones` 2.771e-04 7.437e-05
## Trabajo -3.160e-05 8.641e-06
## Transporte 2.563e-05 5.935e-06
## `Vivienda, Ciudad y Territorio` -1.071e-05 2.941e-06
## t value Pr(>|t|)
## (Intercept) 16.294 1.57e-08 ***
## TURB 7.645 1.75e-05 ***
## NBI -7.741 1.57e-05 ***
## IDESFISCAL -1.366 0.201791
## `Ambiente y Desarrollo Sostenible` 2.394 0.037673 *
## defensa -3.842 0.003252 **
## `Educación Nacional` -5.331 0.000333 ***
## `Hacienda y Crédito Público` 5.405 0.000299 ***
## Industria 2.849 0.017274 *
## `Información Estadística` -3.360 0.007241 **
## `Inteligencia Estratégica y Contrainteligencia` -1.369 0.200946
## interior 1.512 0.161576
## `Ley de Justicia` 1.027 0.328626
## `Minas y Energía` -2.727 0.021290 *
## Planeación 0.905 0.386976
## `Presidencia de la República` -2.708 0.022005 *
## `Relaciones Exteriores` -3.039 0.012476 *
## `Servicio Público` 3.591 0.004918 **
## `Tecnologías de la Información y las Comunicaciones` 3.726 0.003934 **
## Trabajo -3.657 0.004412 **
## Transporte 4.318 0.001518 **
## `Vivienda, Ciudad y Territorio` -3.641 0.004532 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.821 on 10 degrees of freedom
## Multiple R-squared: 0.991, Adjusted R-squared: 0.972
## F-statistic: 52.23 on 21 and 10 DF, p-value: 1.379e-07
R-cuadrado ajustado:
0.972, indicando que el modelo
explica el 97.2% de la variabilidad en el ICV.
Variables seleccionadas:
El modelo ha identificado
las variables más significativas.
Multicolinealidad:
Reducida en comparación con el
Modelo 1, mejorando la interpretabilidad.
Conclusión:
El modelo stepwise proporciona un
equilibrio entre ajuste y simplicidad.
Extraemos los coeficientes y sus valores p para evaluar la significancia de cada variable.
library(tibble)
# Obtener los coeficientes del modelo y sus valores p
<- summary(modelo_stepwise)$coefficients
importancia_variables
# Crear un data frame ordenado por valor p
<- as.data.frame(importancia_variables) %>%
importancia_df rownames_to_column(var = 'Variable') %>%
rename(Coeficiente = Estimate, `Error Estándar` = `Std. Error`, `Valor t` = `t value`, `Valor p` = `Pr(>|t|)`) %>%
arrange(`Valor p`)
# Mostrar las variables ordenadas por significancia
library(knitr)
kable(importancia_df, digits = 3, caption = "Importancia de las Variables en el Modelo Stepwise (ordenadas por Valor p)")
Variable | Coeficiente | Error Estándar | Valor t | Valor p |
---|---|---|---|---|
(Intercept) | 59.812 | 3.671 | 16.294 | 0.000 |
NBI | -0.275 | 0.036 | -7.741 | 0.000 |
TURB | 47.595 | 6.226 | 7.645 | 0.000 |
Hacienda y Crédito Público |
0.000 | 0.000 | 5.405 | 0.000 |
Educación Nacional |
0.000 | 0.000 | -5.331 | 0.000 |
Transporte | 0.000 | 0.000 | 4.318 | 0.002 |
defensa | 0.000 | 0.000 | -3.842 | 0.003 |
Tecnologías de la Información y las Comunicaciones |
0.000 | 0.000 | 3.726 | 0.004 |
Trabajo | 0.000 | 0.000 | -3.657 | 0.004 |
Vivienda, Ciudad y Territorio |
0.000 | 0.000 | -3.641 | 0.005 |
Servicio Público |
0.000 | 0.000 | 3.591 | 0.005 |
Información Estadística |
0.000 | 0.000 | -3.360 | 0.007 |
Relaciones Exteriores |
-0.001 | 0.000 | -3.039 | 0.012 |
Industria | 0.000 | 0.000 | 2.849 | 0.017 |
Minas y Energía |
0.000 | 0.000 | -2.727 | 0.021 |
Presidencia de la República |
0.000 | 0.000 | -2.708 | 0.022 |
Ambiente y Desarrollo Sostenible |
0.000 | 0.000 | 2.394 | 0.038 |
interior | 0.000 | 0.000 | 1.512 | 0.162 |
Inteligencia Estratégica y Contrainteligencia |
-0.087 | 0.064 | -1.369 | 0.201 |
IDESFISCAL | -0.090 | 0.066 | -1.366 | 0.202 |
Ley de Justicia |
0.000 | 0.000 | 1.027 | 0.329 |
Planeación | 0.000 | 0.000 | 0.905 | 0.387 |
Variables con significancia alta (p-valor < 0.01):
TURB
, NBI
,
Educación Nacional
,
Hacienda y Crédito Público
, Industria
,
Información Estadística
, Servicio Público
,
Tecnologías de la Información y las Comunicaciones
,
Trabajo
, Transporte
, Vivienda
,
Ciudad y Territorio
.
Variables con significancia moderada (p-valor < 0.05):
Ambiente y Desarrollo Sostenible
,
defensa
, Minas y Energía
,
Presidencia de la República
,
Relaciones Exteriores
.
Variables insignificantes (p-valor > 0.05):
IDESFISCAL
,
Inteligencia Estratégica y Contrainteligencia
,
interior
, Ley de Justicia
,
Planeación
.
Eliminamos variables insignificantes para simplificar el modelo sin perder capacidad predictiva.
# Crear una fórmula con las variables significativas
<- importancia_df %>%
variables_significativas filter(`Valor p` < 0.05, Variable != "(Intercept)") %>%
pull(Variable)
<- as.formula(paste("ICV ~", paste(variables_significativas, collapse = " + ")))
formula_refinada
# Ajustar el modelo refinado
<- lm(formula_refinada, data = datos_sin_departamento)
modelo_refinado
# Resumen del modelo refinado
summary(modelo_refinado)
##
## Call:
## lm(formula = formula_refinada, data = datos_sin_departamento)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.4221 -0.6251 -0.0237 0.6867 4.1890
##
## Coefficients:
## Estimate Std. Error
## (Intercept) 5.941e+01 2.670e+00
## NBI -2.842e-01 2.828e-02
## TURB 3.763e+01 3.348e+00
## `Hacienda y Crédito Público` 2.671e-05 4.960e-06
## `Educación Nacional` -1.750e-05 3.188e-06
## Transporte 1.870e-05 4.465e-06
## defensa -8.396e-06 2.286e-06
## `Tecnologías de la Información y las Comunicaciones` 2.010e-04 5.898e-05
## Trabajo -2.154e-05 6.682e-06
## `Vivienda, Ciudad y Territorio` -8.952e-06 2.443e-06
## `Servicio Público` 1.306e-06 3.756e-07
## `Información Estadística` -1.333e-04 4.313e-05
## `Relaciones Exteriores` -6.624e-04 2.866e-04
## Industria 2.046e-05 6.236e-06
## `Minas y Energía` -6.731e-06 2.624e-06
## `Presidencia de la República` -2.337e-04 9.235e-05
## `Ambiente y Desarrollo Sostenible` 2.683e-06 1.512e-06
## t value Pr(>|t|)
## (Intercept) 22.252 6.69e-13 ***
## NBI -10.051 4.67e-08 ***
## TURB 11.240 1.05e-08 ***
## `Hacienda y Crédito Público` 5.385 7.58e-05 ***
## `Educación Nacional` -5.490 6.22e-05 ***
## Transporte 4.188 0.000792 ***
## defensa -3.673 0.002259 **
## `Tecnologías de la Información y las Comunicaciones` 3.407 0.003902 **
## Trabajo -3.223 0.005689 **
## `Vivienda, Ciudad y Territorio` -3.665 0.002300 **
## `Servicio Público` 3.478 0.003374 **
## `Información Estadística` -3.090 0.007462 **
## `Relaciones Exteriores` -2.311 0.035433 *
## Industria 3.281 0.005055 **
## `Minas y Energía` -2.565 0.021531 *
## `Presidencia de la República` -2.531 0.023072 *
## `Ambiente y Desarrollo Sostenible` 1.774 0.096374 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.797 on 15 degrees of freedom
## Multiple R-squared: 0.9868, Adjusted R-squared: 0.9727
## F-statistic: 70.12 on 16 and 15 DF, p-value: 3.487e-11
R-cuadrado ajustado:
Similar al modelo stepwise,
manteniendo un buen nivel de explicación de la variabilidad del
ICV.
Simplicidad:
Modelo más sencillo con solo las
variables significativas.
Conclusión:
El modelo refinado es más interpretable
y práctico para aplicaciones futuras.
Variables Clave:
La tasa de urbanización
(TURB)
, necesidades básicas insatisfechas
(NBI)
, y la inversión en sectores como educación, hacienda,
industria, y transporte son determinantes en la calidad de
vida.
Modelo Refinado:
Proporciona un equilibrio entre
simplicidad y poder predictivo.
Aplicabilidad:
Los resultados pueden orientar
políticas públicas y estrategias de inversión para mejorar el ICV en los
departamentos.
En esta fase, desarrollaremos un modelo predictivo de series de
tiempo para la compra pública total utilizando las
columnas Fecha.de.Inicio.del.Contrato
y
Valor.del.Contrato
de nuestro conjunto de
datos compra_publica
. El objetivo es conocer la tendencia
para los próximos periodos y simular escenarios futuros de inversión en
compra pública a nivel departamental y municipal, teniendo como
principio la mejora de la calidad de vida de los ciudadanos.
El análisis de series de tiempo de la compra pública total nos permitirá entender su comportamiento histórico y pronosticar su tendencia futura. Al integrar este modelo con los resultados obtenidos en la Fase 2, podremos evaluar cómo los cambios proyectados en la inversión pública podrían influir en el Índice de Calidad de Vida (ICV).
En este caso, disponemos de datos históricos de la compra pública total de Santiago de Cali. Estos datos deben estar en formato de serie de tiempo, con observaciones periódicas (mensuales, trimestrales, anuales, etc.).
# Importar datos de compra pública total
<- read.csv("secop_cali.csv")
compra_publica <- compra_publica
compra_publica_fase2 # Verificar los datos
head(compra_publica, 20)
# Visualizar algunas filas de las columnas relevantes
head(compra_publica[, c('Fecha.de.Inicio.del.Contrato', 'Valor.del.Contrato')])
Es importante asegurarnos de que no existan valores faltantes o erróneos en las columnas que utilizaremos.
# Revisar tipos de datos
class(compra_publica$Valor.del.Contrato)
## [1] "numeric"
class(compra_publica$Fecha.de.Inicio.del.Contrato)
## [1] "character"
# Verificar valores faltantes en 'Fecha.de.Inicio.del.Contrato'
<- sum(compra_publica$Fecha.de.Inicio.del.Contrato == "" | is.na(compra_publica$Fecha.de.Inicio.del.Contrato))
total_faltantes_fecha <- round((total_faltantes_fecha / nrow(compra_publica)) * 100, 3)
porcentaje_faltantes_fecha
# Verificar valores faltantes en 'Valor.del.Contrato'
<- sum(is.na(compra_publica$Valor.del.Contrato))
total_faltantes_valor <- round((total_faltantes_valor / nrow(compra_publica)) * 100, 4)
porcentaje_faltantes_valor
# Mostrar resultados
cat("El total de datos faltantes en la columna 'Fecha.de.Inicio.del.Contrato' es", total_faltantes_fecha, "que equivale a un", porcentaje_faltantes_fecha, "%\n")
## El total de datos faltantes en la columna 'Fecha.de.Inicio.del.Contrato' es 12633 que equivale a un 4.867 %
cat("El total de datos faltantes en la columna 'Valor.del.Contrato' es", total_faltantes_valor, "que equivale a un", porcentaje_faltantes_valor, "%\n")
## El total de datos faltantes en la columna 'Valor.del.Contrato' es 0 que equivale a un 0 %
Eliminaremos registros con fechas vacías o valores NA en las columnas relevantes.
# Eliminar registros con fechas vacías o NA
<- compra_publica %>%
compra_publica filter(Fecha.de.Inicio.del.Contrato != '' & !is.na(Fecha.de.Inicio.del.Contrato))
# Verificar que ya no hay fechas vacías
sum(compra_publica$Fecha.de.Inicio.del.Contrato == '')
## [1] 0
sum(is.na(compra_publica$Fecha.de.Inicio.del.Contrato))
## [1] 0
Convertimos la columna de fechas al formato Date y eliminamos fechas inválidas.
# Convertir la fecha al formato Date
$Fecha <- as.Date(compra_publica$Fecha.de.Inicio.del.Contrato, format = "%m/%d/%Y")
compra_publica
# Verificar conversiones fallidas
<- sum(is.na(compra_publica$Fecha))
total_fechas_invalidas cat("Total de fechas inválidas después de la conversión:", total_fechas_invalidas, "\n")
## Total de fechas inválidas después de la conversión: 0
# Eliminar registros con fechas inválidas
<- compra_publica %>%
compra_publica filter(!is.na(Fecha))
Creamos variables de año y mes y agregamos los datos por estos periodos.
library(lubridate)
library(dplyr)
# Crear variables de año y mes y agrupar por periodo
<- compra_publica %>%
compra_publica mutate(Año = year(Fecha), Mes = month(Fecha)) %>%
group_by(Año, Mes) %>%
summarise(Compra_Publica_Total = sum(Valor.del.Contrato, na.rm = TRUE)) %>%
ungroup()
# Crear columna de fecha
<- compra_publica %>%
compra_publica mutate(Fecha = as.Date(paste(Año, Mes, "01", sep = "-")))
# Filtrar años no deseados
<- compra_publica %>%
compra_publica filter(!(year(Fecha) %in% c(2016, 2017, 2024, 2025)))
# Ordenar los datos por fecha
<- compra_publica %>%
compra_publica arrange(Fecha)
# Verificar los datos agregados
head(compra_publica)
Como los datos presentan varianza heterogénea (heterocedasticidad), además de valores muy altos y otros bajos en el valor total de los contratos, aplicamos una transformación logarítmica para estabilizar la varianza.
library(ggplot2)
library(forecast)
library(tseries)
# Transformación logarítmica
$Log_Compra_Publica_Total <- log(compra_publica$Compra_Publica_Total + 1)
compra_publica
# Crear serie de tiempo logarítmica
<- ts(compra_publica$Log_Compra_Publica_Total,
log_ts_compra_publica start = c(min(compra_publica$Año), min(compra_publica$Mes)),
frequency = 12)
# Graficar la serie de tiempo logarítmica
autoplot(log_ts_compra_publica) +
labs(title = "Serie de Tiempo de la Compra Pública Total (Logarítmica)",
x = "Tiempo",
y = "Log(Valor del Contrato)") +
theme_minimal()
Diferenciamos la serie para convertirla en estacionaria y eliminar tendencias.
# Diferenciación
<- diff(log_ts_compra_publica)
log_ts_diff
# Graficar la serie diferenciada
autoplot(log_ts_diff) +
labs(title = "Serie Diferenciada (Log)",
x = "Tiempo",
y = "Diferencias Logarítmicas") +
theme_minimal()
# Prueba ADF
<- adf.test(log_ts_diff, alternative = "stationary")
adf_test_log_diff
# Mostrar resultados
print(adf_test_log_diff)
##
## Augmented Dickey-Fuller Test
##
## data: log_ts_diff
## Dickey-Fuller = -5.8697, Lag order = 4, p-value = 0.01
## alternative hypothesis: stationary
Valor del estadístico de Dickey-Fuller:
El valor del estadístico es -5.8697.
Este valor debe compararse con los valores críticos de la prueba para determinar si la serie es estacionaria. Dado que este valor es muy negativo (menor que valores críticos típicos como -3.43 para un nivel de significancia del 5%), hay evidencia fuerte para rechazar la hipótesis nula.
Hipótesis de la prueba:
Hipótesis nula (\(H0\)): La serie de tiempo tiene una raíz unitaria (es decir, no es estacionaria).
Hipótesis alternativa (\(Ha\)): La serie de tiempo es estacionaria.
p-value:
El \(p-value\) reportado es 0.01 (o más pequeño, como indica la advertencia en el mensaje).
Un \(p-value\) menor que \(0.05\) implica que podemos rechazar la hipótesis nula con un nivel de confianza del 95%. Esto significa que la serie es estacionaria.
Utilizamos auto.arima
para encontrar el mejor modelo
ARIMA que se ajuste a nuestros datos.
# Ajustar modelo ARIMA
<- auto.arima(log_ts_compra_publica)
modelo_arima_log
# Resumen del modelo
summary(modelo_arima_log)
## Series: log_ts_compra_publica
## ARIMA(0,1,2)(0,0,1)[12] with drift
##
## Coefficients:
## ma1 ma2 sma1 drift
## -0.5340 -0.2469 0.2821 0.0453
## s.e. 0.1085 0.1055 0.1372 0.0228
##
## sigma^2 = 0.4514: log likelihood = -71.33
## AIC=152.66 AICc=153.58 BIC=163.97
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set -0.02244414 0.6481249 0.4766577 -0.141787 1.880484 0.5210919
## ACF1
## Training set 0.08036908
El modelo ajustado es un ARIMA(0,1,2)(0,0,1)[12]
con
drift, lo que significa que incluye diferenciación para estacionariedad,
componentes de promedio móvil (MA) y un término estacional anual.
Resumen clave:
Coeficientes significativos
: Los términos MA y
estacional capturan patrones no aleatorios en los datos.
Buen ajuste
: Las métricas \(RMSE=0.648\), \(MAPE=1.88%\), y \(ME≈0\) indican alta precisión y sin
sesgo.
Predicciones confiables
: El modelo captura la
tendencia (drift = 0.0453) y patrones estacionales, siendo adecuado para
pronósticos futuros.
Con un error porcentual bajo y residuos sin autocorrelación significativa (\(ACF1=0.08\)), el modelo es sólido para predicción.
Es importante verificar que los residuos del modelo se comporten como ruido blanco.
# Verificar residuos
checkresiduals(modelo_arima_log)
##
## Ljung-Box test
##
## data: Residuals from ARIMA(0,1,2)(0,0,1)[12] with drift
## Q* = 15.236, df = 11, p-value = 0.172
##
## Model df: 3. Total lags used: 14
Gráfica de residuos a lo largo del tiempo:
ACF de los residuos:
La mayoría de las autocorrelaciones están dentro de las bandas de confianza (líneas azules). Esto sugiere que los residuos no tienen autocorrelaciones significativas, lo cual es un buen indicador de que el modelo ha capturado las dependencias temporales correctamente.
Distribución de los residuos:
Prueba de Ljung-Box:
El valor \(Q^∗ =15.236\), grados de libertad (\(df=11\)) y p-value = 0.172.
Dado que el \(p-value\) es mayor que 0.05, no hay evidencia significativa para rechazar la hipótesis nula. Esto indica que los residuos son ruido blanco (independientes y sin autocorrelación significativa).
Conclusión: El modelo ARIMA(0,1,2)(0,0,1)[12] con drift ajusta bien los datos. Los residuos no muestran patrones significativos y se comportan como ruido blanco, lo que valida la adecuación del modelo para predicción.
Utilizamos el modelo ajustado para pronosticar la compra pública total para los próximos 12 meses.
# Pronóstico final utilizando todos los datos
<- auto.arima(log_ts_compra_publica)
final_model <- forecast(final_model, h = 12)
final_forecast
# Mostrar el pronóstico
print(final_forecast)
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## Jan 2024 26.56025 25.69921 27.42129 25.24341 27.87710
## Feb 2024 26.96808 26.01814 27.91801 25.51528 28.42087
## Mar 2024 26.73919 25.77071 27.70767 25.25803 28.22035
## Apr 2024 26.97570 25.98903 27.96238 25.46672 28.48469
## May 2024 26.94624 25.94170 27.95078 25.40993 28.48255
## Jun 2024 27.06282 26.04073 28.08492 25.49966 28.62598
## Jul 2024 26.87776 25.83840 27.91711 25.28820 28.46731
## Aug 2024 26.77791 25.72158 27.83424 25.16239 28.39342
## Sep 2024 27.02471 25.95167 28.09774 25.38364 28.66578
## Oct 2024 26.94414 25.85465 28.03363 25.27791 28.61037
## Nov 2024 26.97345 25.86775 28.07914 25.28243 28.66447
## Dec 2024 26.98315 25.86148 28.10482 25.26770 28.69859
# Graficar el pronóstico
autoplot(final_forecast) +
labs(title = "Pronóstico de la Compra Pública Total (Logarítmica)",
x = "Tiempo",
y = "Log(Valor del Contrato)") +
theme_minimal()
El modelo pronostica una ligera tendencia ascendente en el valor logarítmico de la compra pública total para los próximos 12 meses.
Los intervalos de confianza indican la incertidumbre asociada con las predicciones.
A medida que avanzamos en el tiempo, estos intervalos se amplían ligeramente.
A continuación, se dejan los links a las bases de datos utilizadas en este análisis: