Contexto

Este análisis explora los patrones de los accidentes de tránsito en México, reduciendo las variables numéricas con PCA y agrupándolas con clustering para identificar tendencias clave en días, condiciones y severidad.

Paso 1. Instalar paquetes y llamar librerías

# install.packages("cluster")  #Analisis de Agrupamiento
library(cluster)
# install.packages("ggplot2") #Graficar
library(ggplot2)
# install.packages("data.table") #Manejo de muchos datos
library(data.table)
# install.packages("factoextra") #Gráfica optimización de numeros cluster
library(factoextra)

Paso 2. Obtener los datos

accidentes <- read.csv("/Users/mariajoseflores/Downloads/sct_70_accidentes_dia.csv")

Paso 3. Entender los datos

# Paso 3. Entender los datos
summary(accidentes)
##  entidad_federativa  accidentes            lunes            martes      
##  Length:64          Length:64          Min.   :  1.00   Min.   :  1.00  
##  Class :character   Class :character   1st Qu.:  7.75   1st Qu.:  6.00  
##  Mode  :character   Mode  :character   Median : 21.00   Median : 19.00  
##                                        Mean   : 31.02   Mean   : 25.16  
##                                        3rd Qu.: 45.00   3rd Qu.: 35.50  
##                                        Max.   :176.00   Max.   :156.00  
##    miercoles          jueves          viernes           sabado      
##  Min.   :  0.00   Min.   :  0.00   Min.   :  1.00   Min.   :  0.00  
##  1st Qu.:  6.00   1st Qu.:  6.00   1st Qu.:  7.00   1st Qu.: 10.75  
##  Median : 16.00   Median : 16.00   Median : 21.00   Median : 26.00  
##  Mean   : 25.34   Mean   : 28.06   Mean   : 30.27   Mean   : 38.89  
##  3rd Qu.: 37.75   3rd Qu.: 38.75   3rd Qu.: 45.50   3rd Qu.: 59.25  
##  Max.   :184.00   Max.   :169.00   Max.   :190.00   Max.   :207.00  
##     domingo          luz_dia       luz_crepusculo     luz_noche     
##  Min.   :  3.00   Min.   :  4.00   Min.   : 0.000   Min.   :  7.00  
##  1st Qu.: 11.75   1st Qu.: 32.75   1st Qu.: 2.000   1st Qu.: 23.00  
##  Median : 29.50   Median : 78.00   Median : 5.000   Median : 69.50  
##  Mean   : 41.20   Mean   :116.92   Mean   : 8.203   Mean   : 93.98  
##  3rd Qu.: 64.75   3rd Qu.:165.75   3rd Qu.:13.250   3rd Qu.:141.25  
##  Max.   :208.00   Max.   :704.00   Max.   :32.000   Max.   :552.00  
##  luz_alumbrado_publico
##  Min.   :0.0000       
##  1st Qu.:0.0000       
##  Median :0.0000       
##  Mean   :0.8281       
##  3rd Qu.:1.0000       
##  Max.   :8.0000
str(accidentes)
## 'data.frame':    64 obs. of  13 variables:
##  $ entidad_federativa   : chr  "Aguascalientes" "Aguascalientes" "Baja California" "Baja California" ...
##  $ accidentes           : chr  "accidentes" "accidentes mortales" "accidentes" "accidentes mortales" ...
##  $ lunes                : num  34 6 50 8 18 6 27 1 100 13 ...
##  $ martes               : num  20 4 37 6 29 6 32 5 80 7 ...
##  $ miercoles            : num  16 5 36 6 23 5 29 4 96 16 ...
##  $ jueves               : num  23 2 41 6 19 4 17 3 107 12 ...
##  $ viernes              : num  20 3 55 8 35 6 29 1 90 12 ...
##  $ sabado               : num  33 8 75 14 35 9 24 4 108 9 ...
##  $ domingo              : num  33 8 83 16 42 6 37 8 95 10 ...
##  $ luz_dia              : num  91 13 207 37 102 19 98 11 358 36 ...
##  $ luz_crepusculo       : num  4 0 15 5 13 3 3 1 23 2 ...
##  $ luz_noche            : num  84 23 151 22 78 19 94 14 294 41 ...
##  $ luz_alumbrado_publico: num  0 0 4 0 8 1 0 0 1 0 ...

Paso 4. Escalar los datos

# Seleccionar solo las columnas numéricas
num_cols_log <- sapply(accidentes, is.numeric)
accidentes_num <- accidentes[, num_cols_log, drop = FALSE]

# Manejo de NA
accidentes_num <- na.omit(accidentes_num)

# Escalar los datos
datos_escalados <- scale(accidentes_num)

# ---- GRAFICA ÚNICA: PCA (PC1 vs PC2) ----
pca <- prcomp(datos_escalados, scale. = TRUE)

pca_df <- data.frame(PC1 = pca$x[,1],
                     PC2 = pca$x[,2])

ggplot(pca_df, aes(PC1, PC2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  labs(title = "Accidentes - Proyección PCA",
       x = "Componente Principal 1",
       y = "Componente Principal 2") +
  theme_minimal()

Paso 6. Generar los grupos

grupos1 <-3
clusters1 <- kmeans(datos_escalados, grupos1)
clusters1
## K-means clustering with 3 clusters of sizes 5, 17, 42
## 
## Cluster means:
##        lunes     martes  miercoles     jueves    viernes     sabado    domingo
## 1  2.3087830  2.4826763  2.5122909  2.4842891  2.4773887  2.3827179  2.1765817
## 2  0.6993969  0.5690535  0.5231419  0.5994074  0.5842939  0.6997532  0.7800705
## 3 -0.5579443 -0.5258879 -0.5108302 -0.5383660 -0.5314271 -0.5668904 -0.5748597
##      luz_dia luz_crepusculo  luz_noche luz_alumbrado_publico
## 1  2.3888862      2.3499250  2.4501987             0.8186018
## 2  0.6574690      0.7379218  0.6275231             0.6953300
## 3 -0.5505096     -0.5784356 -0.5456877            -0.3788957
## 
## Clustering vector:
##  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 
##  3  3  2  3  2  3  3  3  1  3  2  3  3  3  3  3  3  3  3  3  1  3  1  3  2  3 
## 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 
##  2  3  2  3  2  3  3  3  3  3  1  3  2  3  2  3  2  3  3  3  2  3  2  3  2  3 
## 53 54 55 56 57 58 59 60 61 62 63 64 
##  2  3  2  3  2  3  1  3  3  3  2  3 
## 
## Within cluster sum of squares by cluster:
## [1] 70.97948 66.83573 50.07200
##  (between_SS / total_SS =  72.9 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Paso 7. Optimizar números los grupos

set.seed(123)
optimizacion <- clusGap(accidentes_num, FUN=kmeans, nstar= 1, K.max=10)
# El K.max normalmente es 10. en este ejercicio al ser 8 datos se dejó en 7
plot(optimizacion, xlab= "Número clusters k")

# Se selecciona como óptimo de clusters

Paso 8. Graficar los grupos

fviz_cluster(clusters1, data=datos_escalados)

# Paso 9. Agregar clusters a la base de dsatos

accidentes_num <- cbind(accidentes_num, clusters1$cluster)
head(accidentes_num)
##   lunes martes miercoles jueves viernes sabado domingo luz_dia luz_crepusculo
## 1    34     20        16     23      20     33      33      91              4
## 2     6      4         5      2       3      8       8      13              0
## 3    50     37        36     41      55     75      83     207             15
## 4     8      6         6      6       8     14      16      37              5
## 5    18     29        23     19      35     35      42     102             13
## 6     6      6         5      4       6      9       6      19              3
##   luz_noche luz_alumbrado_publico clusters1$cluster
## 1        84                     0                 3
## 2        23                     0                 3
## 3       151                     4                 2
## 4        22                     0                 3
## 5        78                     8                 2
## 6        19                     1                 3
LS0tCnRpdGxlOiAiQWNjaWRlbnRlcyBUcsOhbnNpdG8iCmF1dGhvcjogIk1hcmlhIEpvc2UgRmxvcmVzIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCiAgICB0aGVtZTogeWV0aQotLS0KCiFbXShodHRwczovL3d3dy50cmFpbmZlcy5jbC93cC1jb250ZW50L3VwbG9hZHMvMjAyMy8xMS9kaWEtbXVuZGlhbC1hY2NpZGVudGVzLWRlLXRyYW5zaXRvLmpwZykgCgojIDxzcGFuIHN0eWxlID0gImNvbG9yOmJsdWU7Ij4gQ29udGV4dG8gPC9zcGFuPgpFc3RlIGFuw6FsaXNpcyBleHBsb3JhIGxvcyBwYXRyb25lcyBkZSBsb3MgYWNjaWRlbnRlcyBkZSB0csOhbnNpdG8gZW4gTcOpeGljbywgcmVkdWNpZW5kbyBsYXMgdmFyaWFibGVzIG51bcOpcmljYXMgY29uIFBDQSB5IGFncnVww6FuZG9sYXMgY29uIGNsdXN0ZXJpbmcgcGFyYSBpZGVudGlmaWNhciB0ZW5kZW5jaWFzIGNsYXZlIGVuIGTDrWFzLCBjb25kaWNpb25lcyB5IHNldmVyaWRhZC4KCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6Ymx1ZTsiPiBQYXNvIDEuIEluc3RhbGFyIHBhcXVldGVzIHkgbGxhbWFyIGxpYnJlcsOtYXMgPC9zcGFuPgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBpbnN0YWxsLnBhY2thZ2VzKCJjbHVzdGVyIikgICNBbmFsaXNpcyBkZSBBZ3J1cGFtaWVudG8KbGlicmFyeShjbHVzdGVyKQojIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKSAjR3JhZmljYXIKbGlicmFyeShnZ3Bsb3QyKQojIGluc3RhbGwucGFja2FnZXMoImRhdGEudGFibGUiKSAjTWFuZWpvIGRlIG11Y2hvcyBkYXRvcwpsaWJyYXJ5KGRhdGEudGFibGUpCiMgaW5zdGFsbC5wYWNrYWdlcygiZmFjdG9leHRyYSIpICNHcsOhZmljYSBvcHRpbWl6YWNpw7NuIGRlIG51bWVyb3MgY2x1c3RlcgpsaWJyYXJ5KGZhY3RvZXh0cmEpCmBgYAoKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpibHVlOyI+IFBhc28gMi4gT2J0ZW5lciBsb3MgZGF0b3MgIDwvc3Bhbj4KYGBge3J9CmFjY2lkZW50ZXMgPC0gcmVhZC5jc3YoIi9Vc2Vycy9tYXJpYWpvc2VmbG9yZXMvRG93bmxvYWRzL3NjdF83MF9hY2NpZGVudGVzX2RpYS5jc3YiKQpgYGAKCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6Ymx1ZTsiPiBQYXNvIDMuIEVudGVuZGVyIGxvcyBkYXRvcyAgPC9zcGFuPgpgYGB7cn0KIyBQYXNvIDMuIEVudGVuZGVyIGxvcyBkYXRvcwpzdW1tYXJ5KGFjY2lkZW50ZXMpCnN0cihhY2NpZGVudGVzKQpgYGAKCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6Ymx1ZTsiPiBQYXNvIDQuIEVzY2FsYXIgbG9zIGRhdG9zICA8L3NwYW4+CmBgYHtyfQojIFNlbGVjY2lvbmFyIHNvbG8gbGFzIGNvbHVtbmFzIG51bcOpcmljYXMKbnVtX2NvbHNfbG9nIDwtIHNhcHBseShhY2NpZGVudGVzLCBpcy5udW1lcmljKQphY2NpZGVudGVzX251bSA8LSBhY2NpZGVudGVzWywgbnVtX2NvbHNfbG9nLCBkcm9wID0gRkFMU0VdCgojIE1hbmVqbyBkZSBOQQphY2NpZGVudGVzX251bSA8LSBuYS5vbWl0KGFjY2lkZW50ZXNfbnVtKQoKIyBFc2NhbGFyIGxvcyBkYXRvcwpkYXRvc19lc2NhbGFkb3MgPC0gc2NhbGUoYWNjaWRlbnRlc19udW0pCgojIC0tLS0gR1JBRklDQSDDmk5JQ0E6IFBDQSAoUEMxIHZzIFBDMikgLS0tLQpwY2EgPC0gcHJjb21wKGRhdG9zX2VzY2FsYWRvcywgc2NhbGUuID0gVFJVRSkKCnBjYV9kZiA8LSBkYXRhLmZyYW1lKFBDMSA9IHBjYSR4WywxXSwKICAgICAgICAgICAgICAgICAgICAgUEMyID0gcGNhJHhbLDJdKQoKZ2dwbG90KHBjYV9kZiwgYWVzKFBDMSwgUEMyKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIGNvbG9yID0gInN0ZWVsYmx1ZSIpICsKICBsYWJzKHRpdGxlID0gIkFjY2lkZW50ZXMgLSBQcm95ZWNjacOzbiBQQ0EiLAogICAgICAgeCA9ICJDb21wb25lbnRlIFByaW5jaXBhbCAxIiwKICAgICAgIHkgPSAiQ29tcG9uZW50ZSBQcmluY2lwYWwgMiIpICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYAoKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpibHVlOyI+IFBhc28gNi4gR2VuZXJhciBsb3MgZ3J1cG9zIDwvc3Bhbj4KYGBge3J9CmdydXBvczEgPC0zCmNsdXN0ZXJzMSA8LSBrbWVhbnMoZGF0b3NfZXNjYWxhZG9zLCBncnVwb3MxKQpjbHVzdGVyczEKYGBgCgojIDxzcGFuIHN0eWxlID0gImNvbG9yOmJsdWU7Ij4gUGFzbyA3LiBPcHRpbWl6YXIgbsO6bWVyb3MgbG9zIGdydXBvcyA8L3NwYW4+CmBgYHtyfQpzZXQuc2VlZCgxMjMpCm9wdGltaXphY2lvbiA8LSBjbHVzR2FwKGFjY2lkZW50ZXNfbnVtLCBGVU49a21lYW5zLCBuc3Rhcj0gMSwgSy5tYXg9MTApCiMgRWwgSy5tYXggbm9ybWFsbWVudGUgZXMgMTAuIGVuIGVzdGUgZWplcmNpY2lvIGFsIHNlciA4IGRhdG9zIHNlIGRlasOzIGVuIDcKcGxvdChvcHRpbWl6YWNpb24sIHhsYWI9ICJOw7ptZXJvIGNsdXN0ZXJzIGsiKQojIFNlIHNlbGVjY2lvbmEgY29tbyDDs3B0aW1vIGRlIGNsdXN0ZXJzCgpgYGAKCgojIDxzcGFuIHN0eWxlID0gImNvbG9yOmJsdWU7Ij4gUGFzbyA4LiBHcmFmaWNhciBsb3MgZ3J1cG9zIDwvc3Bhbj4KYGBge3J9CmZ2aXpfY2x1c3RlcihjbHVzdGVyczEsIGRhdGE9ZGF0b3NfZXNjYWxhZG9zKQpgYGAKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpibHVlOyI+IFBhc28gOS4gQWdyZWdhciBjbHVzdGVycyBhIGxhIGJhc2UgZGUgZHNhdG9zIDwvc3Bhbj4KYGBge3J9CmFjY2lkZW50ZXNfbnVtIDwtIGNiaW5kKGFjY2lkZW50ZXNfbnVtLCBjbHVzdGVyczEkY2x1c3RlcikKaGVhZChhY2NpZGVudGVzX251bSkKYGBg