Introducción

Este informe presenta un análisis estadístico detallado de un conjunto de datos sobre viviendas en la ciudad de Cali. El objetivo principal es identificar patrones y relaciones clave que puedan guiar decisiones estratégicas para una empresa inmobiliaria, optimizando la inversión y maximizando los beneficios en un entorno competitivo y cambiante.

Metodología

Se emplearon diversas técnicas estadísticas y de análisis de datos:

  • Análisis Exploratorio de Datos (EDA)
  • Análisis de Componentes Principales (PCA).
  • Análisis de Conglomerados
  • Análisis de Correspondencia Múltiple (MCA)

Análisis Exploratorio de Datos

Se realizó una exploración inicial para identificar valores atípicos, distribuciones de variables y relaciones básicas entre características.

# Exploración inicial de los datos
library(paqueteMODELOS)
data("vivenda")
data <- vivienda

Limpieza de datos

Manejo de datos faltantes

Como se evidencia en el anexo 1, varias de las columnas presentan valores faltantes. Dichos datos deben ser tratados para asegurarse que todos los análisis presenten resultados confiables.

Para ello, se harán una serie de modificaciones. Para las variables de habitaciones y baños que tienen un valor de 0, se reemplazarán por un valor nulo, al asumir que es poco probable que una vivienda no tenga habitaciones o baños, sino que posiblemente el valor no se haya registrado correctamente.

Por tanto, para las variables de precio, área construida, cantidad de baños y de habitaciones, se eliminarán los registros faltantes, pasando de 8.322 registros a 8.243.

Luego, se modificarán los valores vacios de la variable parqueaderos, para reemplazarlos por 0. Ya que asumimos que si no se registró un valor para esta variable, es porque no habían parqueaderos en dicho inmueble.

Finalmente, se definirá codificación del tipo de datos de algunos campos, para evitar errores posteriores. En el anexo 2 se puede ver el resumen de los datos luego de la limpieza.

no_na_data <- data %>%
  distinct(id, .keep_all = TRUE) %>% # Eliminar duplicados basados en la columna id
  mutate(piso = as.numeric(piso),
         zona = as.factor(zona),
         tipo = as.factor(tipo),
         barrio = as.factor(barrio),
         parqueaderos = ifelse(is.na(parqueaderos), 0, parqueaderos),
         habitaciones = ifelse(habitaciones == 0, NA, habitaciones),
         banios = ifelse(banios == 0, NA, banios)) %>%
  drop_na(preciom, areaconst, banios, habitaciones)

Estandarización de las variables numéricas

Debido a las diferencias entre los rangos de las variables númericas, se recomienda estandarizarlas, de manera que valores muy grandes en unas variables, no acaparen a otros con conjuntos de datos más pequeños.

# Estandarización de las variables numéricas
datos_numericos <- no_na_data %>% select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato)
datos_estandarizados <- scale(datos_numericos)

Gráficos de resumen

  • Boxplot de precios por zonas: Se evidencia una gran cantidad de datos atípicos en la Zona Norte y Sur, lo que nos da a entender que hay varias viviendas con precio por m2 muy superior al promedio.
  • ggplot(no_na_data, aes(x = zona, y = preciom, fill = zona)) +
      geom_boxplot() +
      theme_minimal()

  • Gráfico de dispersión (Precio vs Área Construida): Se puede notar que hay una gran variabilidad en los precios de las viviendas para áreas construidad similares, lo que nos podría indicar que otros factores, además del área construida, inciden en el precio de las viviendas.
  • ggplot(no_na_data, aes(x = areaconst, y = preciom, color = zona)) +
      geom_point(alpha = 0.6, size = 3) +
      theme_minimal() +
      labs(title = "Relación entre Área Construida y Precio",
           x = "Área Construida (m²)", y = "Precio")

  • Histograma de distribución de precios: La distribución muestra un sesgo hacia la derecha, indicando que la mayoría de viviendas se encuentran agrupadas entre los 0 y los 1.000.
  • ggplot(no_na_data, aes(x = preciom, fill = zona)) +
      geom_histogram(bins = 30, alpha = 0.7, position = "identity") +
      theme_minimal() +
      labs(title = "Distribución de Precios de Propiedades",
           x = "Precio", y = "Frecuencia")

  • Boxplot por estrato socioeconómico: Se evidencia que hay distintas viviendas con precios muy por encima del promedio para todos los estratos económicos, exceptuando el estrato 6. Lo que indica que la asignación de estrato puede no ser tan precisa o puede no estar directamente relacionada con el valor de la vivienda.
  • ggplot(no_na_data, aes(x = as.factor(estrato), y = preciom, fill = as.factor(estrato))) +
      geom_boxplot() +
      theme_minimal() +
      labs(title = "Distribución de Precios por Estrato Socioeconómico", x = NULL, y = "Precio", fill="Estrato")

Análisis de Componentes Principales (PCA)

El PCA se usa para identificar las variables que más contribuyen a la variabilidad de los datos. Se interpretarán los componentes principales y se analizarán los individuos más extremos en el espacio reducido.

A continuacion se presenta la matriz de rotacion, que muestra la manera en que cada variable contribuye a cada componente principal. Y luego se encuentra un gráfico de barras que visualiza la varianza por cada uno de los componentes principales.

com_pca <- prcomp(datos_estandarizados)
kable(com_pca$rotation, format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
PC1 PC2 PC3 PC4 PC5 PC6
preciom 0.4764696 0.1861367 -0.0656902 0.3696122 -0.2996181 0.7124819
areaconst 0.4452096 -0.2455056 0.1055181 0.6628264 0.3236600 -0.4316096
parqueaderos 0.4075145 0.2649129 0.7893587 -0.3660649 0.0621465 -0.0529177
banios 0.4690063 -0.1798160 -0.2940206 -0.2909371 -0.6383220 -0.4112807
habitaciones 0.2867890 -0.6774635 -0.1127307 -0.3957219 0.4074211 0.3514246
estrato 0.3263162 0.5861831 -0.5121594 -0.2209170 0.4776652 -0.1031087
fviz_eig(com_pca, addlabels = TRUE)

Podemos identificar que el componente 1 (CP1) explica casi el 60% de la variabilidad de los datos. Y, junto con el componente 2 (CP2), explican cerca del 80% de dicha variabilidad. Por tanto, estos 2 componentes deberían ser suficientes para describir los datos.

Además, para el CP1, las variables que más contribuyen son el precio, el área construida, los baños y los parqueaderos, todas de manera positiva. Y para el CP2, serían las habitaciones y el estrato, la primera de forma negativa y la segunda positiva.

Resultados del PCA:

Aquí se podrá visualizar tanto la relación entre las variables como la distribución de las observaciones (individuos) en el nuevo espacio dimensional reducido.

# Aplicación del PCA
pca_result <- PCA(datos_estandarizados, graph = FALSE)

# Identificación de los 4 registros más extremos
dim_coords <- as.data.frame(pca_result$ind$coord)

extremos_indices <- c(which.max(dim_coords$Dim.1), 
                      which.min(dim_coords$Dim.1), 
                      which.max(dim_coords$Dim.2), 
                      which.min(dim_coords$Dim.2))

extremos <- dim_coords[extremos_indices, ]
extremos$ID <- no_na_data$id[extremos_indices]

fviz_pca_var(pca_result, col.var = "contrib", repel=TRUE)

En este gráfico, la dirección de las flechas indica cómo las variables contribuyen con los componentes, su longitud indica su contribución a la varianza total y su ángulo muestra cuales variables se encuentran correlacionadas.

Por tanto, vemos que el area construida y la cantidad de baños se encuentran positivamente correlacionadas, al igual que el precio y la cantidad de parqueaderos del inmueble. Y que la cantidad de habitaciones y el estrato parecen no encontrarse correlacionadas.

fviz_pca_ind(pca_result, geom.ind = "point", col.ind = no_na_data$zona) +
  geom_point(data = extremos, aes(x = Dim.1, y = Dim.2), 
             color = "red", size = 4, shape = 17) +
  geom_text(data = extremos, aes(x = Dim.1, y = Dim.2, label = ID), 
            vjust = -1, hjust = 0.5, color = "red", size = 4) +
  ylim(-4,7)

En este caso, notamos que la mayoría de los datos se concentran alrededor del centro, lo que sugiere que la mayoría de registros comparten características similares.

A pesar de ello, la zona Sur tiende a dispersarse bastante a la derecha, lo que podría indicar que presenta una alta variabilidad. Las zonas Norte, Oriente y Centro parecen agruparse mas hacia la parte superior del plano, mientras que la zona Oeste se agrupa mas en el inferior. Esto podria indicarnos de las posibles similitudes en las variables que caracterizan a las distintas zonas.

kable(no_na_data[extremos_indices, ], format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud
5684 Zona Sur NA 6 1800 1586 10 4 5 Casa ciudad jardín -76.53798 3.35961
967 Zona Norte NA 3 92 60 0 1 1 Apartamento acopi -76.50679 3.46582
534 Zona Norte 3 3 370 1440 1 4 10 Casa villa del prado -76.49815 3.46343
7505 Zona Sur 2 6 1600 330 10 5 3 Casa pance -76.55000 3.33500

Por último, se analizarán las 4 observaciones mas alejadas del centro para entender un poco mejor el sentido de los ejes.

Por ejemplo, para los registros mas alejados en el eje x, el registro 967 tiene un área construida de 1.586m2 y 4 baños, mientras que el registro 5.684 tiene un área de 60m2 y solo 1 baño, lo que refleja la correlación entre estas 2 variables.

Y para los registros más alejados en el eje y, el registro 534 tiene un precio de 370 por m2 y 1 parqueadero, mientras que el registro 7.505 tiene un precio de 1.600 por m2 y 10 parqueaderos, lo que también refleja la correlación entre estas 2 variables.

Análisis de Conglomerados

Se utiliza para identificar grupos homogéneos dentro del conjunto de datos, basándose en características similares. Esta técnica permite segmentar el mercado inmobiliario en diferentes clústeres, lo que facilita la identificación de patrones de comportamiento, tendencias de precios y perfiles de propiedades con características comunes.

Para este caso se evaluaron 2 enfoques de agrupación, donde cada uno destaca en unos aspectos pero presenta falencias en otros. En ambos casos, se calculó la cantidad óptima de clústeres (anexo 4 y 5) con un gráfico de evaluación que busca identificar el número que maximiza el ancho promedio de la silueta.

Metodo Jerárquico

# --- Análisis de Conglomerados (Clustering) ---
# Determinación del número óptimo de clusters
dist_emp <- dist(datos_estandarizados, method = "euclidean")
hc_emp <- hclust(dist_emp, method = 'average')

cluster_assignments <- cutree(hc_emp, k = 3)
datos_plot <- as.data.frame(datos_estandarizados)
datos_plot$cluster <- factor(cluster_assignments)
ggplot(datos_plot, aes(x = datos_plot[,1], y = datos_plot[,2], color = cluster)) +
  geom_point(size = 3, alpha = 0.8) +             # Puntos con mayor tamaño y algo de transparencia
  labs(title = "Clustering Jerárquico (Enlace Promedio)",
       x = "Variable 1",
       y = "Variable 2",
       color = "Clúster") +
  theme_minimal() +                               # Tema limpio
  theme(legend.position = "right") 

silhouette_emp <- silhouette(cluster_assignments, dist_emp)

En este método, lo primero que evidenciamos es que el clúster 1 tiene la mayoria de las observaciones (8.235), mientras que los clúster 2 y 3 solo tienen 3 y 5 observaciones, respectivamente. Lo cual refleja un desbalanceo en la formación de los clústeres, posiblemente debido a valores atípicos.

El clúster 1 se encuentra parcialmente compacto, lo que podria demostrar una buena cohesión interna para los valores más bajos de la variable. También, con respecto a los clústeres 2 y 3, se evidencia una buena separación entre los grupos.

A pesar de lo anterior, el valor promedio del coeficiente de Silhouette es 0.6932615, lo que refleja un buen agrupamiento.

Metodo k-means

km_res <- kmeans(datos_estandarizados, centers = 2, nstart = 25)
silhouette_kmeans <- silhouette(km_res$cluster, dist_emp)
fviz_cluster(km_res, data = datos_estandarizados)

no_na_data$cluster <- as.factor(datos_plot$cluster)
#no_na_data$cluster <- as.factor(km_res$cluster)

El análisis de K-means con 2 clústeres muestra una separación moderada entre los grupos, con algunas observaciones en la frontera entre clústeres, lo que sugiere cierta ambigüedad en la asignación. El clúster 1 contiene la mayor cantidad de los datos, los cuales se encuentran bastante agrupados cerca del centro del plano pero se empiezan a dispersar a medida que se alejan, mostrando que algunas observaciones están en el límite entre clústeres, posiblemente debido a un agrupamiento débil. Mientras que para el clúster 2, a pesar de que los datos se encuentran mucho más agrupados, el gráfico de silueta (anexo 7) muestra valores cercanos a 0, e incluso algunos negativos, lo que indicaría que las observaciones podrían estar mal asignadas.

Por último, el ancho promedio de la silueta es de 0.3992222, lo que indica una estructura de clústeres débil, posiblemente mejorable.

Analisis de Correspondencia Múltiple (MCA)

Se utilizó para examinar las asociaciones entre variables categóricas (tipo de vivienda y zona). La idea es identificar patrones y asociaciones para descubrir cómo se relacionan los factores, facilitando la segmentación de propiedades y la identificación de tendencias de preferencia en el mercado.

library(dplyr)

subset_vivienda <- no_na_data %>%
  select(zona, tipo)
# --- Análisis de Correspondencia Múltiple (MCA) ---

# Aplicación del Análisis de Correspondencia Múltiple (MCA)
mca_result <- MCA(subset_vivienda, graph = FALSE)

fviz_screeplot(mca_result, addlabels = TRUE, ylim = c(0, 80), ncp = 5)+ggtitle("")+
ylab("Porcentaje de varianza explicado (top 5)") + xlab("Ejes")

Podemos evidenciar que las primeras 2 dimensiones explican casi el 45% de la varianza de estas 2 variables, por tanto estas dimensiones deberían reflejar correctamente la variabilidad de los datos. Esto información tambien se complementa con el anexo 8, que contiene, además, los valores propios para cada dimensión.

# Visualización de resultados del MCA
fviz_mca_var(mca_result, 
             repel = TRUE,          # Evita superposición de etiquetas
             col.var = "cos2",      # Colorea según calidad de representación
             gradient.cols = c("blue", "purple", "red")) # Escala de colo

Aquí podemos, por un lado, identificar la calidad de la representación de cada categoría, de manera que las zonas Oriente y Oeste se encuentran claramente caracterizadas por el tipo de vivienda, indicando que la mayoria de inmuebles en la zona Oriente son casas y en la Zona Oeste son apartamentos. Mientras que el resto de las zonas no se encuentran tan bien representadas, debido a que su distribución por tipo de vivienda posiblemente sea más heterogénea.

fviz_mca_var(mca_result, choice = "mca.cor",
               repel = TRUE,
               ggtheme = theme_grey(),ggtitle="")

Finalmente, de acuerdo a este grafico, se identifica que la primera dimensión explica bien el tipo de vivienda, mientras que la segunda dimension parece explicar un poco mejor la zona urbana.

Conclusiones

Con base en los hallazgos del análisis estadístico realizado sobre los datos de viviendas en Cali, se puede concluir que existen patrones significativos que permiten entender mejor la dinámica del mercado inmobiliario en la ciudad. El análisis exploratorio reveló la presencia de valores atípicos en precios por metro cuadrado, especialmente en las zonas Norte y Sur, lo que sugiere una alta variabilidad en dichas áreas. Además, se identificó que el precio de las viviendas no depende exclusivamente del área construida, sino que también influyen factores como la cantidad de baños, parqueaderos y el estrato socioeconómico.

El análisis de componentes principales (PCA) destacó que el precio, el área construida, los baños y los parqueaderos son las variables que más explican la variabilidad del mercado. Los clústeres formados mediante análisis jerárquico y k-means evidenciaron la existencia de grupos de propiedades con características similares, con distintos tipos de agrupaciones que dependerán de las necesidades. Finalmente, el análisis de correspondencia múltiple (MCA) mostró asociaciones claras entre el tipo de vivienda y la zona, siendo más homogéneas en zonas específicas como Oriente y Oeste.

Con base en los hallazgos del análisis, se pueden plantear las siguientes recomendaciones estratégicas para optimizar la inversión inmobiliaria y maximizar los beneficios:

  1. Segmentación del Mercado Inmobiliario: Las zonas Norte y Sur presentan una gran dispersión en los precios por m², lo que sugiere oportunidades para identificar propiedades subvaloradas o con potencial de revalorización. Mientras que las zonas Oriente y Oeste muestran asociaciones claras con tipos específicos de vivienda (casas y apartamentos, respectivamente), por lo que es recomendable adaptar la oferta de acuerdo con estas preferencias para mejorar la penetración en el mercado.

  2. Optimización de la Estrategia de Precios: Identificar y analizar inmuebles con precios extremadamente altos o bajos para comprender si se trata de oportunidades de inversión o de sobrevaloraciones que podrían representar un riesgo financiero.

  3. Mejorar la Estrategia de Segmentación de Clientes: Aunque el análisis de conglomerados mostró una estructura de clústeres débil, se pueden utilizar los grupos identificados como base para diseñar estrategias comerciales personalizadas, enfocadas en perfiles de propiedades con características similares. Además, se recomienda considerar el uso de técnicas de clustering más avanzadas o la inclusión de nuevas variables para mejorar la cohesión y separación de los grupos identificados.

  4. Estrategias de Desarrollo Inmobiliario: Las viviendas con más baños y parqueaderos tienden a tener precios más altos, por lo que desarrollar proyectos que ofrezcan más atributos podría generar mayores retornos de inversión. Igualmente se recomienda invertir en diferentes tipos de propiedades y zonas para mitigar riesgos asociados a fluctuaciones en el mercado inmobiliario.

Anexos

Anexo 1 - Resumen de los datos: Original

kable(summary(data), format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud
Min. : 1 Length:8322 Length:8322 Min. :3.000 Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000 Min. : 0.000 Length:8322 Length:8322 Min. :-76.59 Min. :3.333
1st Qu.:2080 Class :character Class :character 1st Qu.:4.000 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54 1st Qu.:3.381
Median :4160 Mode :character Mode :character Median :5.000 Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000 Median : 3.000 Mode :character Mode :character Median :-76.53 Median :3.416
Mean :4160 NA NA Mean :4.634 Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111 Mean : 3.605 NA NA Mean :-76.53 Mean :3.418
3rd Qu.:6240 NA NA 3rd Qu.:5.000 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000 3rd Qu.: 4.000 NA NA 3rd Qu.:-76.52 3rd Qu.:3.452
Max. :8319 NA NA Max. :6.000 Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000 Max. :10.000 NA NA Max. :-76.46 Max. :3.498
NA’s :3 NA NA NA’s :3 NA’s :2 NA’s :3 NA’s :1605 NA’s :3 NA’s :3 NA NA NA’s :3 NA’s :3
kable(str(data), format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id          : num [1:8322] 1147 1169 1350 5992 1212 ...
##  $ zona        : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
##  $ piso        : chr [1:8322] NA NA NA "02" ...
##  $ estrato     : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
##  $ preciom     : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
##  $ areaconst   : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
##  $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
##  $ banios      : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
##  $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
##  $ tipo        : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
##  $ barrio      : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
##  $ longitud    : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ latitud     : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   zona = col_character(),
##   ..   piso = col_character(),
##   ..   estrato = col_double(),
##   ..   preciom = col_double(),
##   ..   areaconst = col_double(),
##   ..   parqueaderos = col_double(),
##   ..   banios = col_double(),
##   ..   habitaciones = col_double(),
##   ..   tipo = col_character(),
##   ..   barrio = col_character(),
##   ..   longitud = col_double(),
##   ..   latitud = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Anexo 2 - Resumen de los datos: Corregido

kable(summary(no_na_data), format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud cluster
Min. : 1 Zona Centro : 121 Min. : 1.000 Min. :3.000 Min. : 58.0 Min. : 30 Min. : 0.000 Min. : 1.000 Min. : 1.000 Apartamento:5074 valle del lili:1008 Min. :-76.59 Min. :3.333 1:8235
1st Qu.:2080 Zona Norte :1888 1st Qu.: 2.000 1st Qu.:4.000 1st Qu.: 220.0 1st Qu.: 80 1st Qu.: 1.000 1st Qu.: 2.000 1st Qu.: 3.000 Casa :3169 ciudad jardín : 513 1st Qu.:-76.54 1st Qu.:3.381 2: 3
Median :4164 Zona Oeste :1188 Median : 3.000 Median :5.000 Median : 330.0 Median : 122 Median : 1.000 Median : 3.000 Median : 3.000 NA pance : 406 Median :-76.53 Median :3.416 3: 5
Mean :4161 Zona Oriente: 345 Mean : 3.768 Mean :4.637 Mean : 433.3 Mean : 174 Mean : 1.488 Mean : 3.128 Mean : 3.634 NA la flora : 361 Mean :-76.53 Mean :3.418 NA
3rd Qu.:6244 Zona Sur :4701 3rd Qu.: 5.000 3rd Qu.:5.000 3rd Qu.: 540.0 3rd Qu.: 227 3rd Qu.: 2.000 3rd Qu.: 4.000 3rd Qu.: 4.000 NA santa teresita: 261 3rd Qu.:-76.52 3rd Qu.:3.452 NA
Max. :8319 NA Max. :12.000 Max. :6.000 Max. :1999.0 Max. :1745 Max. :10.000 Max. :10.000 Max. :10.000 NA el caney : 206 Max. :-76.46 Max. :3.498 NA
NA NA NA’s :2593 NA NA NA NA NA NA NA (Other) :5488 NA NA NA

Anexo 3 - Matriz de covarianzas

cov_matrix <- cov(datos_numericos, use = "complete.obs")
kable(round(cov_matrix), format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
preciom areaconst parqueaderos banios habitaciones estrato
preciom 108192 32234 263 318 129 207
areaconst 32234 20255 87 135 111 41
parqueaderos 263 87 2 1 0 1
banios 318 135 1 2 1 1
habitaciones 129 111 0 1 2 0
estrato 207 41 1 1 0 1
corrplot::corrplot.mixed(cor(datos_numericos), lower="ellipse", upper="number", order="hclust")

Anexo 4 - Cantidad optima de clústers: Método jerárquico

fviz_nbclust(datos_estandarizados, hcut, method = "silhouette")

Anexo 5 - Cantidad optima de clústers: Método k-means

fviz_nbclust(datos_estandarizados, kmeans, method = "silhouette")

Anexo 6 - Grafico de Silueta y tamaños de los clústeres: Método jerárquico

sil_emp_plot <- fviz_silhouette(silhouette_emp, print.summary = FALSE)
sil_emp_plot

datos_silueta <- as.data.frame(silhouette_emp)

# Calcular el tamaño del cluster y el ancho promedio de la silueta por cluster
resumen_clusters <- aggregate(
  cbind(size = cluster, ave_sil_width = sil_width) ~ cluster,
  data = datos_silueta,
  FUN = function(x) c(length(x), mean(x))
)

# Ajustar el data.frame para que quede bien formateado
resumen_clusters <- datos_silueta %>%
  group_by(cluster) %>%
  summarise(
    Tamaño = n(),                                # Tamaño del cluster
    Ancho_Promedio_Silueta = round(mean(sil_width), 3)  # Ancho promedio de la silueta
  ) %>%
  ungroup()

# Mostrar la tabla de resultados
kable(resumen_clusters, format = "html", caption = "Tamaño de Clusters y Ancho Promedio de Silueta") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
Tamaño de Clusters y Ancho Promedio de Silueta
cluster Tamaño Ancho_Promedio_Silueta
1 8235 0.693
2 3 0.330
3 5 0.537

Anexo 7 - Grafico de Silueta y tamaños de los clústeres: Método k-means

# Visualización de clusters
fviz_silhouette(silhouette_kmeans, print.summary = FALSE)

summary_silhouette <- summary(silhouette_kmeans)

#summary_silhouette$clus.sizes = Tamaño de los clusters
#summary_silhouette$clus.avg.widths = Ancho promedio de la silueta por cluster

# Crear el data frame para la tabla
resumen_clusters <- data.frame(
  Cluster = names(summary_silhouette$clus.sizes),
  Tamaño = summary_silhouette$clus.sizes,
  Ancho_Promedio_Silueta = round(summary_silhouette$clus.avg.widths, 3)
)

# Mostrar la tabla con kable
kable(resumen_clusters, format = "html", caption = "Tamaño de Clusters y Ancho Promedio de Silueta (K-means)") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
Tamaño de Clusters y Ancho Promedio de Silueta (K-means)
Cluster Tamaño.cl Tamaño.Freq Ancho_Promedio_Silueta
1 1 5574 0.517
2 2 2669 0.154

Anexo 8 - Tabla de valores propios

kable(head(mca_result$eig,5), format = "html") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
eigenvalue percentage of variance cumulative percentage of variance
dim 1 0.6444675 25.7787 25.7787
dim 2 0.5000000 20.0000 45.7787
dim 3 0.5000000 20.0000 65.7787
dim 4 0.5000000 20.0000 85.7787
dim 5 0.3555325 14.2213 100.0000