1 Introducción

En el presente trabajo se realiza un análisis estadístico multivariado sobre datos de viviendas urbanas, con el fin de apoyar la toma de decisiones de una empresa inmobiliaria. Los datos provienen del paquete paqueteMODELOS y fueron recopilados originalmente mediante web scraping de la plataforma OLX.

El objetivo es aplicar tres técnicas principales: Análisis de Componentes Principales (ACP), Análisis de Conglomerados (Clustering) y Análisis de Correspondencia, para identificar patrones y segmentaciones en el mercado que resulten útiles a nivel estratégico.

1.1 Carga de librerías y datos

# devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
library(paqueteMODELOS)
library(tidyverse)
library(factoextra)
library(FactoMineR)
library(corrplot)
library(cluster)
library(NbClust)
library(knitr)
library(kableExtra)
library(gridExtra)
library(scales)
library(RColorBrewer)

data("vivienda")

2 Exploración inicial de los datos

Antes de aplicar las técnicas multivariadas, es necesario entender la estructura y distribución de las variables disponibles.

2.1 Estructura del dataset

str(vivienda)
## 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>
cat("El dataset tiene", nrow(vivienda), "registros y", ncol(vivienda), "variables.\n")
## El dataset tiene 8322 registros y 13 variables.

Se cuenta con 8,322 propiedades y 13 variables. Las variables numéricas principales son: precio (en millones), área construida, número de parqueaderos, baños, habitaciones y estrato socioeconómico. Las categóricas incluyen zona, tipo de vivienda (Casa/Apartamento) y barrio.

2.2 Resumen estadístico

vivienda %>%
  select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato) %>%
  summary() %>%
  kable(caption = "Resumen estadístico de las variables numéricas") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
Resumen estadístico de las variables numéricas
preciom areaconst parqueaderos banios habitaciones estrato
Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000 Min. : 0.000 Min. :3.000
1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000 1st Qu.: 3.000 1st Qu.:4.000
Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000 Median : 3.000 Median :5.000
Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111 Mean : 3.605 Mean :4.634
3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000 3rd Qu.: 4.000 3rd Qu.:5.000
Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000 Max. :10.000 Max. :6.000
NA’s :2 NA’s :3 NA’s :1605 NA’s :3 NA’s :3 NA’s :3

Del resumen se observa que el precio promedio es de aproximadamente 434 millones, con una mediana de 330 millones, lo que indica una distribución asimétrica hacia la derecha (hay propiedades muy costosas que jalan el promedio). El área construida también muestra este comportamiento, con una media de 175 m² pero mediana de 123 m². Los estratos van del 3 al 6, con mediana en 5.

2.3 Datos faltantes

na_count <- colSums(is.na(vivienda))
na_df <- data.frame(Variable = names(na_count), Faltantes = na_count, 
                     Porcentaje = round(na_count / nrow(vivienda) * 100, 2))
na_df %>%
  filter(Faltantes > 0) %>%
  kable(caption = "Variables con valores faltantes", row.names = FALSE) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Variables con valores faltantes
Variable Faltantes Porcentaje
id 3 0.04
zona 3 0.04
piso 2638 31.70
estrato 3 0.04
preciom 2 0.02
areaconst 3 0.04
parqueaderos 1605 19.29
banios 3 0.04
habitaciones 3 0.04
tipo 3 0.04
barrio 3 0.04
longitud 3 0.04
latitud 3 0.04

Hay dos variables con cantidad importante de datos faltantes: piso (31.7%) y parqueaderos (19.3%). El resto de las variables tienen menos del 0.04% de faltantes, lo cual no es preocupante. Para los análisis se eliminarán las filas con NA en las variables utilizadas.

2.4 Distribuciones

ggplot(vivienda, aes(x = preciom)) +
  geom_histogram(aes(y = after_stat(density)), bins = 50, fill = "#2c7fb8", color = "white", alpha = 0.8) +
  geom_density(color = "#d95f0e", linewidth = 1) +
  labs(title = "Distribución del Precio de Viviendas",
       subtitle = "Precio en millones de pesos",
       x = "Precio (millones)", y = "Densidad") +
  theme_minimal()
Distribución del precio

Distribución del precio

La distribución del precio es claramente asimétrica positiva: la mayoría de propiedades se concentran entre 100 y 500 millones, pero existe una cola larga hacia la derecha con propiedades que superan los 1,000 millones.

ggplot(vivienda, aes(x = areaconst)) +
  geom_histogram(aes(y = after_stat(density)), bins = 50, fill = "#7570b3", color = "white", alpha = 0.8) +
  geom_density(color = "#d95f0e", linewidth = 1) +
  labs(title = "Distribución del Área Construida",
       x = "Área construida (m²)", y = "Densidad") +
  theme_minimal()
Distribución del área construida

Distribución del área construida

El área construida sigue un patrón similar al precio. La mayoría de inmuebles tienen entre 50 y 250 m², pero hay algunos que superan los 1,000 m².

2.5 Variables categóricas

p1 <- ggplot(vivienda, aes(x = fct_infreq(zona), fill = zona)) +
  geom_bar(alpha = 0.85) +
  labs(title = "Distribución por Zona", x = "Zona", y = "Frecuencia") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1), legend.position = "none")

p2 <- ggplot(vivienda, aes(x = factor(estrato), fill = factor(estrato))) +
  geom_bar(alpha = 0.85) +
  labs(title = "Distribución por Estrato", x = "Estrato", y = "Frecuencia") +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal() +
  theme(legend.position = "none")

p3 <- ggplot(vivienda, aes(x = tipo, fill = tipo)) +
  geom_bar(alpha = 0.85) +
  labs(title = "Distribución por Tipo", x = "Tipo de vivienda", y = "Frecuencia") +
  theme_minimal() +
  theme(legend.position = "none")

grid.arrange(p1, p2, p3, ncol = 3)

La Zona Sur concentra la mayor cantidad de ofertas, seguida de la Zona Norte. En cuanto al estrato, el 5 es el más frecuente, seguido del 4. Los apartamentos son más numerosos que las casas en la oferta total.

2.6 Precio por zona y estrato

ggplot(vivienda, aes(x = factor(estrato), y = preciom, fill = factor(estrato))) +
  geom_boxplot(alpha = 0.7, outlier.alpha = 0.3) +
  facet_wrap(~ zona, scales = "free_y") +
  labs(title = "Precio de Viviendas por Estrato y Zona",
       x = "Estrato", y = "Precio (millones)", fill = "Estrato") +
  scale_fill_brewer(palette = "YlOrRd") +
  theme_minimal()
Precio por estrato y zona

Precio por estrato y zona

Se puede ver que, como era de esperarse, a mayor estrato mayor precio. Sin embargo, la dispersión también aumenta en los estratos altos, lo que indica mayor heterogeneidad en esos segmentos. La Zona Sur y Zona Norte son las que presentan mayor variabilidad de precios.

2.7 Correlaciones

vars_num <- vivienda %>%
  select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato) %>%
  drop_na()

cor_matrix <- cor(vars_num)

corrplot(cor_matrix, method = "color", type = "upper", 
         addCoef.col = "black", tl.col = "black", tl.srt = 45,
         col = colorRampPalette(c("#2166ac", "white", "#b2182b"))(100),
         title = "Matriz de Correlaciones", mar = c(0, 0, 2, 0))
Matriz de correlaciones

Matriz de correlaciones

De la matriz de correlaciones destaco lo siguiente:

  • El precio tiene correlación alta con área construida (0.68), parqueaderos (0.69), baños (0.67) y estrato (0.59). Esto tiene sentido: propiedades más grandes y en mejores estratos cuestan más.
  • Las habitaciones tienen una correlación de 0.27 con el precio, que es la más baja entre las variables numéricas. Esto probablemente se debe a que una casa vieja puede tener muchas habitaciones pero no ser costosa.
  • Un dato interesante: habitaciones y estrato tienen correlación negativa (-0.08), lo que sugiere que en estratos altos las viviendas no necesariamente tienen más habitaciones; más bien tienen mayor área y mejores acabados.

Estas correlaciones altas entre varias variables justifican la aplicación del ACP, ya que hay redundancia de información que se puede sintetizar.


3 Análisis de Componentes Principales (ACP)

El ACP es una técnica que permite reducir la dimensionalidad de un conjunto de datos transformando las variables originales (posiblemente correlacionadas) en nuevas variables no correlacionadas llamadas componentes principales. Cada componente captura una porción de la varianza total, de manera decreciente.

Los elementos principales del ACP son:

  • Valores propios (eigenvalues): Indican cuánta varianza explica cada componente. Si es mayor a 1, el componente explica más que una variable original (criterio de Kaiser).
  • Vectores propios / Cargas (loadings): Son los coeficientes que relacionan cada variable original con los componentes. Permiten interpretar qué mide cada componente.
  • Scores: Las coordenadas de cada observación en el nuevo espacio reducido.
  • Varianza acumulada: Permite decidir cuántos componentes retener.

3.1 Preparación y ejecución

Se seleccionan las 6 variables numéricas y se eliminan las observaciones con datos faltantes. Las variables se estandarizan automáticamente (scale.unit = TRUE) porque están en escalas muy diferentes.

datos_acp <- vivienda %>%
  select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato) %>%
  drop_na()

cat("Se utilizan", nrow(datos_acp), "observaciones completas para el ACP.\n")
## Se utilizan 6717 observaciones completas para el ACP.
res_acp <- PCA(datos_acp, scale.unit = TRUE, graph = FALSE)

3.2 Valores propios y varianza explicada

eig_val <- get_eigenvalue(res_acp)
eig_val %>%
  kable(caption = "Valores propios y varianza explicada", digits = 3) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Valores propios y varianza explicada
eigenvalue variance.percent cumulative.variance.percent
Dim.1 3.484 58.063 58.063
Dim.2 1.223 20.385 78.447
Dim.3 0.499 8.325 86.772
Dim.4 0.360 5.992 92.765
Dim.5 0.244 4.073 96.838
Dim.6 0.190 3.162 100.000
fviz_eig(res_acp, addlabels = TRUE, ylim = c(0, 60),
         barfill = "#2c7fb8", barcolor = "#2c7fb8") +
  labs(title = "Gráfico de Sedimentación",
       x = "Componente Principal", y = "% de varianza explicada") +
  theme_minimal()
Scree Plot

Scree Plot

eig_df <- as.data.frame(eig_val)
cat("Varianza explicada por los 2 primeros componentes:", 
    round(sum(eig_df[1:2, "variance.percent"]), 2), "%\n")
## Varianza explicada por los 2 primeros componentes: 78.45 %
cat("Varianza explicada por los 3 primeros componentes:", 
    round(sum(eig_df[1:3, "variance.percent"]), 2), "%\n")
## Varianza explicada por los 3 primeros componentes: 86.77 %

Interpretación: El primer componente principal explica el 58.1% de la varianza total y el segundo el 20.4%, lo que da un acumulado del 78.4% con solo dos componentes. Aplicando el criterio de Kaiser (eigenvalue > 1), se retienen los dos primeros componentes, ya que solo estos tienen valor propio mayor a 1 (3.48 y 1.22 respectivamente). El scree plot también muestra un “codo” claro después del segundo componente. Esto significa que con dos dimensiones se puede representar la mayor parte de la información contenida en las 6 variables originales.

3.3 Contribución de las variables

fviz_pca_var(res_acp, 
             col.var = "contrib",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE) +
  labs(title = "Círculo de Correlaciones",
       subtitle = "Variables en el plano de los dos primeros componentes") +
  theme_minimal()
Círculo de correlaciones

Círculo de correlaciones

fviz_contrib(res_acp, choice = "var", axes = 1, fill = "#2c7fb8") +
  labs(title = "Contribución de las variables al Componente 1") +
  theme_minimal()
Contribuciones al Componente 1

Contribuciones al Componente 1

fviz_contrib(res_acp, choice = "var", axes = 2, fill = "#d95f0e") +
  labs(title = "Contribución de las variables al Componente 2") +
  theme_minimal()
Contribuciones al Componente 2

Contribuciones al Componente 2

Interpretación del círculo de correlaciones: En el círculo se observa que las variables preciom, areaconst, banios y parqueaderos apuntan hacia la derecha y están cercanas entre sí, lo cual confirma que están altamente correlacionadas y contribuyen al primer componente de forma similar. Este primer componente se puede interpretar como una dimensión de “tamaño y valor” de la vivienda: a mayor score en este componente, la propiedad es más grande, más costosa y tiene más baños y parqueaderos.

El segundo componente está definido principalmente por la oposición entre habitaciones (hacia arriba) y estrato (hacia abajo). Esto genera un contraste interesante: las viviendas con muchas habitaciones pero estrato bajo se ubican arriba, mientras que las de estrato alto pero menos habitaciones van abajo. Podríamos interpretar este eje como un contraste entre “tamaño familiar vs. exclusividad”.

3.4 Cargas factoriales

loadings_df <- as.data.frame(res_acp$var$coord)
loadings_df$Variable <- rownames(loadings_df)
loadings_df <- loadings_df %>% select(Variable, everything())

loadings_df %>%
  kable(caption = "Cargas factoriales (coordenadas de las variables en cada componente)", digits = 3) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Cargas factoriales (coordenadas de las variables en cada componente)
Variable Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
preciom preciom 0.878 -0.265 -0.076 -0.174 -0.131
areaconst areaconst 0.840 0.226 -0.183 -0.394 0.150
parqueaderos parqueaderos 0.798 -0.167 -0.435 0.372 0.059
banios banios 0.868 0.177 0.261 0.084 -0.335
habitaciones habitaciones 0.557 0.738 0.234 0.163 0.206
estrato estrato 0.551 -0.705 0.384 0.042 0.215

Las cargas confirman lo observado en el gráfico. En el Componente 1, todas las variables tienen cargas positivas altas, especialmente preciom (0.878), banios (0.868) y areaconst (0.840). En el Componente 2, habitaciones tiene la carga más alta positiva (0.738) y estrato la más alta negativa (-0.705), lo que refuerza la interpretación de este eje como el contraste mencionado anteriormente.

3.5 Biplot

fviz_pca_biplot(res_acp,
                col.ind = "cos2",
                gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
                col.var = "black",
                repel = TRUE,
                geom.ind = "point",
                pointsize = 1.5,
                alpha.ind = 0.5) +
  labs(title = "Biplot del ACP",
       subtitle = "Individuos coloreados por calidad de representación (cos²)") +
  theme_minimal()
Biplot del ACP

Biplot del ACP

En el biplot se visualizan simultáneamente las propiedades (puntos) y las variables (flechas). Los puntos coloreados en naranja/rojo tienen mejor representación en este plano bidimensional (cos² alto). Se nota que la mayoría de las propiedades se concentran en la zona central-izquierda, que corresponde a viviendas de tamaño y precio moderado. Los puntos más hacia la derecha son las propiedades premium (más costosas y grandes).


4 Análisis de Conglomerados

El análisis de conglomerados o clustering busca agrupar las propiedades de manera que las viviendas dentro de un mismo grupo sean similares entre sí y diferentes a las de otros grupos. Para esto se necesita definir:

  • Medida de distancia: Se usa la distancia euclidiana sobre variables estandarizadas.
  • Algoritmo de agrupamiento: K-Means (particional) y Ward (jerárquico).
  • Número óptimo de clusters: Se determina mediante los métodos del codo, silueta y estadístico gap.

4.1 Preparación

datos_cluster <- scale(datos_acp)

# Se toma una muestra para los métodos de selección de k (por eficiencia computacional)
set.seed(123)
n_muestra <- min(3000, nrow(datos_cluster))
idx <- sample(1:nrow(datos_cluster), n_muestra)
datos_cluster_muestra <- datos_cluster[idx, ]

4.2 Selección del número de clusters

p_elbow <- fviz_nbclust(datos_cluster_muestra, kmeans, method = "wss", k.max = 10) +
  labs(title = "Método del Codo") +
  theme_minimal()

p_silhouette <- fviz_nbclust(datos_cluster_muestra, kmeans, method = "silhouette", k.max = 10) +
  labs(title = "Método de la Silueta") +
  theme_minimal()

grid.arrange(p_elbow, p_silhouette, ncol = 2)
Métodos para seleccionar k

Métodos para seleccionar k

set.seed(123)
fviz_nbclust(datos_cluster_muestra, kmeans, method = "gap_stat", k.max = 10, nboot = 50) +
  labs(title = "Método del Estadístico Gap") +
  theme_minimal()
Estadístico Gap

Estadístico Gap

Interpretación: El método del codo muestra una disminución marcada de la inercia intra-cluster entre k=1 y k=3, y después la reducción es más gradual. El método de la silueta indica que k=2 da el mejor coeficiente promedio, pero k=3 también es aceptable. El estadístico gap sugiere k=4. Considerando los tres métodos y la necesidad de tener segmentos interpretables para la empresa, se opta por k=3 clusters, ya que ofrece un buen balance entre simpleza y detalle de la segmentación.

4.3 K-Means con k=3

set.seed(123)
k_optimo <- 3

km_result <- kmeans(datos_cluster, centers = k_optimo, nstart = 25, iter.max = 100)

datos_con_cluster <- datos_acp %>%
  mutate(cluster = factor(km_result$cluster))

cat("Tamaño de cada cluster:\n")
## Tamaño de cada cluster:
table(km_result$cluster)
## 
##    1    2    3 
##  887 3498 2332

4.4 Visualización en el plano del ACP

fviz_cluster(km_result, data = datos_cluster,
             palette = c("#2c7fb8", "#d95f0e", "#1b9e77"),
             geom = "point",
             pointsize = 1.5,
             ellipse.type = "convex",
             ggtheme = theme_minimal()) +
  labs(title = "Segmentación de Propiedades (K-Means, k=3)",
       subtitle = "Proyectados en los dos primeros componentes principales")
Clusters en el espacio del ACP

Clusters en el espacio del ACP

La visualización en el plano del ACP muestra que los tres clusters se separan bien a lo largo del Componente 1 (eje horizontal), que recordemos es el de “tamaño y valor”. El cluster naranja (2) queda a la izquierda (propiedades más pequeñas y económicas), el verde (3) en el centro, y el azul (1) a la derecha (propiedades premium).

4.5 Perfiles de cada cluster

perfil_cluster <- datos_con_cluster %>%
  group_by(cluster) %>%
  summarise(
    n = n(),
    precio_medio = round(mean(preciom), 1),
    precio_mediana = round(median(preciom), 1),
    area_media = round(mean(areaconst), 1),
    parqueaderos_medio = round(mean(parqueaderos), 1),
    banios_medio = round(mean(banios), 1),
    habitaciones_medio = round(mean(habitaciones), 1),
    estrato_medio = round(mean(estrato), 1)
  )

perfil_cluster %>%
  kable(caption = "Perfil promedio de cada cluster",
        col.names = c("Cluster", "N", "Precio (M)", "Precio Med.", "Área (m²)", 
                      "Parqueaderos", "Baños", "Habitaciones", "Estrato")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE)
Perfil promedio de cada cluster
Cluster N Precio (M) Precio Med. Área (m²) Parqueaderos Baños Habitaciones Estrato
1 887 1117.0 1100 419.6 3.8 5.2 4.6 5.7
2 3498 261.3 250 97.7 1.2 2.3 2.9 4.4
3 2332 533.8 500 215.6 2.0 4.0 4.2 5.2

Interpretación de los perfiles:

  • Cluster 1 (n=887): Es el segmento premium. Precio promedio de 1,117 millones, área de 420 m², casi 4 parqueaderos, 5 baños y estrato promedio de 5.7. Son propiedades grandes y exclusivas, representando solo el 13% de la oferta.

  • Cluster 2 (n=3,498): Es el segmento económico y el más numeroso (52% de la oferta). Precio promedio de 261 millones, área de 98 m², 1 parqueadero, 2 baños y estrato 4.4. Son viviendas de tamaño estándar orientadas a un mercado más amplio.

  • Cluster 3 (n=2,332): Segmento intermedio (35% de la oferta). Precio de 534 millones, área de 216 m², 2 parqueaderos, 4 baños y estrato 5.2. Son propiedades de gama media-alta.

datos_long <- datos_con_cluster %>%
  pivot_longer(cols = -cluster, names_to = "variable", values_to = "valor")

ggplot(datos_long, aes(x = cluster, y = valor, fill = cluster)) +
  geom_boxplot(alpha = 0.7) +
  facet_wrap(~ variable, scales = "free_y", ncol = 3) +
  scale_fill_manual(values = c("#2c7fb8", "#d95f0e", "#1b9e77")) +
  labs(title = "Distribución de variables por cluster",
       x = "Cluster", y = "Valor") +
  theme_minimal()
Variables por cluster

Variables por cluster

Los boxplots confirman la caracterización: el Cluster 1 tiene medianas mucho más altas en todas las variables excepto habitaciones, donde la diferencia es menor. También se nota que el Cluster 1 tiene mucha dispersión en precio y área, lo que indica que dentro de este segmento premium hay bastante heterogeneidad.

4.6 Clustering jerárquico

Para complementar, se aplica también un clustering jerárquico con el método de Ward sobre una muestra de 500 observaciones (por limitaciones computacionales del dendrograma).

set.seed(123)
muestra_dendro <- min(500, nrow(datos_cluster))
idx_dendro <- sample(1:nrow(datos_cluster), muestra_dendro)

dist_matrix <- dist(datos_cluster[idx_dendro, ], method = "euclidean")
hc_result <- hclust(dist_matrix, method = "ward.D2")

fviz_dend(hc_result, k = k_optimo, 
          cex = 0.4, 
          palette = c("#2c7fb8", "#d95f0e", "#1b9e77"),
          rect = TRUE, rect_fill = TRUE, rect_border = "gray",
          main = "Dendrograma - Método de Ward",
          xlab = "Propiedades", ylab = "Distancia")
Dendrograma

Dendrograma

El dendrograma muestra que el corte en 3 grupos es razonable, ya que las ramas principales se separan a una distancia considerable. Esto es consistente con lo obtenido por K-Means.

4.7 Validación con coeficiente de silueta

sil <- silhouette(km_result$cluster, dist(datos_cluster))
cat("Coeficiente de silueta promedio:", round(mean(sil[, 3]), 3), "\n")
## Coeficiente de silueta promedio: 0.31
fviz_silhouette(sil, palette = c("#2c7fb8", "#d95f0e", "#1b9e77")) +
  labs(title = "Gráfico de Silueta",
       subtitle = paste("Coeficiente promedio:", round(mean(sil[, 3]), 3))) +
  theme_minimal()
##   cluster size ave.sil.width
## 1       1  887          0.14
## 2       2 3498          0.46
## 3       3 2332          0.15
Silueta

Silueta

El coeficiente de silueta promedio es de 0.31, que se considera una estructura moderada. El Cluster 2 (económico) tiene la mejor silueta (0.46), indicando que es el grupo más compacto y bien separado. Los clusters 1 y 3 tienen siluetas más bajas (0.14 y 0.15), lo que sugiere que hay cierta superposición entre las propiedades premium e intermedias. Esto tiene sentido porque la frontera entre “gama media-alta” y “premium” no siempre es nítida en el mercado inmobiliario.


5 Análisis de Correspondencia

El Análisis de Correspondencia (AC) sirve para estudiar las relaciones entre variables categóricas. Su lógica es similar al ACP pero aplicada a tablas de contingencia. Los conceptos clave son:

  • Tabla de contingencia: Frecuencias cruzadas entre dos variables categóricas.
  • Inercia: Mide la dispersión de la tabla; equivale a la chi-cuadrado dividida por n.
  • Perfiles fila/columna: Distribuciones condicionales.
  • Contribuciones: Cuánto aporta cada categoría a la definición de los ejes.

5.1 AC Simple: Zona vs Estrato

Se elige este cruce primero porque ambas variables tienen varias categorías (5 zonas × 4 estratos), lo que permite obtener un espacio factorial con al menos 2 dimensiones.

tabla_zona_estrato <- table(vivienda$zona, vivienda$estrato)

tabla_zona_estrato %>%
  kable(caption = "Tabla de contingencia: Zona vs Estrato") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Tabla de contingencia: Zona vs Estrato
3 4 5 6
Zona Centro 105 14 4 1
Zona Norte 572 407 769 172
Zona Oeste 54 84 290 770
Zona Oriente 340 8 2 1
Zona Sur 382 1616 1685 1043
chi_test <- chisq.test(tabla_zona_estrato)
cat("Test Chi-cuadrado:\n")
## Test Chi-cuadrado:
cat("  Estadístico:", round(chi_test$statistic, 3), "\n")
##   Estadístico: 3830.435
cat("  g.l.:", chi_test$parameter, "\n")
##   g.l.: 12
cat("  p-valor:", format.pval(chi_test$p.value, digits = 4), "\n")
##   p-valor: < 2.2e-16

El test chi-cuadrado da un estadístico de 3830.4 con p-valor prácticamente cero, lo que confirma que sí existe una asociación significativa entre la zona y el estrato. Esto justifica la aplicación del AC.

res_ca <- CA(tabla_zona_estrato, graph = FALSE)

eig_ca <- get_eigenvalue(res_ca)
as.data.frame(eig_ca) %>%
  kable(caption = "Inercia explicada por cada dimensión", digits = 4) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Inercia explicada por cada dimensión
eigenvalue variance.percent cumulative.variance.percent
Dim.1 0.3222 69.9655 69.9655
Dim.2 0.1275 27.6800 97.6455
Dim.3 0.0108 2.3545 100.0000

La primera dimensión captura el 70% de la inercia y la segunda el 27.7%, acumulando el 97.6%. Esto significa que el mapa bidimensional es una representación excelente de la asociación entre zonas y estratos.

fviz_ca_biplot(res_ca, 
               repel = TRUE,
               col.row = "#2c7fb8",
               col.col = "#d95f0e",
               shape.row = 17,
               shape.col = 15) +
  labs(title = "Análisis de Correspondencia Simple",
       subtitle = "Zona vs Estrato socioeconómico") +
  theme_minimal()
Mapa de correspondencia: Zona vs Estrato

Mapa de correspondencia: Zona vs Estrato

Interpretación del mapa: La proximidad entre puntos indica asociación. Se observa claramente que:

  • Zona Oriente y Zona Centro están asociadas con el estrato 3 (extremo derecho del gráfico). Son zonas con oferta predominantemente de estrato bajo.
  • Zona Oeste se asocia fuertemente con el estrato 6 (parte superior izquierda). Es la zona más exclusiva.
  • Zona Sur y estrato 5 están muy próximos (parte inferior central), indicando que la Zona Sur es principalmente de estrato 5.
  • Zona Norte queda en una posición intermedia, con presencia de varios estratos, lo que la hace una zona más heterogénea.
  • El estrato 4 está abajo, algo separado de las zonas, lo que indica que se distribuye más uniformemente sin asociarse fuertemente con una zona específica.
p_cr <- fviz_contrib(res_ca, choice = "row", axes = 1:2, fill = "#2c7fb8") +
  labs(title = "Contribución de las Zonas") + theme_minimal()

p_cc <- fviz_contrib(res_ca, choice = "col", axes = 1:2, fill = "#d95f0e") +
  labs(title = "Contribución de los Estratos") + theme_minimal()

grid.arrange(p_cr, p_cc, ncol = 2)

Las zonas que más contribuyen a definir los ejes son Zona Oriente y Zona Oeste (las más extremas), y el estrato con mayor contribución es el 3, seguido del 6.

5.2 AC Simple: Tipo de vivienda vs Zona

tabla_tipo_zona <- table(vivienda$tipo, vivienda$zona)

tabla_tipo_zona %>%
  kable(caption = "Tabla de contingencia: Tipo vs Zona") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Tabla de contingencia: Tipo vs Zona
Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
Apartamento 24 1198 1029 62 2787
Casa 100 722 169 289 1939
chi_test2 <- chisq.test(tabla_tipo_zona)
cat("Test Chi-cuadrado: estadístico =", round(chi_test2$statistic, 3), 
    ", p-valor =", format.pval(chi_test2$p.value, digits = 4), "\n")
## Test Chi-cuadrado: estadístico = 690.93 , p-valor = < 2.2e-16

La asociación también es significativa (chi² = 690.9, p < 0.001).

res_ca2 <- CA(tabla_tipo_zona, graph = FALSE, ncp = 5)

# Como tipo solo tiene 2 categorías, el AC genera solo 1 dimensión
ndim_ca2 <- ifelse(is.null(ncol(res_ca2$row$coord)), 1, ncol(res_ca2$row$coord))

if (ndim_ca2 >= 2) {
  print(
    fviz_ca_biplot(res_ca2, repel = TRUE,
                   col.row = "#1b9e77", col.col = "#7570b3",
                   shape.row = 17, shape.col = 15) +
      labs(title = "AC Simple: Tipo de vivienda vs Zona") +
      theme_minimal()
  )
} else {
  row_coords <- res_ca2$row$coord
  col_coords <- res_ca2$col$coord
  if (is.matrix(row_coords)) row_coords <- row_coords[, 1]
  if (is.matrix(col_coords)) col_coords <- col_coords[, 1]
  
  coords_all <- rbind(
    data.frame(nombre = names(row_coords), dim1 = as.numeric(row_coords), tipo_cat = "Tipo de vivienda"),
    data.frame(nombre = names(col_coords), dim1 = as.numeric(col_coords), tipo_cat = "Zona")
  )
  
  print(
    ggplot(coords_all, aes(x = dim1, y = 0, color = tipo_cat, label = nombre)) +
      geom_point(size = 4) +
      geom_text(vjust = -1.2, size = 3.5, show.legend = FALSE) +
      scale_color_manual(values = c("#1b9e77", "#7570b3")) +
      labs(title = "AC Simple: Tipo de vivienda vs Zona (1 dimensión)",
           x = "Dimensión 1", y = "", color = "Categoría") +
      theme_minimal() +
      theme(axis.text.y = element_blank(), axis.ticks.y = element_blank())
  )
}
AC Tipo vs Zona (1 dimensión)

AC Tipo vs Zona (1 dimensión)

Dado que la variable tipo solo tiene 2 categorías (Casa y Apartamento), el AC genera una sola dimensión (mín(filas, columnas) - 1 = 2 - 1 = 1). En el gráfico unidimensional se ve que:

  • Apartamento se asocia más con Zona Oeste (ambos a la izquierda).
  • Casa se asocia más con Zona Oriente y Zona Centro (ambos a la derecha).
  • Zona Norte y Zona Sur quedan en posiciones intermedias, con mezcla de ambos tipos.

5.3 Análisis de Correspondencia Múltiple (ACM)

Para estudiar la relación simultánea entre tipo, zona y estrato, se aplica el ACM, que es la extensión del AC a más de dos variables categóricas.

datos_acm <- vivienda %>%
  select(tipo, zona, estrato) %>%
  mutate(estrato = factor(estrato, labels = paste0("Estrato_", sort(unique(estrato))))) %>%
  drop_na()

res_acm <- MCA(datos_acm, graph = FALSE)
eig_acm <- get_eigenvalue(res_acm)
head(eig_acm, 5) %>%
  kable(caption = "Inercia del ACM", digits = 4) %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Inercia del ACM
eigenvalue variance.percent cumulative.variance.percent
Dim.1 0.5621 21.0783 21.0783
Dim.2 0.4531 16.9921 38.0704
Dim.3 0.3796 14.2367 52.3071
Dim.4 0.3334 12.5042 64.8113
Dim.5 0.3233 12.1243 76.9355
fviz_mca_var(res_acm, 
             col.var = "contrib",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE,
             ggtheme = theme_minimal()) +
  labs(title = "Análisis de Correspondencia Múltiple",
       subtitle = "Tipo, Zona y Estrato en el espacio factorial")
Mapa del ACM - Categorías

Mapa del ACM - Categorías

fviz_mca_biplot(res_acm,
                repel = TRUE,
                geom.ind = "point",
                col.ind = "gray70",
                col.var = "contrib",
                gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
                alpha.ind = 0.3,
                ggtheme = theme_minimal()) +
  labs(title = "Biplot del ACM",
       subtitle = "Individuos y categorías")
Biplot del ACM

Biplot del ACM

Interpretación del ACM: Las dos primeras dimensiones explican el 38% de la inercia total, que en ACM es un valor aceptable (suelen ser menores que en ACP). Del mapa de categorías se puede leer:

  • Estrato_3, Casa y Zona Oriente/Zona Centro están en la zona derecha del gráfico, indicando que las casas de estrato 3 se concentran en las zonas oriente y centro.
  • Zona Oeste y Estrato_6 están en la parte superior izquierda, reflejando que esta zona es la más exclusiva.
  • Zona Sur y Estrato_5 están muy próximos en la parte inferior, confirmando su fuerte asociación.
  • Apartamento queda en una posición más central-izquierda, asociándose con Zona Oeste y estratos medios-altos.
  • Estrato_4 está abajo, algo aislado, sugiriendo un perfil diferenciado del resto.

6 Visualizaciones complementarias

6.1 Mapa de calor: Precio por zona y estrato

heatmap_data <- vivienda %>%
  group_by(zona, estrato) %>%
  summarise(precio_medio = mean(preciom, na.rm = TRUE), .groups = "drop")

ggplot(heatmap_data, aes(x = factor(estrato), y = zona, fill = precio_medio)) +
  geom_tile(color = "white", linewidth = 0.5) +
  geom_text(aes(label = round(precio_medio, 0)), color = "black", size = 3.5) +
  scale_fill_gradient2(low = "#2166ac", mid = "#f7f7f7", high = "#b2182b",
                       midpoint = median(heatmap_data$precio_medio, na.rm = TRUE)) +
  labs(title = "Precio Promedio por Zona y Estrato",
       x = "Estrato", y = "Zona", fill = "Precio\n(millones)") +
  theme_minimal()
Precio promedio por zona y estrato

Precio promedio por zona y estrato

El mapa de calor muestra que el estrato 6 es consistentemente el más caro en todas las zonas, pero con diferencias: en Zona Oriente el estrato 6 tiene un promedio de 1,350 millones (aunque con muy pocos datos), mientras que en Zona Sur es de 817 millones. Los precios más accesibles están en estrato 3 de la Zona Norte (171 millones).

6.2 Precio vs Área por tipo y zona

ggplot(vivienda, aes(x = areaconst, y = preciom, color = tipo)) +
  geom_point(alpha = 0.4, size = 1.5) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1) +
  facet_wrap(~ zona) +
  scale_color_manual(values = c("#2c7fb8", "#d95f0e")) +
  labs(title = "Relación Precio vs Área Construida por Zona y Tipo",
       x = "Área construida (m²)", y = "Precio (millones)", color = "Tipo") +
  theme_minimal() +
  coord_cartesian(xlim = c(0, quantile(vivienda$areaconst, 0.98, na.rm = TRUE)),
                  ylim = c(0, quantile(vivienda$preciom, 0.98, na.rm = TRUE)))
Precio vs Área

Precio vs Área

En todas las zonas, los apartamentos (azul) tienen una pendiente precio/m² mayor que las casas (naranja), lo que indica que el m² de apartamento tiende a ser más caro. Esto es especialmente marcado en Zona Oeste y Zona Norte.

6.3 Oferta por tipo y zona

tabla_prop <- vivienda %>%
  count(zona, tipo) %>%
  group_by(zona) %>%
  mutate(prop = n / sum(n))

ggplot(tabla_prop, aes(x = zona, y = prop, fill = tipo)) +
  geom_bar(stat = "identity", alpha = 0.85) +
  scale_fill_manual(values = c("#2c7fb8", "#d95f0e")) +
  scale_y_continuous(labels = percent_format()) +
  labs(title = "Proporción de la oferta por tipo y zona",
       x = "Zona", y = "Proporción", fill = "Tipo") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))
Oferta proporcional

Oferta proporcional

La Zona Oeste tiene la mayor proporción de apartamentos (más del 85%), mientras que la Zona Oriente y Zona Centro tienen mayor proporción de casas. La Zona Sur tiene una mezcla más equilibrada.

6.4 Clusters y variables categóricas

vivienda_completa <- vivienda %>%
  select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato, zona, tipo) %>%
  drop_na(preciom, areaconst, parqueaderos, banios, habitaciones, estrato)

vivienda_completa$cluster <- factor(km_result$cluster)

p_zona <- ggplot(vivienda_completa, aes(x = cluster, fill = zona)) +
  geom_bar(position = "fill", alpha = 0.85) +
  scale_y_continuous(labels = percent_format()) +
  labs(title = "Composición por Zona", x = "Cluster", y = "Proporción") +
  theme_minimal()

p_tipo <- ggplot(vivienda_completa, aes(x = cluster, fill = tipo)) +
  geom_bar(position = "fill", alpha = 0.85) +
  scale_y_continuous(labels = percent_format()) +
  scale_fill_manual(values = c("#2c7fb8", "#d95f0e")) +
  labs(title = "Composición por Tipo", x = "Cluster", y = "Proporción") +
  theme_minimal()

grid.arrange(p_zona, p_tipo, ncol = 2)
Clusters por zona y tipo

Clusters por zona y tipo

El Cluster 1 (premium) tiene mayor presencia de la Zona Sur y Zona Norte, y está compuesto casi exclusivamente por casas. El Cluster 2 (económico) también es mayoritariamente de Zona Sur pero con mucha mayor proporción de apartamentos. Esto es coherente: los apartamentos económicos dominan el mercado masivo.


7 Conclusiones

A partir de los tres análisis realizados, se pueden extraer las siguientes conclusiones para la empresa inmobiliaria:

Sobre el ACP: Las propiedades se caracterizan principalmente por dos dimensiones. La primera (58% de la varianza) resume el tamaño y valor general de la vivienda, mientras que la segunda (20%) captura el contraste entre viviendas familiares (muchas habitaciones, estrato más bajo) y viviendas exclusivas (estrato alto, menos habitaciones). Con estas dos dimensiones se captura casi el 80% de la información, lo que simplifica considerablemente el análisis.

Sobre los clusters: El mercado se segmenta naturalmente en tres grupos: un segmento económico mayoritario (52% de la oferta, ~260 millones promedio), un segmento intermedio (35%, ~530 millones) y un segmento premium minoritario (13%, ~1,100 millones). La empresa puede usar estos segmentos para enfocar sus estrategias de marketing y valoración de manera diferenciada.

Sobre el análisis de correspondencia: Existe una asociación fuerte entre zona, estrato y tipo de vivienda. La Zona Oeste es el mercado de estrato 6 por excelencia (apartamentos exclusivos), la Zona Oriente concentra la oferta de estrato 3 (predominantemente casas), y la Zona Sur es el mercado más grande y diverso. Estas asociaciones deben considerarse al evaluar oportunidades de inversión.

7.1 Recomendaciones

  1. Para el segmento económico (Cluster 2), que representa la mayor parte del mercado, la empresa debería enfocarse en volumen de operaciones, aprovechando que es un segmento grande y relativamente homogéneo.

  2. El segmento premium (Cluster 1) ofrece mayores márgenes pero requiere estrategias personalizadas. Se recomienda especial atención a la Zona Oeste y Zona Norte en estratos 5 y 6.

  3. La Zona Sur, por ser la más diversa y con mayor volumen de oferta, ofrece oportunidades en todos los segmentos y debería ser un foco estratégico.

  4. Se recomienda actualizar periódicamente este análisis ya que el mercado inmobiliario es dinámico y los patrones pueden cambiar.


8 Anexos

8.1 Anexo A: Resumen del ACP

summary(res_acp)
## 
## Call:
## PCA(X = datos_acp, scale.unit = TRUE, graph = FALSE) 
## 
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6
## Variance               3.484   1.223   0.499   0.360   0.244   0.190
## % of var.             58.063  20.385   8.325   5.992   4.073   3.162
## Cumulative % of var.  58.063  78.447  86.772  92.765  96.838 100.000
## 
## Individuals (the 10 first)
##                  Dist    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3
## 1            |  2.897 | -1.105  0.005  0.146 |  2.480  0.075  0.733 |  0.193
## 2            |  2.382 | -1.844  0.015  0.599 |  0.917  0.010  0.148 | -0.916
## 3            |  2.201 | -0.890  0.003  0.164 |  1.393  0.024  0.400 | -1.411
## 4            |  2.037 |  0.851  0.003  0.175 |  0.494  0.003  0.059 | -0.950
## 5            |  1.549 | -1.400  0.008  0.817 | -0.426  0.002  0.076 |  0.302
## 6            |  1.308 | -1.100  0.005  0.707 | -0.300  0.001  0.053 |  0.581
## 7            |  1.780 | -1.506  0.010  0.715 |  0.086  0.000  0.002 | -0.737
## 8            |  0.698 | -0.247  0.000  0.125 |  0.076  0.000  0.012 |  0.164
## 9            |  1.912 |  0.583  0.001  0.093 |  1.182  0.017  0.382 |  0.890
## 10           |  1.748 |  0.954  0.004  0.298 | -0.405  0.002  0.054 | -0.669
##                 ctr   cos2  
## 1             0.001  0.004 |
## 2             0.025  0.148 |
## 3             0.059  0.411 |
## 4             0.027  0.218 |
## 5             0.003  0.038 |
## 6             0.010  0.197 |
## 7             0.016  0.171 |
## 8             0.001  0.055 |
## 9             0.024  0.217 |
## 10            0.013  0.146 |
## 
## Variables
##                 Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## preciom      |  0.878 22.135  0.771 | -0.265  5.735  0.070 | -0.076  1.169
## areaconst    |  0.840 20.275  0.706 |  0.226  4.178  0.051 | -0.183  6.733
## parqueaderos |  0.798 18.301  0.638 | -0.167  2.289  0.028 | -0.435 37.969
## banios       |  0.868 21.646  0.754 |  0.177  2.557  0.031 |  0.261 13.657
## habitaciones |  0.557  8.917  0.311 |  0.738 44.570  0.545 |  0.234 10.977
## estrato      |  0.551  8.726  0.304 | -0.705 40.671  0.497 |  0.384 29.496
##                cos2  
## preciom       0.006 |
## areaconst     0.034 |
## parqueaderos  0.190 |
## banios        0.068 |
## habitaciones  0.055 |
## estrato       0.147 |

8.2 Anexo B: Centros de los clusters

km_result$centers %>%
  round(3) %>%
  kable(caption = "Centros estandarizados de cada cluster") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Centros estandarizados de cada cluster
preciom areaconst parqueaderos banios habitaciones estrato
1.935 1.655 1.763 1.431 0.720 0.893
-0.620 -0.579 -0.534 -0.713 -0.489 -0.453
0.194 0.239 0.131 0.525 0.460 0.340
cat("Varianza explicada por el clustering:", 
    round(km_result$betweenss / km_result$totss * 100, 2), "%\n")
## Varianza explicada por el clustering: 49.65 %

8.3 Anexo C: Resumen del AC (Zona vs Estrato)

summary(res_ca)
## 
## Call:
## CA(X = tabla_zona_estrato, graph = FALSE) 
## 
## The chi square of independence between the two variables is equal to 3830.435 (p-value =  0 ).
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3
## Variance               0.322   0.127   0.011
## % of var.             69.966  27.680   2.354
## Cumulative % of var.  69.966  97.646 100.000
## 
## Rows
##                Iner*1000     Dim.1     ctr    cos2     Dim.2     ctr    cos2  
## Zona Centro  |    47.079 |   1.725  13.761   0.942 |   0.364   1.547   0.042 |
## Zona Norte   |    46.762 |   0.390  10.887   0.750 |  -0.147   3.920   0.107 |
## Zona Oeste   |   135.034 |  -0.569  14.476   0.345 |   0.783  69.204   0.653 |
## Zona Oriente |   184.564 |   2.015  53.171   0.928 |   0.537   9.563   0.066 |
## Zona Sur     |    47.004 |  -0.209   7.704   0.528 |  -0.188  15.767   0.428 |
##                Dim.3     ctr    cos2  
## Zona Centro    0.228   7.148   0.016 |
## Zona Norte    -0.170  61.735   0.143 |
## Zona Oeste    -0.037   1.820   0.001 |
## Zona Oriente   0.160  10.006   0.006 |
## Zona Sur       0.061  19.291   0.044 |
## 
## Columns
##                Iner*1000     Dim.1     ctr    cos2     Dim.2     ctr    cos2  
## 3            |   253.402 |   1.187  76.333   0.970 |   0.207   5.851   0.029 |
## 4            |    47.744 |  -0.154   1.895   0.128 |  -0.380  28.966   0.773 |
## 5            |    25.471 |  -0.132   1.796   0.227 |  -0.204  10.824   0.542 |
## 6            |   133.827 |  -0.519  19.976   0.481 |   0.539  54.359   0.518 |
##                Dim.3     ctr    cos2  
## 3              0.015   0.350   0.000 |
## 4              0.136  43.547   0.099 |
## 5             -0.133  54.323   0.231 |
## 6              0.028   1.780   0.001 |

8.4 Anexo D: Resumen del ACM

summary(res_acm)
## 
## Call:
## MCA(X = datos_acm, graph = FALSE) 
## 
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6   Dim.7
## Variance               0.562   0.453   0.380   0.333   0.323   0.272   0.201
## % of var.             21.078  16.992  14.237  12.504  12.124  10.192   7.551
## Cumulative % of var.  21.078  38.070  52.307  64.811  76.936  87.127  94.678
##                        Dim.8
## Variance               0.142
## % of var.              5.322
## Cumulative % of var. 100.000
## 
## Individuals (the 10 first)
##                 Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## 1            |  2.421  0.125  0.606 |  0.963  0.025  0.096 |  0.504  0.008
## 2            |  2.421  0.125  0.606 |  0.963  0.025  0.096 |  0.504  0.008
## 3            |  2.421  0.125  0.606 |  0.963  0.025  0.096 |  0.504  0.008
## 4            |  0.103  0.000  0.006 | -0.722  0.014  0.298 |  0.899  0.026
## 5            | -0.072  0.000  0.003 | -0.330  0.003  0.054 | -1.308  0.054
## 6            | -0.072  0.000  0.003 | -0.330  0.003  0.054 | -1.308  0.054
## 7            | -0.069  0.000  0.002 | -0.539  0.008  0.127 | -0.518  0.008
## 8            | -0.072  0.000  0.003 | -0.330  0.003  0.054 | -1.308  0.054
## 9            |  0.394  0.003  0.067 | -0.401  0.004  0.069 | -0.914  0.026
## 10           |  0.394  0.003  0.067 | -0.401  0.004  0.069 | -0.914  0.026
##                cos2  
## 1             0.026 |
## 2             0.026 |
## 3             0.026 |
## 4             0.462 |
## 5             0.857 |
## 6             0.857 |
## 7             0.117 |
## 8             0.857 |
## 9             0.361 |
## 10            0.361 |
## 
## Categories (the 10 first)
##                  Dim.1     ctr    cos2  v.test     Dim.2     ctr    cos2
## Apartamento  |  -0.406   5.980   0.261 -46.558 |   0.056   0.139   0.005
## Casa         |   0.643   9.474   0.261  46.558 |  -0.088   0.221   0.005
## Zona Centro  |   2.712   6.500   0.111  30.423 |   0.978   1.049   0.014
## Zona Norte   |   0.449   2.763   0.061  22.448 |  -0.251   1.066   0.019
## Zona Oeste   |  -1.067   9.727   0.192 -39.923 |   1.761  32.849   0.522
## Zona Oriente |   3.083  23.782   0.419  59.014 |   1.421   6.267   0.089
## Zona Sur     |  -0.212   1.516   0.059 -22.190 |  -0.476   9.461   0.298
## Estrato_3    |   1.720  30.646   0.626  72.168 |   0.612   4.816   0.079
## Estrato_4    |  -0.199   0.600   0.014 -10.636 |  -0.894  15.033   0.275
## Estrato_5    |  -0.206   0.830   0.021 -13.188 |  -0.471   5.394   0.110
##               v.test     Dim.3     ctr    cos2  v.test  
## Apartamento    6.380 |  -0.282   4.271   0.126 -32.337 |
## Casa          -6.380 |   0.446   6.767   0.126  32.337 |
## Zona Centro   10.972 |   1.171   1.794   0.021  13.135 |
## Zona Norte   -12.516 |  -1.378  38.467   0.570 -68.830 |
## Zona Oeste    65.872 |  -0.154   0.298   0.004  -5.746 |
## Zona Oriente  27.200 |   0.723   1.935   0.023  13.833 |
## Zona Sur     -49.767 |   0.514  13.192   0.348  53.793 |
## Estrato_3     25.688 |  -0.238   0.867   0.012  -9.976 |
## Estrato_4    -47.795 |   0.702  11.075   0.170  37.552 |
## Estrato_5    -30.184 |  -0.758  16.683   0.284 -48.589 |
## 
## Categorical variables (eta2)
##                Dim.1 Dim.2 Dim.3  
## tipo         | 0.261 0.005 0.126 |
## zona         | 0.747 0.689 0.634 |
## estrato      | 0.679 0.665 0.379 |

9 Referencias

  • Husson, F., Lê, S., & Pagès, J. (2011). Exploratory Multivariate Analysis by Example Using R. CRC Press.
  • Kassambara, A. (2017). Practical Guide to Principal Component Methods in R. STHDA.
  • Greenacre, M. (2017). Correspondence Analysis in Practice. CRC Press.
  • Lê, S., Josse, J., & Husson, F. (2008). FactoMineR: An R Package for Multivariate Analysis. Journal of Statistical Software, 25(1), 1-18.
  • R Core Team (2024). R: A Language and Environment for Statistical Computing.