.
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)
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()
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.
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.
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")
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 |
# 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()
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")
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.
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
.
Se procede a segmentar las viviendas en grupos homogéneos basados en sus características más relevantes.
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.
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)")
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.
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
.
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.
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”.
Este análisis del mercado inmobiliario de Cali revela una estructura clara y segmentada, impulsada por un conjunto interrelacionado de factores.
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.
Segmentación del Mercado: El mercado se puede dividir en tres grandes segmentos:
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.