Teoría

Estos datos son el resultado de un análisis de la industria de — en México.

Instalar paquetes

#install.packages("cluster") #Análisis 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 de optimización de número de clusters
library(factoextra)

Paso 2. Obtener los datos

df1_restaurantes <- read.csv("/Users/humbertocs/Desktop/Tec/Concentración IA/M2_Programacion R IA/Mexico/denue_00_72_1_csv/conjunto_de_datos/denue_inegi_72_1.csv")

df2_restaurantes <- read.csv("/Users/humbertocs/Desktop/Tec/Concentración IA/M2_Programacion R IA/Mexico/denue_00_72_2_csv/conjunto_de_datos/denue_inegi_72_2.csv")

Limpieza de datos

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:data.table':
## 
##     between, first, last
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
df_restaurantes <- bind_rows(df1_restaurantes, df2_restaurantes)

unique(df_restaurantes$entidad)
##  [1] "Aguascalientes"                  "Baja California"                
##  [3] "Baja California Sur"             "Campeche"                       
##  [5] "Coahuila de Zaragoza"            "Colima"                         
##  [7] "Chiapas"                         "Chihuahua"                      
##  [9] "Ciudad de M\xe9xico"             "Durango"                        
## [11] "Guanajuato"                      "Guerrero"                       
## [13] "Hidalgo"                         "Jalisco"                        
## [15] "M\xe9xico"                       "Michoac\xe1n de Ocampo"         
## [17] "Morelos"                         "Nayarit"                        
## [19] "Nuevo Le\xf3n"                   "Oaxaca"                         
## [21] "Puebla"                          "Quer\xe9taro"                   
## [23] "Quintana Roo"                    "San Luis Potos\xed"             
## [25] "Sinaloa"                         "Sonora"                         
## [27] "Tabasco"                         "Tamaulipas"                     
## [29] "Tlaxcala"                        "Veracruz de Ignacio de la Llave"
## [31] "Yucat\xe1n"                      "Zacatecas"
library(stringi)
library(stringr)

df_restaurantes <- df_restaurantes %>%
  mutate(entidad = stri_trans_general(entidad, "Latin-ASCII"),
         entidad = str_to_title(entidad))

unique(df_restaurantes$entidad)
##  [1] "Aguascalientes"                  "Baja California"                
##  [3] "Baja California Sur"             "Campeche"                       
##  [5] "Coahuila De Zaragoza"            "Colima"                         
##  [7] "Chiapas"                         "Chihuahua"                      
##  [9] "Ciudad De M�Xico"                "Durango"                        
## [11] "Guanajuato"                      "Guerrero"                       
## [13] "Hidalgo"                         "Jalisco"                        
## [15] "M�Xico"                          "Michoac�N De Ocampo"            
## [17] "Morelos"                         "Nayarit"                        
## [19] "Nuevo Le�N"                      "Oaxaca"                         
## [21] "Puebla"                          "Quer�Taro"                      
## [23] "Quintana Roo"                    "San Luis Potos�"                
## [25] "Sinaloa"                         "Sonora"                         
## [27] "Tabasco"                         "Tamaulipas"                     
## [29] "Tlaxcala"                        "Veracruz De Ignacio De La Llave"
## [31] "Yucat�N"                         "Zacatecas"
library(dplyr)

df_restaurantes <- df_restaurantes %>%
  mutate(entidad = recode(entidad,
    "Coahuila De Zaragoza" = "Coahuila",
    "Ciudad De M�Xico" = "Ciudad de México",
    "M�Xico" = "México",
    "Michoac�N De Ocampo" = "Michoacán",
    "Nuevo Le�N" = "Nuevo León",
    "Quer�Taro" = "Querétaro",
    "San Luis Potos�" = "San Luis Potosí",
    "Veracruz De Ignacio De La Llave" = "Veracruz",
    "Yucat�N" = "Yucatán"
  ))


unique(df_restaurantes$nombre_act)
##  [1] "Cafeter\xedas, fuentes de sodas, never\xedas, refresquer\xedas y similares"                                   
##  [2] "Restaurantes de autoservicio"                                                                                 
##  [3] "Hoteles con otros servicios integrados"                                                                       
##  [4] "Restaurantes con servicio de preparaci\xf3n de alimentos a la carta o de comida corrida"                      
##  [5] "Bares, cantinas y similares"                                                                                  
##  [6] "Restaurantes con servicio de preparaci\xf3n de antojitos"                                                     
##  [7] "Restaurantes con servicio de preparaci\xf3n de tacos y tortas"                                                
##  [8] "Centros nocturnos, discotecas y similares"                                                                    
##  [9] "Restaurantes que preparan otro tipo de alimentos para llevar"                                                 
## [10] "Restaurantes con servicio de preparaci\xf3n de pizzas, hamburguesas, hot dogs y pollos rostizados para llevar"
## [11] "Servicios de preparaci\xf3n de alimentos para ocasiones especiales"                                           
## [12] "Restaurantes con servicio de preparaci\xf3n de pescados y mariscos"                                           
## [13] "Servicios de preparaci\xf3n de otros alimentos para consumo inmediato"                                        
## [14] "Servicios de comedor para empresas e instituciones"                                                           
## [15] "Hoteles sin otros servicios integrados"                                                                       
## [16] "Departamentos y casas amueblados con servicios de hoteler\xeda"                                               
## [17] "Moteles"                                                                                                      
## [18] "Servicios de preparaci\xf3n de alimentos en unidades m\xf3viles"                                              
## [19] "Caba\xf1as, villas y similares"                                                                               
## [20] "Pensiones y casas de hu\xe9spedes"                                                                            
## [21] "Campamentos y albergues recreativos"
cafeterias <- df_restaurantes %>%
  filter(nombre_act == "Cafeter\xedas, fuentes de sodas, never\xedas, refresquer\xedas y similares")


cafeterias_NL <- cafeterias %>%
  filter(entidad == "Nuevo Le�N")
cafeterias_por_estado <- cafeterias %>%
  group_by(entidad) %>%
  summarise(total_cafeterias = n(), .groups = "drop")

Paso 3. -

summary(cafeterias_por_estado)
##    entidad          total_cafeterias
##  Length:32          Min.   :  549   
##  Class :character   1st Qu.: 1346   
##  Mode  :character   Median : 2109   
##                     Mean   : 2917   
##                     3rd Qu.: 3557   
##                     Max.   :13156
str(cafeterias_por_estado)
## tibble [32 × 2] (S3: tbl_df/tbl/data.frame)
##  $ entidad         : chr [1:32] "Aguascalientes" "Baja California" "Baja California Sur" "Campeche" ...
##  $ total_cafeterias: int [1:32] 1349 3097 1310 549 2406 1889 9797 1488 885 1119 ...

Paso 4. Escalar los datos

# Sólo si no estan en la misma escala
datos_escalados <- scale(cafeterias_por_estado$total_cafeterias)

Paso 5. Determinar número de grupos

# Siempre es un valor inicial "cualquiera", luego se optimiza.
grupos1 <- 3

Paso 6. Generar los grupos

set.seed(123)
clusters1 <- kmeans(datos_escalados, grupos1)
clusters1
## K-means clustering with 3 clusters of sizes 22, 2, 8
## 
## Cluster means:
##         [,1]
## 1 -0.4927850
## 2  3.1708624
## 3  0.5624431
## 
## Clustering vector:
##  [1] 1 3 1 1 1 1 2 1 1 1 3 1 1 3 3 1 2 1 3 3 3 1 1 1 1 1 1 1 1 3 1 1
## 
## Within cluster sum of squares by cluster:
## [1] 0.7638714 0.7742134 1.4800248
##  (between_SS / total_SS =  90.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Paso 7. Optimizar el número de grupos

set.seed(123)
optimizacion1 <- clusGap(datos_escalados, FUN=kmeans, nstart = 1, K.max=10)
# EL K means normalmente es 10, en este ejercicio al ser 8 datos, se dejó en 7.
plot(optimizacion1, xlab="Número de clústers k")

# Selecciona como óptimo el primer punto más alto
# Similar a la técnica del codo pero esta es más notable

Paso 8. Graficar los grupos

#fviz_cluster(datos_escalados, data=coords_rest)

Paso 9. Agregar Grupos a la Base de Datos

df1_cluster <- cbind(cafeterias_por_estado, cluster = clusters1$cluster)
head(df1_cluster)
##               entidad total_cafeterias cluster
## 1      Aguascalientes             1349       1
## 2     Baja California             3097       3
## 3 Baja California Sur             1310       1
## 4            Campeche              549       1
## 5             Chiapas             2406       1
## 6           Chihuahua             1889       1
LS0tCnRpdGxlOiAiTWV4aWNvIgphdXRob3I6ICJIdW1iZXJ0byBDb3J0w6lzIFNhbGRhw7FhIgpkYXRlOiAiMjAyNS0wOC0xOSIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiBUUlVFCiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUKICAgIHRoZW1lOiBkYXJrbHkKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKIVtdKGh0dHBzOi8vd3d3LmFiYXN0dXJodWIuY29tL2ltZy9ibG9nL21lam9yZXMtcmVzdGF1cmFudGVzLS0tZGlzZW5vLXNpbi10aXR1bG8uanBnKQoKIyA8c3BhbiBzdHlsZT0iY29sb3I6d2hpdGU7Ij4gVGVvcsOtYSA8L3NwYW4+CkVzdG9zIGRhdG9zIHNvbiBlbCByZXN1bHRhZG8gZGUgdW4gYW7DoWxpc2lzIGRlIGxhIGluZHVzdHJpYSBkZSAtLS0gZW4gTcOpeGljby4KCgojIDxzcGFuIHN0eWxlPSJjb2xvcjp3aGl0ZTsiPiBJbnN0YWxhciBwYXF1ZXRlcyA8L3NwYW4+CgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojaW5zdGFsbC5wYWNrYWdlcygiY2x1c3RlciIpICNBbsOhbGlzaXMgZGUgYWdydXBhbWllbnRvCmxpYnJhcnkoY2x1c3RlcikKI2luc3RhbGwucGFja2FnZXMoImdncGxvdDIiKSAjR3JhZmljYXIKbGlicmFyeShnZ3Bsb3QyKQojaW5zdGFsbC5wYWNrYWdlcygiZGF0YS50YWJsZSIpICMgTWFuZWpvIGRlIG11Y2hvcyBkYXRvcwpsaWJyYXJ5KGRhdGEudGFibGUpCiNpbnN0YWxsLnBhY2thZ2VzKCJmYWN0b2V4dHJhIikgIyBHcsOhZmljYSBkZSBvcHRpbWl6YWNpw7NuIGRlIG7Dum1lcm8gZGUgY2x1c3RlcnMKbGlicmFyeShmYWN0b2V4dHJhKQoKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjp3aGl0ZTsiPiBQYXNvIDIuIE9idGVuZXIgbG9zIGRhdG9zIDwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGYxX3Jlc3RhdXJhbnRlcyA8LSByZWFkLmNzdigiL1VzZXJzL2h1bWJlcnRvY3MvRGVza3RvcC9UZWMvQ29uY2VudHJhY2nDs24gSUEvTTJfUHJvZ3JhbWFjaW9uIFIgSUEvTWV4aWNvL2RlbnVlXzAwXzcyXzFfY3N2L2Nvbmp1bnRvX2RlX2RhdG9zL2RlbnVlX2luZWdpXzcyXzEuY3N2IikKCmRmMl9yZXN0YXVyYW50ZXMgPC0gcmVhZC5jc3YoIi9Vc2Vycy9odW1iZXJ0b2NzL0Rlc2t0b3AvVGVjL0NvbmNlbnRyYWNpw7NuIElBL00yX1Byb2dyYW1hY2lvbiBSIElBL01leGljby9kZW51ZV8wMF83Ml8yX2Nzdi9jb25qdW50b19kZV9kYXRvcy9kZW51ZV9pbmVnaV83Ml8yLmNzdiIpCgoKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjp3aGl0ZTsiPiBMaW1waWV6YSBkZSBkYXRvcyA8L3NwYW4+CgoKYGBge3J9CgpsaWJyYXJ5KGRwbHlyKQoKZGZfcmVzdGF1cmFudGVzIDwtIGJpbmRfcm93cyhkZjFfcmVzdGF1cmFudGVzLCBkZjJfcmVzdGF1cmFudGVzKQoKdW5pcXVlKGRmX3Jlc3RhdXJhbnRlcyRlbnRpZGFkKQoKYGBgCmBgYHtyfQoKbGlicmFyeShzdHJpbmdpKQpsaWJyYXJ5KHN0cmluZ3IpCgpkZl9yZXN0YXVyYW50ZXMgPC0gZGZfcmVzdGF1cmFudGVzICU+JQogIG11dGF0ZShlbnRpZGFkID0gc3RyaV90cmFuc19nZW5lcmFsKGVudGlkYWQsICJMYXRpbi1BU0NJSSIpLAogICAgICAgICBlbnRpZGFkID0gc3RyX3RvX3RpdGxlKGVudGlkYWQpKQoKdW5pcXVlKGRmX3Jlc3RhdXJhbnRlcyRlbnRpZGFkKQoKYGBgCmBgYHtyfQoKbGlicmFyeShkcGx5cikKCmRmX3Jlc3RhdXJhbnRlcyA8LSBkZl9yZXN0YXVyYW50ZXMgJT4lCiAgbXV0YXRlKGVudGlkYWQgPSByZWNvZGUoZW50aWRhZCwKICAgICJDb2FodWlsYSBEZSBaYXJhZ296YSIgPSAiQ29haHVpbGEiLAogICAgIkNpdWRhZCBEZSBN77+9WGljbyIgPSAiQ2l1ZGFkIGRlIE3DqXhpY28iLAogICAgIk3vv71YaWNvIiA9ICJNw6l4aWNvIiwKICAgICJNaWNob2Fj77+9TiBEZSBPY2FtcG8iID0gIk1pY2hvYWPDoW4iLAogICAgIk51ZXZvIExl77+9TiIgPSAiTnVldm8gTGXDs24iLAogICAgIlF1ZXLvv71UYXJvIiA9ICJRdWVyw6l0YXJvIiwKICAgICJTYW4gTHVpcyBQb3Rvc++/vSIgPSAiU2FuIEx1aXMgUG90b3PDrSIsCiAgICAiVmVyYWNydXogRGUgSWduYWNpbyBEZSBMYSBMbGF2ZSIgPSAiVmVyYWNydXoiLAogICAgIll1Y2F077+9TiIgPSAiWXVjYXTDoW4iCiAgKSkKCgp1bmlxdWUoZGZfcmVzdGF1cmFudGVzJG5vbWJyZV9hY3QpCgpjYWZldGVyaWFzIDwtIGRmX3Jlc3RhdXJhbnRlcyAlPiUKICBmaWx0ZXIobm9tYnJlX2FjdCA9PSAiQ2FmZXRlclx4ZWRhcywgZnVlbnRlcyBkZSBzb2RhcywgbmV2ZXJceGVkYXMsIHJlZnJlc3F1ZXJceGVkYXMgeSBzaW1pbGFyZXMiKQoKCmNhZmV0ZXJpYXNfTkwgPC0gY2FmZXRlcmlhcyAlPiUKICBmaWx0ZXIoZW50aWRhZCA9PSAiTnVldm8gTGXvv71OIikKCgpgYGAKCmBgYHtyfQpjYWZldGVyaWFzX3Bvcl9lc3RhZG8gPC0gY2FmZXRlcmlhcyAlPiUKICBncm91cF9ieShlbnRpZGFkKSAlPiUKICBzdW1tYXJpc2UodG90YWxfY2FmZXRlcmlhcyA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikKCmBgYAoKCgoKCgojIDxzcGFuIHN0eWxlPSJjb2xvcjp3aGl0ZTsiPiBQYXNvIDMuIC0gPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzdW1tYXJ5KGNhZmV0ZXJpYXNfcG9yX2VzdGFkbykKc3RyKGNhZmV0ZXJpYXNfcG9yX2VzdGFkbykKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjp3aGl0ZTsiPiBQYXNvIDQuIEVzY2FsYXIgbG9zIGRhdG9zIDwvc3Bhbj4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBTw7NsbyBzaSBubyBlc3RhbiBlbiBsYSBtaXNtYSBlc2NhbGEKZGF0b3NfZXNjYWxhZG9zIDwtIHNjYWxlKGNhZmV0ZXJpYXNfcG9yX2VzdGFkbyR0b3RhbF9jYWZldGVyaWFzKQpgYGAKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOndoaXRlOyI+IFBhc28gNS4gRGV0ZXJtaW5hciBuw7ptZXJvIGRlIGdydXBvcyA8L3NwYW4+CmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgU2llbXByZSBlcyB1biB2YWxvciBpbmljaWFsICJjdWFscXVpZXJhIiwgbHVlZ28gc2Ugb3B0aW1pemEuCmdydXBvczEgPC0gMwogCmBgYAoKIyA8c3BhbiBzdHlsZT0iY29sb3I6d2hpdGU7Ij4gUGFzbyA2LiBHZW5lcmFyIGxvcyBncnVwb3MgPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzZXQuc2VlZCgxMjMpCmNsdXN0ZXJzMSA8LSBrbWVhbnMoZGF0b3NfZXNjYWxhZG9zLCBncnVwb3MxKQpjbHVzdGVyczEKIApgYGAKIyA8c3BhbiBzdHlsZT0iY29sb3I6d2hpdGU7Ij4gUGFzbyA3LiBPcHRpbWl6YXIgZWwgbsO6bWVybyBkZSBncnVwb3MgPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzZXQuc2VlZCgxMjMpCm9wdGltaXphY2lvbjEgPC0gY2x1c0dhcChkYXRvc19lc2NhbGFkb3MsIEZVTj1rbWVhbnMsIG5zdGFydCA9IDEsIEsubWF4PTEwKQojIEVMIEsgbWVhbnMgbm9ybWFsbWVudGUgZXMgMTAsIGVuIGVzdGUgZWplcmNpY2lvIGFsIHNlciA4IGRhdG9zLCBzZSBkZWrDsyBlbiA3LgpwbG90KG9wdGltaXphY2lvbjEsIHhsYWI9Ik7Dum1lcm8gZGUgY2zDunN0ZXJzIGsiKQojIFNlbGVjY2lvbmEgY29tbyDDs3B0aW1vIGVsIHByaW1lciBwdW50byBtw6FzIGFsdG8KIyBTaW1pbGFyIGEgbGEgdMOpY25pY2EgZGVsIGNvZG8gcGVybyBlc3RhIGVzIG3DoXMgbm90YWJsZQoKIApgYGAKCgojIDxzcGFuIHN0eWxlPSJjb2xvcjp3aGl0ZTsiPiBQYXNvIDguIEdyYWZpY2FyIGxvcyBncnVwb3MgPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojZnZpel9jbHVzdGVyKGRhdG9zX2VzY2FsYWRvcywgZGF0YT1jb29yZHNfcmVzdCkKCiAKYGBgCgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6d2hpdGU7Ij4gUGFzbyA5LiBBZ3JlZ2FyIEdydXBvcyBhIGxhIEJhc2UgZGUgRGF0b3MgPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpkZjFfY2x1c3RlciA8LSBjYmluZChjYWZldGVyaWFzX3Bvcl9lc3RhZG8sIGNsdXN0ZXIgPSBjbHVzdGVyczEkY2x1c3RlcikKaGVhZChkZjFfY2x1c3RlcikKIApgYGAKCg==