Introducción

library(cluster)
library(ggplot2)
library(data.table)
library(factoextra)
library(readxl)
library(dplyr)

Carga de datos

df <- read_excel("C:\\Users\\erik-\\OneDrive\\Documentos\\Escuela\\Universidad\\7ºSemestre\\Modulo_2\\Percepcion_inseguridad_2024_por_estado.xlsx")
df
## # A tibble: 32 × 2
##    desc_entidad         `2024`
##    <chr>                 <dbl>
##  1 Aguascalientes         40.6
##  2 Baja California        37.2
##  3 Baja California Sur    19.3
##  4 Campeche               36.5
##  5 Coahuila de Zaragoza   28.9
##  6 Colima                 34.7
##  7 Chiapas                32.7
##  8 Chihuahua              33.2
##  9 Ciudad de México       47.5
## 10 Durango                24.3
## # ℹ 22 more rows

Exploración de la base de datos

summary(df)
##  desc_entidad            2024      
##  Length:32          Min.   :19.29  
##  Class :character   1st Qu.:31.04  
##  Mode  :character   Median :36.83  
##                     Mean   :36.59  
##                     3rd Qu.:40.68  
##                     Max.   :58.86
str(df)
## tibble [32 × 2] (S3: tbl_df/tbl/data.frame)
##  $ desc_entidad: chr [1:32] "Aguascalientes" "Baja California" "Baja California Sur" "Campeche" ...
##  $ 2024        : num [1:32] 40.6 37.2 19.3 36.5 28.9 ...

Transformación de base de datos

df_num <- df[sapply(df, is.numeric)]

Limpieza de base de datos

df_num <- na.omit(df_num)               
df_num <- df_num[apply(df_num, 1, function(x) all(is.finite(x))), ]  

Creación preliminar de los clusters

set.seed(123)
grupos <- 4
clusters <- kmeans(df_num, grupos)
clusters
## K-means clustering with 4 clusters of sizes 8, 2, 5, 17
## 
## Cluster means:
##       2024
## 1 24.25946
## 2 57.98978
## 3 47.14110
## 4 36.77509
## 
## Clustering vector:
##  [1] 4 4 1 4 1 4 4 4 3 1 3 4 4 4 2 4 2 1 4 1 3 4 4 4 1 4 3 1 3 4 1 4
## 
## Within cluster sum of squares by cluster:
## [1]  96.589506   1.531946  14.855287 149.326137
##  (between_SS / total_SS =  91.1 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Buscar la optimización de clusters

set.seed(123)
optimizacion <- clusGap(df_num, FUN = kmeans, nstart = 1, K.max = 7)
plot(optimizacion, xlab = "Número de clusters k", main = "Optimización")

Creación de clusters con optimización

set.seed(123)
grupos_optimizado <- 3
clusters_optimizado <- kmeans(df_num, grupos_optimizado)
clusters_optimizado
## K-means clustering with 3 clusters of sizes 8, 7, 17
## 
## Cluster means:
##       2024
## 1 24.25946
## 2 50.24072
## 3 36.77509
## 
## Clustering vector:
##  [1] 3 3 1 3 1 3 3 3 2 1 2 3 3 3 2 3 2 1 3 1 2 3 3 3 1 3 2 1 2 3 1 3
## 
## Within cluster sum of squares by cluster:
## [1]  96.58951 184.52148 149.32614
##  (between_SS / total_SS =  85.4 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Unir las predicciones

df_cl <- cbind(df, cluster = clusters_optimizado$cluster)

Revisar las proporciones de los clusters

ggplot(df_cl, aes(x = factor(cluster), fill = factor(cluster))) +
  geom_bar() +
  labs(title = "Número de estados por clúster",
       x = "Clúster", y = "Cantidad de estados") +
  theme_minimal()

Presentar los clusters

df_cl <- df_cl %>% arrange(`2024`)
df_cl
##            desc_entidad     2024 cluster
## 1   Baja California Sur 19.29402       1
## 2               Sinaloa 19.33081       1
## 3               Nayarit 22.07829       1
## 4               Durango 24.30245       1
## 5               Yucatán 25.30951       1
## 6                Oaxaca 27.26456       1
## 7            Tamaulipas 27.56524       1
## 8  Coahuila de Zaragoza 28.93081       1
## 9              Guerrero 31.74318       3
## 10              Chiapas 32.72925       3
## 11            Chihuahua 33.20264       3
## 12               Sonora 33.68126       3
## 13             Veracruz 33.98077       3
## 14               Colima 34.71915       3
## 15  Michoacán de Ocampo 35.17247       3
## 16             Campeche 36.46388       3
## 17      Baja California 37.20460       3
## 18              Jalisco 37.71220       3
## 19         Quintana Roo 38.19205       3
## 20            Zacatecas 39.00657       3
## 21           Nuevo León 39.42006       3
## 22                    x 39.99854       3
## 23      San Luis Potosí 40.43117       3
## 24       Aguascalientes 40.60093       3
## 25            Querétaro 40.91783       3
## 26               Puebla 44.34018       2
## 27           Guanajuato 46.42415       2
## 28     Ciudad de México 47.49259       2
## 29              Tabasco 47.89977       2
## 30             Tlaxcala 49.54879       2
## 31              Morelos 57.11458       2
## 32               México 58.86498       2

Conclusiones

Podemos identificar que el mejor número de clusters para nuestra agrupar las entidades por percepción de inseguridad es de 3 clusters. De igual forma al revisar el dataframe con los estados de México y su cluster asignado, podemos identifar que el primer cluster tiene a los estados con menor percepción de inseguridad en el cluster 1, los que están en un rango medio (31% en adelante) en cluster 3 y en el cluster 2 los que tienen un porcentaje más alto de percepción de inseguridad.

LS0tDQp0aXRsZTogIk1leGljbyINCmF1dGhvcjogIkVyaWsgR29uemFsZXoiDQpkYXRlOiAiMjAyNS0wOC0xOSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUcnVlIA0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCiAgICB0aGVtZTogZGFya2x5DQoNCi0tLQ0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOndoaXRlOyI+IEludHJvZHVjY2nDs24gPC9zcGFuPg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoY2x1c3RlcikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoZmFjdG9leHRyYSkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShkcGx5cikNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOndoaXRlOyI+IENhcmdhIGRlIGRhdG9zIDwvc3Bhbj4NCmBgYHtyfQ0KZGYgPC0gcmVhZF9leGNlbCgiQzpcXFVzZXJzXFxlcmlrLVxcT25lRHJpdmVcXERvY3VtZW50b3NcXEVzY3VlbGFcXFVuaXZlcnNpZGFkXFw3wrpTZW1lc3RyZVxcTW9kdWxvXzJcXFBlcmNlcGNpb25faW5zZWd1cmlkYWRfMjAyNF9wb3JfZXN0YWRvLnhsc3giKQ0KYGBgDQoNCg0KYGBge3J9DQpkZg0KYGBgDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6d2hpdGU7Ij4gRXhwbG9yYWNpw7NuIGRlIGxhIGJhc2UgZGUgZGF0b3MgPC9zcGFuPg0KYGBge3J9DQpzdW1tYXJ5KGRmKQ0Kc3RyKGRmKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6d2hpdGU7Ij4gVHJhbnNmb3JtYWNpw7NuIGRlIGJhc2UgZGUgZGF0b3MgPC9zcGFuPg0KYGBge3J9DQpkZl9udW0gPC0gZGZbc2FwcGx5KGRmLCBpcy5udW1lcmljKV0NCmBgYA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOndoaXRlOyI+IExpbXBpZXphIGRlIGJhc2UgZGUgZGF0b3MgPC9zcGFuPg0KYGBge3J9DQpkZl9udW0gPC0gbmEub21pdChkZl9udW0pICAgICAgICAgICAgICAgDQpkZl9udW0gPC0gZGZfbnVtW2FwcGx5KGRmX251bSwgMSwgZnVuY3Rpb24oeCkgYWxsKGlzLmZpbml0ZSh4KSkpLCBdICANCmBgYA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOndoaXRlOyI+IENyZWFjacOzbiBwcmVsaW1pbmFyIGRlIGxvcyBjbHVzdGVycyA8L3NwYW4+DQpgYGB7cn0NCnNldC5zZWVkKDEyMykNCmdydXBvcyA8LSA0DQpjbHVzdGVycyA8LSBrbWVhbnMoZGZfbnVtLCBncnVwb3MpDQpjbHVzdGVycw0KYGBgDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6d2hpdGU7Ij4gQnVzY2FyIGxhIG9wdGltaXphY2nDs24gZGUgY2x1c3RlcnMgPC9zcGFuPg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQpvcHRpbWl6YWNpb24gPC0gY2x1c0dhcChkZl9udW0sIEZVTiA9IGttZWFucywgbnN0YXJ0ID0gMSwgSy5tYXggPSA3KQ0KcGxvdChvcHRpbWl6YWNpb24sIHhsYWIgPSAiTsO6bWVybyBkZSBjbHVzdGVycyBrIiwgbWFpbiA9ICJPcHRpbWl6YWNpw7NuIikNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOndoaXRlOyI+IENyZWFjacOzbiBkZSBjbHVzdGVycyBjb24gb3B0aW1pemFjacOzbiA8L3NwYW4+DQpgYGB7cn0NCnNldC5zZWVkKDEyMykNCmdydXBvc19vcHRpbWl6YWRvIDwtIDMNCmNsdXN0ZXJzX29wdGltaXphZG8gPC0ga21lYW5zKGRmX251bSwgZ3J1cG9zX29wdGltaXphZG8pDQpjbHVzdGVyc19vcHRpbWl6YWRvDQpgYGANCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjp3aGl0ZTsiPiBVbmlyIGxhcyBwcmVkaWNjaW9uZXMgPC9zcGFuPg0KYGBge3J9DQpkZl9jbCA8LSBjYmluZChkZiwgY2x1c3RlciA9IGNsdXN0ZXJzX29wdGltaXphZG8kY2x1c3RlcikNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOndoaXRlOyI+IFJldmlzYXIgbGFzIHByb3BvcmNpb25lcyBkZSBsb3MgY2x1c3RlcnMgPC9zcGFuPg0KYGBge3J9DQpnZ3Bsb3QoZGZfY2wsIGFlcyh4ID0gZmFjdG9yKGNsdXN0ZXIpLCBmaWxsID0gZmFjdG9yKGNsdXN0ZXIpKSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicyh0aXRsZSA9ICJOw7ptZXJvIGRlIGVzdGFkb3MgcG9yIGNsw7pzdGVyIiwNCiAgICAgICB4ID0gIkNsw7pzdGVyIiwgeSA9ICJDYW50aWRhZCBkZSBlc3RhZG9zIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6d2hpdGU7Ij4gUHJlc2VudGFyIGxvcyBjbHVzdGVycyA8L3NwYW4+DQpgYGB7cn0NCmRmX2NsIDwtIGRmX2NsICU+JSBhcnJhbmdlKGAyMDI0YCkNCmRmX2NsDQpgYGANCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjp3aGl0ZTsiPiBDb25jbHVzaW9uZXMgPC9zcGFuPg0KUG9kZW1vcyBpZGVudGlmaWNhciBxdWUgZWwgbWVqb3IgbsO6bWVybyBkZSBjbHVzdGVycyBwYXJhIG51ZXN0cmEgYWdydXBhciBsYXMgZW50aWRhZGVzIHBvciBwZXJjZXBjacOzbiBkZSBpbnNlZ3VyaWRhZCBlcyBkZSAzIGNsdXN0ZXJzLiBEZSBpZ3VhbCBmb3JtYSBhbCByZXZpc2FyIGVsIGRhdGFmcmFtZSBjb24gbG9zIGVzdGFkb3MgZGUgTcOpeGljbyB5IHN1IGNsdXN0ZXIgYXNpZ25hZG8sIHBvZGVtb3MgaWRlbnRpZmFyIHF1ZSBlbCBwcmltZXIgY2x1c3RlciB0aWVuZSBhIGxvcyBlc3RhZG9zIGNvbiBtZW5vciBwZXJjZXBjacOzbiBkZSBpbnNlZ3VyaWRhZCBlbiBlbCBjbHVzdGVyIDEsIGxvcyBxdWUgZXN0w6FuIGVuIHVuIHJhbmdvIG1lZGlvICgzMSUgZW4gYWRlbGFudGUpIGVuIGNsdXN0ZXIgMyB5IGVuIGVsIGNsdXN0ZXIgMiBsb3MgcXVlIHRpZW5lbiB1biBwb3JjZW50YWplIG3DoXMgYWx0byBkZSBwZXJjZXBjacOzbiBkZSBpbnNlZ3VyaWRhZC4NCg0KDQo=