Introducción

.


Carga y Preparación de Datos

Inicialmente, se cargan las librerías necesarias para el análisis y el conjunto de datos vivienda.

# Carga de paquetes para el análisis
suppressPackageStartupMessages({
  library(paqueteMODELOS)
  library(ggplot2)
  library(dplyr)
  library(FactoMineR)
  library(factoextra)
  library(mice)
  library(viridis)
  library(patchwork)
  library(cluster)
})

# Carga de datos
data(vivienda)

Etapa 1: Exploración y Limpieza de Datos

Un paso fundamental es la evaluación de la calidad de los datos. Se excluyen las variables con exceso de datos faltantes (piso, parqueaderos) y el identificador id debido a que no es relevante esta última variable para el estudio. Posteriormente, se eliminan las filas que aún contienen valores ausentes para asegurar un conjunto de datos completo.

# Exclusión de variables problemáticas y eliminación de filas con NA
vivienda_clean <- vivienda %>%
  select(-id, -piso, -parqueaderos) %>%
  na.omit()

# Estandarización de variables numéricas para PCA
vivienda_num <- vivienda_clean %>%
  select_if(is.numeric) %>%
  scale() %>%
  as.data.frame()

Etapa 2: Análisis de Componentes Principales (PCA)

El PCA se utiliza para reducir la dimensionalidad del conjunto de datos, identificando las combinaciones lineales de variables que explican la mayor parte de la varianza.

Varianza Explicada por Componente

El gráfico de sedimentación ayuda a determinar el número de componentes principales a retener.

# Ejecución del PCA
res.pca <- prcomp(vivienda_num)

# Gráfico de sedimentación
fviz_eig(res.pca, addlabels = TRUE, barfill = "#21908d", barcolor = "#440154",
         main = "Gráfico de Sedimentación (Scree Plot)",
         xlab = "Componentes Principales",
         ylab = "% de Varianza Explicada") +
  theme_minimal() +
  labs(subtitle = "Las primeras 4 dimensiones capturan más del 85% de la varianza total.")

Según el gráfico, es posible deducir que las primeras cuatro dimensiones son suficientes para capturar una porción significativa de la información.

Cargas Vectoriales (Loadings)

La siguiente tabla detalla la carga (el coeficiente o “peso”) de cada variable original en la conformación de los componentes principales. Un valor alto (positivo o negativo) indica que la variable tiene una fuerte influencia en ese componente. Por ejemplo, areaconst, habitaciones y banios tienen cargas altas en el PC1, definiéndolo como una dimensión de “tamaño y capacidad” de la vivienda.

# Extraer y mostrar las cargas vectoriales en una tabla formateada
cargas_pca <- res.pca$rotation
kable(cargas_pca, digits = 3, caption = "Cargas de las Variables en cada Componente Principal")
Cargas de las Variables en cada Componente Principal
PC1 PC2 PC3 PC4 PC5 PC6 PC7
estrato 0.360 -0.462 0.293 -0.250 -0.477 0.502 0.174
preciom 0.495 -0.068 0.251 -0.252 0.229 -0.220 -0.723
areaconst 0.456 0.268 0.028 -0.126 0.641 0.292 0.455
banios 0.490 0.186 -0.069 -0.017 -0.394 -0.652 0.373
habitaciones 0.297 0.549 -0.327 0.324 -0.337 0.432 -0.312
longitud -0.267 0.462 -0.016 -0.825 -0.177 0.052 -0.016
latitud -0.134 0.401 0.860 0.269 -0.089 -0.003 0.047

Contribución de Variables a los Componentes

# Gráficos de contribución para los 4 primeros componentes
p1 <- fviz_contrib(res.pca, choice = "var", axes = 1, top = 5, fill = "#440154") + labs(title = "Contribución a PC1")
p2 <- fviz_contrib(res.pca, choice = "var", axes = 2, top = 5, fill = "#3b528b") + labs(title = "Contribución a PC2")
p3 <- fviz_contrib(res.pca, choice = "var", axes = 3, top = 5, fill = "#21908d") + labs(title = "Contribución a PC3")
p4 <- fviz_contrib(res.pca, choice = "var", axes = 4, top = 5, fill = "#5dc863") + labs(title = "Contribución a PC4")

# Combinar gráficos con patchwork
(p1 + p2) / (p3 + p4) + plot_annotation(
  title = "Principales Variables Contribuyentes a cada Dimensión",
  subtitle = "Visualización de las 5 variables más influyentes por componente principal."
) & theme_light()

Calidad de Representación de las Variables (cos2)

El cos2 (coseno al cuadrado) mide la calidad con la que cada variable es representada por los componentes principales. Un valor alto indica que la proyección de la variable en el mapa PCA es fiable. Este gráfico muestra que casi todas nuestras variables están bien representadas por los dos primeros componentes, lo que da validez a las interpretaciones visuales que haremos a continuación.

# Visualización del cos2 para las variables en los dos primeros ejes
fviz_cos2(res.pca, choice = "var", axes = 1:2) +
  theme_minimal() +
  labs(title = "Calidad de Representación (cos2) de las Variables",
       subtitle = "Suma del cos2 en los componentes 1 y 2")

Círculo de Correlaciones

fviz_pca_var(res.pca,
             col.var = "contrib",
             gradient.cols = viridis(3, direction = -1),
             repel = TRUE) +
  labs(title = "Círculo de Correlaciones de Variables",
       subtitle = "Proyección de variables en el plano PC1 vs. PC2",
       color = "Contribución") +
  theme_minimal()

Este gráfico confirma que areaconst, habitaciones y banios están fuertemente correlacionadas entre sí. A su vez, preciom y estrato también muestran una correlación positiva. Notablemente, el primer grupo de variables es casi ortogonal al segundo, indicando que son dimensiones relativamente independientes en los datos.

Biplot de Variables e Individuos

El biplot nos permite visualizar simultáneamente las variables y las observaciones en el nuevo espacio dimensional, coloreando por tipo de vivienda y zona. La dirección y longitud de las flechas nos dicen cómo se relacionan las variables entre sí y su influencia en el análisis.

p_tipo <- fviz_pca_biplot(res.pca, 
                          geom.ind = "point",
                          pointshape = 21,
                          pointsize = 2,
                          fill.ind = vivienda_clean$tipo,
                          col.var = "black", 
                          alpha.var = "contrib",
                          repel = TRUE,
                          legend.title = "Tipo de Vivienda",
                          addEllipses = TRUE,
                          ellipse.level = 0.95) +
  scale_fill_viridis_d(option = "A") +
  labs(title = "Biplot PCA: Relación entre Variables y Tipo de Vivienda",
       subtitle = "Casas vs. Apartamentos en el espacio de componentes principales.") +
  theme_minimal()

# Biplot coloreado por zona
p_zona <- fviz_pca_biplot(res.pca, 
                          geom.ind = "point",
                          pointshape = 21,
                          pointsize = 2,
                          fill.ind = vivienda_clean$zona,
                          col.var = "black", 
                          alpha.var = "contrib",
                          repel = TRUE,
                          legend.title = "Zona Geográfica",
                          addEllipses = TRUE,
                          ellipse.level = 0.95) +
  scale_fill_viridis_d(option = "C") +
  labs(title = "Biplot PCA: Relación entre Variables y Zona Geográfica",
       subtitle = "Diferenciación de viviendas según su ubicación en Cali.") +
  theme_minimal()

p_tipo

p_zona

Los biplots revelan una clara segregación. Las casas se asocian fuertemente con mayor areaconst, habitaciones y banios. Los apartamentos se correlacionan más con preciom y estrato. Geográficamente, la Zona Oeste se caracteriza por un alto preciom, mientras que la Zona Sur destaca por su areaconst.


Etapa 3: Análisis de Conglomerados (Clustering)

Se procede a segmentar las viviendas en grupos homogéneos basados en sus características más relevantes.

Selección del Número Óptimo de Clústeres (k)

Se utilizan los métodos del Codo (Elbow) y la Silueta para determinar el número k de clústeres más apropiado.

# Preparación de datos para clustering
vivienda_CON <- vivienda_clean %>%
  select(zona, estrato, preciom, areaconst, habitaciones, banios) %>%
  mutate(zona = as.numeric(factor(zona)))

vivienda_CON_esc <- scale(vivienda_CON)

# Método del Codo y Silueta
p_codo <- fviz_nbclust(vivienda_CON_esc, kmeans, method = "wss") + 
  labs(subtitle = "Método del Codo (Elbow)", title = "")
p_silueta <- fviz_nbclust(vivienda_CON_esc, kmeans, method = "silhouette") + 
  labs(subtitle = "Método de la Silueta", title = "")

p_codo + p_silueta + plot_annotation(title = "Determinación del Número Óptimo de Clústeres (k)")

Ambos métodos sugieren que k=2 o k=3 son las opciones más viables. Se procederá con k=3 para capturar una segmentación más granular del mercado.

Aplicación de K-Means y Caracterización de Clústeres

Se aplica el algoritmo K-Means con k=3.

set.seed(123)
kmeans_model <- kmeans(vivienda_CON_esc, centers = 3, nstart = 25)

# Añadir asignación de clúster a los datos
vivienda_clustered <- vivienda_clean %>%
  mutate(cluster = as.factor(kmeans_model$cluster))

# Visualización de los clústeres en el espacio PCA
fviz_cluster(list(data = vivienda_CON_esc, cluster = kmeans_model$cluster),
             palette = "viridis",
             geom = "point",
             ellipse.type = "convex",
             ggtheme = theme_minimal(),
             main = "Visualización de Clústeres (K-Means)")

Perfil de los Clústeres

Para entender la naturaleza de cada segmento, se analizan las características promedio de las viviendas en cada clúster.

# Preparación de datos para visualización
plot_data <- vivienda_clustered %>%
  select(preciom, areaconst, estrato, habitaciones, banios, cluster) %>%
  tidyr::pivot_longer(
    cols = -cluster,
    names_to = "variable",
    values_to = "valor"
  )

# Boxplots por clúster
ggplot(plot_data, aes(x = cluster, y = valor, fill = cluster)) +
  geom_violin(alpha = 0.5) +
  geom_boxplot(width = 0.1, fill = "white") +
  facet_wrap(~variable, scales = "free_y") +
  labs(
    title = "Caracterización de los Segmentos de Vivienda",
    subtitle = "Distribución de variables clave por clúster.",
    x = "Clúster",
    y = "Valor de la Variable"
  ) +
  theme_light() +
  scale_fill_viridis_d() +
  theme(legend.position = "none")

* Clúster 1 (Morado): Viviendas económicas. Caracterizadas por bajo estrato, menor área, menos habitaciones/baños y el preciom más bajo. * Clúster 2 (Verde): Viviendas de gama media. Estratos 4-5, área y precio moderados. * Clúster 3 (Amarillo): Viviendas de gama alta. Agrupa las propiedades con mayor areaconst, preciom, estrato 6, y mayor número de habitaciones y baños.


Fase 4: Análisis de Correspondencia (CA)

Se explora la asociación entre variables categóricas, específicamente entre la zona y el estrato, y entre la zona y el nivel de preciom.

Asociación entre Zona y Estrato

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

# Test de Chi-cuadrado
chisq_test_res <- chisq.test(tabla_zona_estrato)
cat(paste("Prueba de Chi-cuadrado: p-valor =", format.pval(chisq_test_res$p.value, digits = 3)))
## Prueba de Chi-cuadrado: p-valor = <2e-16
# Análisis de correspondencia y visualización
ca_zona_estrato <- CA(tabla_zona_estrato, graph = FALSE)
fviz_ca_biplot(ca_zona_estrato,
               repel = TRUE,
               col.row = "#21908d",
               col.col = "#440154") +
  labs(title = "Análisis de Correspondencia: Zona vs. Estrato",
       subtitle = "La proximidad indica una fuerte asociación entre categorías.") +
  theme_minimal()

El p-valor bajo confirma una asociación estadísticamente significativa entre la zona y el estrato. El gráfico muestra una fuerte conexión entre la Zona Oeste y el estrato 6, la Zona Sur con los estratos 4 y 5, y las zonas Norte y Oriente con los estratos más bajos.

Asociación entre Zona y Nivel de Precio

Se discretiza el precio por metro cuadrado en cuartiles para realizar el análisis.

# Discretización de la variable 'preciom'
vivienda_precio_cat <- vivienda_clustered %>%
  mutate(nivel_precio = cut(
    preciom,
    breaks = quantile(preciom, probs = 0:4/4, na.rm = TRUE),
    labels = c("Bajo", "Medio-Bajo", "Medio-Alto", "Alto"),
    include.lowest = TRUE
  ))

# Tabla de contingencia y test
tabla_zona_precio <- table(vivienda_precio_cat$zona, vivienda_precio_cat$nivel_precio)
chisq.test(tabla_zona_precio)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla_zona_precio
## X-squared = 1137.6, df = 12, p-value < 2.2e-16
# Análisis de correspondencia y visualización
ca_zona_precio <- CA(tabla_zona_precio, graph = FALSE)
fviz_ca_biplot(ca_zona_precio,
               repel = TRUE,
               col.row = "#21908d",
               col.col = "#440154") +
  labs(title = "Análisis de Correspondencia: Zona vs. Nivel de Precio",
       subtitle = "La Zona Oeste se asocia con los precios más altos del mercado.") +
  theme_minimal()

Nuevamente, la asociación es muy fuerte. El gráfico confirma los hallazgos anteriores: la Zona Oeste está fuertemente ligada a los niveles de precio “Alto” y “Medio-Alto”, mientras que las zonas Norte y Oriente se asocian con precios “Bajos”.


Conclusiones del Estudio

Este análisis del mercado inmobiliario de Cali revela una estructura clara y segmentada, impulsada por un conjunto interrelacionado de factores.

  1. Factores Clave del Valor: Las variables más determinantes para diferenciar las propiedades en Cali son el área construida, el precio por metro cuadrado, el estrato socioeconómico, y el número de baños y habitaciones. Estas características son los principales ejes de variabilidad en el mercado.

  2. Segmentación del Mercado: El mercado se puede dividir en tres grandes segmentos:

    • Clúster Premium, concentrado en la Zona Oeste, que agrupa propiedades de alto estrato, gran tamaño y precio elevado.
    • Clúster Económico, que representa la oferta de menor costo, con propiedades más pequeñas y de estratos más bajos, distribuidas principalmente en las zonas Norte y Oriente.
    • Clúster Intermedio, que constituye una parte importante del mercado en la Zona Sur, con características moderadas de precio y tamaño.
  3. Fuertes Vínculos Estructurales: El análisis de correspondencia demuestra de manera concluyente que la ubicación (zona) de una vivienda está intrínsecamente ligada a su estrato y a su nivel de precio. La Zona Oeste emerge como el epicentro del mercado de lujo, estableciendo un claro gradiente de valor que disminuye hacia otras zonas de la ciudad.

En resumen, el precio y las características de una vivienda en Cali no pueden entenderse de forma aislada; están profundamente anclados a su contexto socioeconómico y zonal, creando submercados bien definidos con dinámicas propias.