Planeación estratégica basada en analítica prescriptiva
Grupo 503
Profesor Rodolfo Miguel Gameros
Equipo 7:
A00833113 - Avril Lobato
A01771127 - Lesly Darian Romero Vázquez
A00831105 - Jazmín del Carmen Cortez Mendoza
A01284611 - Lisset Hernández
En el contexto de la clusterización geoespacial, es fundamental comprender las herramientas que permiten agrupar puntos según su proximidad. Las principales dos representaciones clave son la matriz de distancias y la matriz de adyacencias. La matriz de distancias cuantifica las diferencias espaciales entre cada par de ubicaciones, usualmente con métricas como la distancia euclidiana, mientras que la matriz de adyacencias indica conexiones directas entre puntos cercanos, comúnmente usada en redes espaciales.
Cabe destacar que se emplean distintos métodos de clusterización jerárquica para agrupar dichos puntos geográficos:
Vinculación simple: une grupos con la menor distancia entre puntos.
Vinculación completa: considera la mayor distancia entre elementos de distintos grupos.
Método de centroides: calcula distancias entre los centros (promedios) de los grupos.
Ward.D2: agrupa minimizando la varianza interna, ideal para formar clusters compactos y homogéneos.
El propósito de esta actividad es aplicar estos conceptos usando el algoritmo kNN y dendrogramas para explorar distintas cantidades de agrupaciones. En este caso, se trabajará con una matriz de distancias y el método de clusterización Ward.D2 para identificar agrupamientos significativos dentro del espacio geográfico analizado.
Se utilizará la base de datos referente a los estados de México y diferentes factores socioeconómicos. A continuación, se realiza la lectura de Datos Socioeconmómicos
## state year state_id crime_rate unemployment employment
## 1 Aguascalientes 2021 1057 6.75 0.04 0.97
## 2 Baja California 2021 2304 84.67 0.01 0.98
## 3 Baja California Sur 2021 2327 8.52 0.03 0.97
## 4 Campeche 2021 1086 9.22 0.02 0.98
## 5 Chiapas 2021 1182 10.01 0.05 0.97
## 6 Chihuahua 2021 888 71.98 0.04 0.97
## business_activity real_wage real_ave_month_income pop_density lq_primary
## 1 -1.90 361.02 5641.67 261.21 0.16
## 2 2.47 388.22 7599.62 53.19 0.47
## 3 -2.12 345.57 8660.90 11.27 0.73
## 4 -2.44 414.48 5357.29 16.42 0.73
## 5 -2.41 312.37 6581.28 77.16 1.56
## 6 -1.25 362.93 5708.75 15.30 0.64
## lq_secondary lq_tertiary new_fdi_real_mxn log_new_fdi_real_mxn region_a
## 1 1.24 1.00 1270.03 3.10 Bajio
## 2 1.62 0.86 20407.81 4.31 Norte
## 3 0.51 1.13 19022.55 4.28 Occidente
## 4 0.78 1.06 2390.64 3.38 Sur
## 5 0.88 0.99 189.58 2.28 Sur
## 6 1.97 0.80 7153.63 3.86 Norte
## region_b
## 1 2
## 2 3
## 3 4
## 4 5
## 5 5
## 6 3
## Rows: 32
## Columns: 17
## $ state <chr> "Aguascalientes", "Baja California", "Baja Calif…
## $ year <int> 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, …
## $ state_id <int> 1057, 2304, 2327, 1086, 1182, 888, 1114, 933, 11…
## $ crime_rate <dbl> 6.75, 84.67, 8.52, 9.22, 10.01, 71.98, 11.58, 4.…
## $ unemployment <dbl> 0.04, 0.01, 0.03, 0.02, 0.05, 0.04, 0.06, 0.04, …
## $ employment <dbl> 0.97, 0.98, 0.97, 0.98, 0.97, 0.97, 0.94, 0.94, …
## $ business_activity <dbl> -1.90, 2.47, -2.12, -2.44, -2.41, -1.25, -2.08, …
## $ real_wage <dbl> 361.02, 388.22, 345.57, 414.48, 312.37, 362.93, …
## $ real_ave_month_income <dbl> 5641.67, 7599.62, 8660.90, 5357.29, 6581.28, 570…
## $ pop_density <dbl> 261.21, 53.19, 11.27, 16.42, 77.16, 15.30, 6195.…
## $ lq_primary <dbl> 0.16, 0.47, 0.73, 0.73, 1.56, 0.64, 0.03, 0.17, …
## $ lq_secondary <dbl> 1.24, 1.62, 0.51, 0.78, 0.88, 1.97, 0.58, 1.55, …
## $ lq_tertiary <dbl> 1.00, 0.86, 1.13, 1.06, 0.99, 0.80, 1.14, 0.93, …
## $ new_fdi_real_mxn <dbl> 1270.03, 20407.81, 19022.55, 2390.64, 189.58, 71…
## $ log_new_fdi_real_mxn <dbl> 3.10, 4.31, 4.28, 3.38, 2.28, 3.86, 4.54, 3.80, …
## $ region_a <chr> "Bajio", "Norte", "Occidente", "Sur", "Sur", "No…
## $ region_b <int> 2, 3, 4, 5, 5, 3, 1, 3, 4, 4, 2, 5, 1, 4, 1, 4, …
Seguidamente, se leen los archivos de las formas geométricas (geocercas) que determinarán los mapas a realizar después para visualizar los datos.
## Reading layer `mexlatlong' from data source
## `C:\Users\AVRIL\Downloads\mexlatlong.shp' using driver `ESRI Shapefile'
## Simple feature collection with 32 features and 19 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -118.4042 ymin: 14.55055 xmax: -86.73862 ymax: 32.71846
## CRS: NA
## [1] "sf" "data.frame"
Se unifican dichas bases en una sola para posteriormente cambiar el tipo de objeto de dicha base a SPDF (SpatialPolygonsDataFrame).
Se segmenta la base de datos para que solamente contenga las variables socioeconómicas a utilizar, las cuales son crime_rate, real_ave_month_income, employment y lq_tertiary.
Crime rate: Existen dos perfiles de unidades territoriales — unas con muy baja criminalidad y otras con valores elevados.
Employment: La tasa de empleo es alta y muy homogénea, con muy pocos valores atípicos.
Lq tertiary: La concentración del sector terciario es, en general, cercana al promedio (cociente ≈ 1), pero hay unidades con infra/supra-representación ligeras.
real_ave_month_income: Ingresos mensuales reales con variabilidad moderada y leve sesgo positivo.
Los principales hallazgos son que:
employment y lq_tertiary muestran alta homogeneidad y poca dispersión.
crime_rate e income presentan mayor variabilidad y asimetría; especialmente crime_rate, con varios valores extremos.
vars_equipo7 <- c("state_id", "crime_rate", "real_ave_month_income", "employment", "lq_tertiary")
mx_selected <- mx_state[ , vars_equipo7]
mx_selected[ , -1] <- scale(mx_selected[ , -1])
# Verifica la estructura de los datos escalados
str(mx_selected)
## 'data.frame': 32 obs. of 5 variables:
## $ state_id : int 1057 2304 2327 1086 1182 888 1114 933 1111 1004 ...
## $ crime_rate : num -0.84 1.959 -0.776 -0.751 -0.723 ...
## $ real_ave_month_income: num 0.1775 1.9202 2.8647 -0.0756 1.0138 ...
## $ employment : num 0.131 0.968 0.131 0.968 0.131 ...
## $ lq_tertiary : num 0.0661 -1.4923 1.5132 0.734 -0.0452 ...
# Histograma de cada variable
library(ggplot2)
library(tidyr)
mx_long <- pivot_longer(mx_selected, cols = -state_id, names_to = "variable", values_to = "valor")
ggplot(mx_long, aes(x = valor)) +
facet_wrap(~ variable, scales = "free") +
geom_histogram(bins = 15, fill = "skyblue", color = "black") +
theme_minimal()
Correlación negativa entre lq_tertiary y crime_rate
Las áreas con mayor proporción de personas con educación terciaria tienden a tener menores tasas de criminalidad.
La educación superior podría estar desempeñando un papel protector contra el crimen. Esto sugiere que políticas educativas podrían tener efectos indirectos positivos en seguridad.
Correlación positiva entre real_ave_month_income y lq_tertiary.
Casi nula correlación entre real_ave_month_income y employment
El nivel de empleo no necesariamente está asociado con un mayor ingreso promedio.
Se puede reflejar una estructura salarial desigual, o que muchos empleos no están bien remunerados. También podría indicar informalidad o diferencias entre calidad del empleo y cantidad.
Leve correlación negativa entre employment y lq_tertiary
Crime_rate está poco relacionado con income y employment (casi nulas)
Las correlaciones observadas son en su mayoría débiles, lo que sugiere que no hay relaciones lineales fuertes entre estas variables en el conjunto de datos analizado. La tasa de criminalidad muestra una ligera tendencia a aumentar con el ingreso promedio y el empleo, pero a disminuir ligeramente con una mayor concentración en el sector terciario. El ingreso promedio y el empleo parecen tener una relación muy débil entre sí, pero ambos muestran una ligera correlación positiva con la concentración en el sector terciario.
crime_rate y real_ave_month_income: Existe una correlación positiva muy débil (0.08), lo que sugiere que, aunque mínima, hay una ligera tendencia a que mayores ingresos promedio se asocien con una tasa de criminalidad ligeramente más alta.
crime_rate y employment: La correlación positiva débil (0.13) indica que podría haber una leve tendencia a que las zonas con mayor nivel de empleo también presenten una tasa de criminalidad ligeramente más alta.
crime_rate y lq_tertiary: Se observa una correlación negativa débil (-0.2), lo que sugiere que las áreas con mayor concentración de empleo en el sector terciario tienden a tener una tasa de criminalidad ligeramente más baja.
real_ave_month_income y employment: La correlación es negativa muy débil (-0.06), indicando que prácticamente no existe una relación significativa entre el ingreso promedio y el nivel de empleo.
real_ave_month_income y lq_tertiary: Hay una correlación positiva débil (0.15), lo que sugiere que los ingresos promedio tienden a ser ligeramente más altos en áreas con mayor concentración de empleo en el sector terciario.
employment y lq_tertiary: Con una correlación negativa débil (-0.24), se sugiere que a mayor nivel de empleo general, podría haber una menor concentración relativa de empleo en el sector terciario.
library(corrplot)
numeric_data <- mx_selected[ , -1] # quitar state_id
cor_matrix <- cor(numeric_data, use = "complete.obs")
corrplot(
cor_matrix,
method = "circle",
type = "upper",
tl.cex = 0.9,
addCoef.col = "black",
number.cex = 0.7 )
crime_rate
Mediana: ≈ 25 delitos por n habitantes de la muestra.
IQR (Q1–Q3): de ≈ 10 a 35 delitos por n habitantes de la muestra.
Cola derecha pronunciada y varios outliers altos (hasta ≈ 95 delitos por n habitantes de la muestra).
Distribución sesgada a la derecha.
real_ave_month_income
Mediana: ≈ 5 500 (mxn).
IQR: de ≈ 4 800 a 6 000.
Un outlier cercano a 8 500; leve sesgo positivo.
Variabilidad moderada.
employment
Mediana: ≈ 0.97 (97 % de la población empleada).
IQR muy estrecho: ≈ 0.965–0.975.
Casi sin outliers; distribución muy concentrada.
lq_tertiary
Mediana: ≈ 1.00 (igual concentración del sector terciario que el promedio).
IQR: ≈ 0.95–1.05.
Algunos outliers bajos (~0.80) y altos (~1.15).
Indica variación moderada en la presencia del sector terciario entre las unidades muestrales.
library(reshape2)
library(ggplot2)
# Reshape de los datos
mx_melt <- melt(mx_selected, id.vars = "state_id")
# Crear los boxplots para cada variable por separado
ggplot(mx_melt, aes(x = variable, y = value)) +
geom_boxplot(fill = "orange", color = "black") +
theme_minimal() +
facet_wrap(~ variable, scales = "free_y")
A continuación se calcula su respectiva matriz de disimilitudes D0_ y se realiza un análisis de conglomerados con k=4.
Se selecciona una k de 4 , en donde al cortar el dendrograma en 4 ramas (los 4 colores), obtenemos cuatro grupos relativamente homogéneos internamente. Entre los grupos se observa que:
Hay 1 grupo muy compacto (verde)
2 grupos de parecido moderado (amarillo y azul)
1 más disperso y diferenciado (rojo)
# Matriz de disimilitudes (distancia euclidiana)
D0_ <- dist(scale(numeric_data), method = "euclidean")
# Cluster jerárquico con método Ward.D2
hc_ward <- hclust(D0_, method = "ward.D2")
# Dendrograma con k=4
library(dendextend)
dend <- as.dendrogram(hc_ward)
colores_personalizados <- c("#FDCB6E", "#619CFF", "#00BA38", "#F8766D") # Colores que deseas
dend_colored <- color_branches(dend, k = 4, col = colores_personalizados, groupLabels = c("3", "2", "4", "1"))
plot(dend_colored, main = "Dendrograma con 4 Clusters (Ward.D2)", ylab = "Distancia")
rect.hclust(hc_ward, k = 4, border = colores_personalizados)
Posteriormente, se asigna a cada estado su cluster correspondiente.
mx_selected$cluster <- cutree(hc_ward, k = 4)
state_geodata <- left_join(
state_geodata,
mx_selected[, c("state_id", "cluster")],
by = c("OBJECTID" = "state_id")
)
# Verifica que los clusters se hayan añadido correctamente
table(state_geodata$cluster, useNA = "ifany")
##
## 1 2 3 4
## 12 8 8 4
Visualización de clusters con Ward
Se utilizó la distancia euclidiana sobre las variables, con esté parámetro los clusters pueden quedar “dispersos”, es decir, no necesariamente vecinos en el mapa, porque no entra a jugar ninguna restricción geográfica.
library(tmap)
library(ggplot2)
library(sf)
state_geodata$cluster <- as.factor(state_geodata$cluster)
ggplot() +
# Capa para estados con NA (gris claro, sin incluir en leyenda)
geom_sf(data = subset(state_geodata, is.na(cluster)), fill = "gray90", color = "black", show.legend = FALSE) +
geom_sf(data = subset(state_geodata, !is.na(cluster)), aes(fill = cluster), color = "black") +
scale_fill_manual(
values = c("1" = "#F8766D", "2" = "#619CFF", "3" = "#FDCB6E", "4" = "#00BA38"),
name = "Cluster Socioeconómico"
) +
labs(
title = "Clusters Socioeconómicos (k = 4)"
) +
theme_minimal() +
theme(
legend.position = "right"
)
Conectividad local:
Cada nodo (ciudad o estado) está conectado con los 4 puntos más cercanos. Dichas conexiones podrían representar:
Vínculos socioeconómicos.
Rutas de interacción (comercial, social, etc.).
Vecindad espacial para análisis geoespaciales (por ejemplo, autocorrelación espacial como Moran’s I o LISA).
Distribución geográfica:
Las conexiones son más densas en el centro y sureste del país.
Mientras que, en el norte, las conexiones son más largas y espaciadas, probablemente por mayor dispersión territorial.
library(sf)
library(tmap)
# Calcular centroides de cada estado
state_centroids <- st_centroid(st_geometry(state_geodata))
# Mostrar el mapa de los centroides
tm_shape(state_geodata) +
tm_borders() +
tm_shape(state_centroids) +
tm_dots(col = "red", size = 0.1) +
tm_layout(title = "Centroides de Estados de México")
col.knn_mx <- knearneigh(state_centroids, k=4)
plot(st_geometry(state_geodata), border="darkgrey")
plot(knn2nb(col.knn_mx), state_centroids, add=TRUE)
title(main="K Nearest Neighbours, k=4")
El dendrograma en los márgenes del heatmap agrupa los estados según similitud en los datos, formando subregiones funcionales que no necesariamente coinciden con la cercanía geográfica. Esto permite un análisis jerárquico alternativo al clustering espacial mostrado, por ejemplo, en el gráfico de KNN:
Colores claros (amarillos): distancias pequeñas ⇒ estados muy cercanos (vecinos).
Colores oscuros (rojos): distancias grandes ⇒ estados lejanos (por ejemplo, un estado del norte frente a uno del sureste).
Con base en lo anterior, se generan los siguientes hallazgos:
Se observa un grupo compacto (esquinas amarillas) que indica un subconjunto de estados muy similares entre sí en la métrica D1_. Este grupo podría corresponder a entidades con perfiles económicos, educativos y de criminalidad parecidos.
Algunos estados tienen distancias altas respecto a casi todos los demás (cuadros más rojos), lo que indica que son atípicos o muy distintos (por ejemplo, estados muy industrializados vs. rurales o con alta criminalidad vs. baja).
library(geosphere)
coords_centroids <- st_coordinates(state_centroids)
D1_ <- dist(coords_centroids, method = "euclidean")
D1__matrix <- as.matrix(D1_)
heatmap(D1__matrix, main = "Matriz de Distancias D1_", col = heat.colors(256))
Con la función choicealpha se identifica que con un alpha de 0.3, se pueden obtener clusters que explican razonablemente bien tanto la variación socio-económica como la proximidad geográfica.
#PRIMER EJEMPLO K = 4
library(cluster)
alpha_seq <- seq(0, 1, by = 0.02)
K <- 4
cr <- choicealpha(D0_, D1_, alpha_seq,
K, graph = FALSE)
#cr$Q #Proporción de Inercia Explicda
plot(cr)
Zonas Mixtas de Desarrollo Medio (Cluster 1): Estados con niveles medios en ingresos y empleo, y un perfil mixto en criminalidad y terciarización.
Estados de Informalidad y Bajos Ingresos (Cluster 2): Estados con mayores niveles de informalidad o bajos ingresos, aunque con variación en especialización sectorial.
Regiones Urbanas de Alta Competitividad (Cluster 3): Estados con mejores ingresos y empleo, posiblemente también con fuerte orientación al sector terciario (alta competitividad urbana o industrial).
Zonas Intermedios Cohesionados (Cluster 4): Estados (Zacatecas, Colima y SLP) con características intermedias pero más cohesionados geográficamente.
library(dendextend)
library(ggplot2)
library(sf)
library(ClustGeo)
library(dplyr)
tree4 <- hclustgeo(D0_, D1_, alpha = 0.3)
P4 <- cutree(tree4, 4) # Generar clusters
state_geodata$cluster <- as.factor(P4) # Asegúrate de que esté como factor y en el mismo orden
# Crear dendrograma con colores
dend_tree4 <- as.dendrogram(tree4)
colores_personalizados <- c("4" = "#FDCB6E", "3" = "#619CFF", "2" = "#00BA38", "1" = "#F8766D")
dend_tree4_color <- color_branches(dend_tree4, k = 4, col = colores_personalizados, groupLabels = c("4", "3", "2", "1"))
# Graficar dendrograma
plot(dend_tree4_color, main = "Dendograma para 4 clusters con alpha 0.3 y distancias geográficas")
# Graficar mapa con colores
ggplot() +
geom_sf(data = subset(state_geodata, is.na(cluster)),
fill = "gray90", color = "black", show.legend = FALSE) +
geom_sf(data = subset(state_geodata, !is.na(cluster)),
aes(fill = cluster), color = "black") +
scale_fill_manual(
values = colores_personalizados,
name = "Cluster Socioeconómico"
) +
labs(title = "Clusters Socioeconómicos (k = 4)") +
theme_minimal() +
theme(legend.position = "right")
Se repite el análisis previo cambiando la cantidad de conglomerados que anteriormente fue k=4 a k=3 ó k=5 con el fin de generar comparaciones con los conglomerados anteriormente realizados.
En las visualizacion de k=3, se observa que:
Zona Desarrollo Relativo (Cluster 1): Estados caracterizados por niveles de ingreso y empleo similares, una tasa de criminalidad comparable y una posible especialización en el sector terciario, probablemente ligada a la industrialización fronteriza.
Zona Desarrollo Tradicional (Cluster 2): Agrupa estados con zonas urbanas desarrolladas, economías orientadas a servicios, niveles intermedios o altos de ingreso y criminalidad relativamente controlada.
Zona Desarrollo Emergente (Cluster 3): Comprende estados con ingresos posiblemente más bajos, empleo con dinámicas propias (como mayor informalidad o menor criminalidad) y un lq_tertiary que refleja una especialización diferenciada .
#SEGUNDO EJEMPLO K = 3
library(cluster)
alpha_seq3 <- seq(0, 1, by = 0.02)
K3 <- 3
cr3 <- choicealpha(D0_, D1_, alpha_seq3,
K3, graph = FALSE)
#cr$Q #Proporción de Inercia Explicda
plot(cr3)
P3 <- cutree(tree4, 3) # Generar clusters con k = 3
state_geodata$cluster <- as.factor(P3) # Asignar nuevos clusters como factor
# Crear dendrograma con colores para k = 3
dend_tree3 <- as.dendrogram(tree4)
colores_personalizados_3 <- c("3" = "#619CFF", "2" = "#00BA38", "1" = "#F8766D")
dend_tree3_color <- color_branches(dend_tree3, k = 3, col = colores_personalizados_3, groupLabels = c("3", "2", "1"))
# Graficar dendrograma para k = 3
plot(dend_tree3_color, main = "Dendograma para 3 clusters con alpha 0.3 y distancias geográficas")
# Graficar mapa con colores para k = 3
ggplot() +
geom_sf(data = subset(state_geodata, is.na(cluster)),
fill = "gray90", color = "black", show.legend = FALSE) +
geom_sf(data = subset(state_geodata, !is.na(cluster)),
aes(fill = cluster), color = "black") +
scale_fill_manual(
values = colores_personalizados_3,
name = "Cluster Socioeconómico"
) +
labs(title = "Clusters Socioeconómicos (k = 3)") +
theme_minimal() +
theme(legend.position = "right")
Por otra parte, en las visualizaciones con k=5, se observa que:
Industrial con alta inseguridad (Cluster 1): Cubre principalmente estados del norte, representa zonas con fuerte actividad industrial y manufacturera. Sin embargo, se ven afectadas por altos niveles de inseguridad, lo que limita su potencial de desarrollo. Esta categoría coincide con estados productivos pero con retos estructurales en materia de violencia. Ejemplos probables: Tamaulipas, Chihuahua, Baja California.
Urbano con servicios desarrollados (Cluster 2): Entidades más urbanizadas y con mayor desarrollo económico, caracterizadas por una economía terciaria (servicios) consolidada, altos ingresos y niveles relativamente bajos de criminalidad. Este cluster incluye grandes centros urbanos como Ciudad de México y Nuevo León, lo que lo alinea claramente con el perfil de zonas modernas, seguras y con alto dinamismo económico.
Seguro con actividad terciaria media (Cluster 3): Cubre estados con economías en transición, niveles moderados de terciarización y cierta inseguridad, aunque no al nivel del cluster rojo. Corresponde a entidades como Zacatecas, Colima o San Luis Potosí. Su posición intermedia refleja una economía menos sofisticada que la del cluster verde, pero con menos riesgo que los estados del cluster rojo.
Rural con estabilidad laboral (Cluster 4): Se localiza en el centro-noroeste del país e incluye estados predominantemente rurales, con ingresos moderados, baja densidad poblacional y buena estabilidad laboral. Aunque sus economías son más tradicionales, mantienen un equilibrio social y económico aceptable. Se alinea bien con el perfil de “Rural con estabilidad laboral”.
Zona con bajo ingreso y alta ocupación (Cluster 5): Incluye estados como Hidalgo, Querétaro o Estado de México. Se caracterizan por alta participación laboral, pero niveles de inseguridad más marcados. Representan una zona de crecimiento económico tensionado, en la que el dinamismo del mercado laboral no se traduce todavía en bienestar amplio.
#TERCER EJEMPLO K = 5
library(cluster)
alpha_seq5 <- seq(0, 1, by = 0.02)
K5 <- 5
cr5 <- choicealpha(D0_, D1_, alpha_seq5,
K5, graph = FALSE)
#cr$Q #Proporción de Inercia Explicda
plot(cr5)
library(dendextend)
library(ggplot2)
library(sf)# Generar clusters k = 5
# Asignar los clusters
P5 <- cutree(tree4, 5)
state_geodata$cluster <- as.factor(P5)
colores_personalizados_5 <- c(
"1" = "#F8766D", # Rojo
"2" = "#00BA38", # Verde
"3" = "#619CFF", # Azul ← el de 3 estados
"4" = "#FDCB6E", # Amarillo
"5" = "#A084CA" # Morado
)
# Crear dendrograma y colorearlo según los números reales de cutree
dend_tree5 <- as.dendrogram(tree4)
dend_tree5_color <- color_branches(
dend_tree5, k = 5,
col = colores_personalizados_5
)
library(dendextend)
# Crear dendrograma
dend_tree5 <- as.dendrogram(tree4)
# Obtener los números de cluster asignados a cada hoja
labels_ordered <- order.dendrogram(dend_tree5)
cluster_labels <- P5[labels_ordered]
# Asignar colores a las etiquetas según los clusters reales
label_colors <- colores_personalizados_5[as.character(cluster_labels)]
# Aplicar colores a las etiquetas del dendrograma
labels_colors(dend_tree5) <- label_colors
# Graficar dendrograma
plot(dend_tree5, main = "Dendograma para 5 clusters con alpha 0.3 y distancias geográficas")
ggplot() +
geom_sf(data = subset(state_geodata, is.na(cluster)),
fill = "gray90", color = "black", show.legend = FALSE) +
geom_sf(data = subset(state_geodata, !is.na(cluster)),
aes(fill = cluster), color = "black") +
scale_fill_manual(
values = colores_personalizados_5,
name = "Cluster Socioeconómico"
) +
labs(title = "Clusters Socioeconómicos (k = 5)") +
theme_minimal() +
theme(legend.position = "right")
El análisis comparativo entre los conglomerados generados con k=3, k=4 y k=5 evidencia cómo el número de clusters afecta el nivel de detalle territorial y socioeconómico de la segmentación. Cada incremento en k implica dividir uno de los grupos previos en subgrupos que conservan proximidad geográfica, pero presentan diferencias socioeconómicas suficientes como para justificar una nueva partición. Por lo tanto, se recomienda utilizar P3 cuando se desea un análisis general del país, P4 para un enfoque regional con mayor detalle, y P5 cuando se busca estudiar subterritorios o estados con características muy particulares. Los conglomerados generados con k=3, se identifican tres grandes zonas: una rural y estable, una industrial con altos niveles de inseguridad, y una desarrollada y urbana con altos ingresos, lo cual resulta útil para una visión general del país. Al aumentar k=4, se logra una mejor diferenciación, destacando un grupo de estados con alto ingreso, empleo formal y terciarización (Cluster 1), así como un clúster más cohesionado geográficamente (Cluster 4), lo que permite un enfoque más equilibrado entre simplicidad y especificidad. Finalmente, con k=5 se obtiene la segmentación más detallada, que distingue subgrupos con condiciones particulares como estados rurales con estabilidad laboral, regiones con baja informalidad pero ingresos modestos, y zonas con fuerte desarrollo económico pero altos niveles de criminalidad. Dicho nivel de detalle permite una focalización más precisa en el diseño de políticas públicas, aunque puede implicar mayor complejidad en la implementación.
Asimismo, la combinación de distancias socioeconómicas (D0) y geográficas (D1) mediante el parámetro α permite equilibrar la homogeneidad de los perfiles con la cohesión espacial. En este caso, se seleccionó α=0.3 como valor óptimo, lo que garantiza la formación de clusters territorialmente coherentes y estadísticamente relevantes. Dicha elección contrasta con métodos como Ward, que priorizan únicamente la similitud en perfiles socioeconómicos sin considerar la ubicación geográfica. En resumen, mientras Ward es útil cuando la prioridad es la pureza del perfil, el uso de α es preferible cuando se necesita que los clusters también reflejen la distribución espacial de los estados.
Kaufman, L., & Rousseeuw, P. J. (2009). Finding groups in data: An introduction to cluster analysis. John Wiley & Sons. https://doi.org/10.1002/9780470316801
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2021). An Introduction to Statistical Learning: with Applications in R (2nd ed.). Springer. https://www.statlearning.com/
Chavent, M., Kuentz-Simonet, V., Labenne, A., & Saracco, J. (2018). ClustGeo: an R package for hierarchical clustering with spatial constraints. R Journal, 10(1), 261–273. https://journal.r-project.org/archive/2018/RJ-2018-031/RJ-2018-031.pdf