El análisis se enfoca en identificar los principales factores que influyen en el precio de las propiedades, así como en determinar si existen segmentos diferenciados dentro del mercado inmobiliario urbano. Para ello, se emplean técnicas que permiten sintetizar información, reducir dimensionalidad y detectar patrones estructurales tanto en variables cuantitativas como categóricas.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.6
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.1 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.2
## ✔ purrr 1.2.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(FactoMineR)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(cluster)
library(corrplot)
## corrplot 0.95 loaded
library(paqueteMODELOS)
## Loading required package: boot
## Loading required package: broom
## Loading required package: GGally
## Loading required package: gridExtra
##
## Attaching package: 'gridExtra'
##
## The following object is masked from 'package:dplyr':
##
## combine
##
## Loading required package: knitr
## Loading required package: summarytools
## Warning in fun(libname, pkgname): couldn't connect to display ":0"
## system might not have X11 capabilities; in case of errors when using dfSummary(), set st_options(use.x11 = FALSE)
##
## Attaching package: 'summarytools'
##
## The following object is masked from 'package:tibble':
##
## view
data("vivienda")
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>
# Eliminación de variable con alto porcentaje de NA
vivienda <- vivienda %>% select(-piso)
# Imputación con mediana en variables numéricas
vivienda <- vivienda %>%
mutate(across(c(preciom, areaconst, parqueaderos, banios, habitaciones),
~ ifelse(is.na(.), median(., na.rm = TRUE), .)))
# Conversión a factores
vivienda <- vivienda %>%
mutate(
estrato = as.factor(estrato),
tipo = as.factor(tipo),
zona = as.factor(zona)
)
dim(vivienda)
## [1] 8322 12
La variable “Piso” fue eliminada debido a su alto porcentaje de valores faltantes, lo que podría introducir sesgos o distorsiones en el análisis multivariado.
Las variables numéricas fueron imputadas utilizando la mediana, ya que esta medida es importante frente a valores atípicos y mantiene la estructura central de los datos sin alterar significativamente la distribución.
Las variables categóricas fueron convertidas a factores para permitir su correcta utilización en el Análisis de Correspondencias Múltiples (MCA).
vars_num <- vivienda %>%
select(preciom, areaconst, parqueaderos, banios, habitaciones)
cor_matrix <- cor(vars_num)
corrplot(cor_matrix, method="color", addCoef.col="black")
Interpretación
se evidencia una relación positiva significativa entre el precio (preciom) y el área construida (areaconst), así como con el número de baños. Esto indica que las características estructurales de la vivienda son determinantes en la valoración económica.
El mercado responde principalmente a atributos físicos medibles, lo que permite estructurar modelos de valoración basados en características objetivas.
Se estandarizan las variables antes del análisis para evitar que aquellas con mayor escala dominaran los resultados.
datos_pca <- scale(vars_num)
res.pca <- prcomp(datos_pca)
summary(res.pca)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5
## Standard deviation 1.7690 0.9399 0.66884 0.5886 0.43953
## Proportion of Variance 0.6259 0.1767 0.08947 0.0693 0.03864
## Cumulative Proportion 0.6259 0.8026 0.89207 0.9614 1.00000
fviz_eig(res.pca,
main = "Gráfico de sedimentación (Scree Plot)",
xlab = "Componentes principales",
ylab = "Porcentaje de varianza explicada")
## Warning in geom_bar(stat = "identity", fill = barfill, color = barcolor, :
## Ignoring empty aesthetic: `width`.
El primer componente explica aproximadamente el 62% de la variabilidad total del mercado inmobiliario, mientras que el segundo componente aporta un 18% adicional. En conjunto, los dos primeros componentes concentran cerca del 80% de la información original, lo que permite reducir dimensionalidad sin pérdida significativa de información.
fviz_pca_var(res.pca, repel=TRUE)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## ℹ The deprecated feature was likely used in the ggpubr package.
## Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## ℹ The deprecated feature was likely used in the factoextra package.
## Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Interpretación
En el plano factorial:
Variables cercanas entre sí indican correlación positiva.
Variables ubicadas lejos del centro tienen mayor contribución.
Variables en direcciones opuestas indican relación negativa.
El mercado inmobiliario presenta una estructura latente donde las características físicas de la vivienda explican la mayor parte de la variación en precios.
El análisis de conglomerados permite segmentar el mercado en grupos con características similares, facilitando la comprensión diferenciandolos en la oferta.
set.seed(123)
wss <- numeric(6)
for (k in 1:6) {
km_temp <- kmeans(datos_pca, centers = k, nstart = 10)
wss[k] <- km_temp$tot.withinss
}
plot(1:6, wss, type = "b",
xlab = "Número de clusters",
ylab = "WSS",
main = "Método del Codo")
El gráfico del WSS muestra cómo disminuye la variabilidad interna al aumentar el número de clusters.
El punto donde la reducción deja de ser significativa sugiere el número más correcto de segmentos.
set.seed(123)
km <- kmeans(datos_pca, centers=4, nstart=25)
km$size
## [1] 4493 810 2369 650
El algoritmo K-means se aplicó sobre los datos estandarizados del Análisis de Componentes Principales, para evitar problemas de diferencias de escala entre variables.
Se definieron 4 conglomerados, según se sugiere en el método del
codo.
El parámetro “nstart=25” permite ejecutar el algoritmo con múltiples
inicializaciones aleatorias, estabilizando en la solución final y
reduciendo la probabilidad de convergencia.
vivienda$cluster <- as.factor(km$cluster)
aggregate(vivienda[,c("preciom","areaconst",
"banios","habitaciones",
"parqueaderos")],
by = list(Cluster = vivienda$cluster),
mean)
## Cluster preciom areaconst banios habitaciones parqueaderos
## 1 1 239.2459 91.04641 2.128199 2.865791 1.419764
## 2 2 1159.8247 426.19991 5.165432 4.374074 3.933333
## 3 3 545.0599 207.62989 3.824398 3.767412 2.010975
## 4 4 469.2369 322.28320 4.747692 7.166154 1.858462
Existe una relación entre precio y área construida, lo que confirma los resultados obtenidos en el análisis de correlación y PCA.
El mercado inmobiliario presenta una estructura claramente segmentada en cuatro niveles:
Económico, Medio, Medio-alto, Premium.
El Cluster 4 rompe parcialmente la relación lineal precio-área, lo que indica que la ubicación o el estrato pueden estar influyendo en la valorización.
fviz_cluster(km, data=datos_pca,
ellipse.type="convex",
ggtheme=theme_minimal())
Interpretación
La visualización muestra cuatro segmentos diferenciados que podrían corresponder a:
Viviendas de menor tamaño y precio reducido.
Segmento intermedio.
Viviendas amplias con mayor valorización.
Segmento premium.
La empresa puede diseñar estrategias comerciales diferenciadas por segmentos, optimizando precios, promociones y localización de inversiones.
# Selección de variables categóricas y eliminación de valores faltantes
datos_mca <- vivienda %>%
select(zona, tipo, estrato) %>%
drop_na()
# Aplicación del MCA
res.mca <- MCA(datos_mca, graph = FALSE)
summary(res.mca)
##
## Call:
## MCA(X = datos_mca, 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
## 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
## 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
## 3 | 1.720 30.646 0.626 72.168 | 0.612 4.816 0.079
## 4 | -0.199 0.600 0.014 -10.636 | -0.894 15.033 0.275
## 5 | -0.206 0.830 0.021 -13.188 | -0.471 5.394 0.110
## v.test Dim.3 ctr cos2 v.test
## 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 |
## Apartamento 6.380 | -0.282 4.271 0.126 -32.337 |
## Casa -6.380 | 0.446 6.767 0.126 32.337 |
## 3 25.688 | -0.238 0.867 0.012 -9.976 |
## 4 -47.795 | 0.702 11.075 0.170 37.552 |
## 5 -30.184 | -0.758 16.683 0.284 -48.589 |
##
## Categorical variables (eta2)
## Dim.1 Dim.2 Dim.3
## zona | 0.747 0.689 0.634 |
## tipo | 0.261 0.005 0.126 |
## estrato | 0.679 0.665 0.379 |
El análisis de correspondencias múltiples se aplicó a las variables categóricas zona, tipo y estrato, con el objetivo de identificar patrones de segmentación territorial y socioeconómica en el mercado inmobiliario.
La ubicación y el nivel socioeconómico son más determinantes en la estructura del mercado que el tipo de vivienda.
fviz_mca_var(res.mca, repel=TRUE)
Interpretación
El plano factorial evidencia que la oferta inmobiliaria no se distribuye de manera aleatoria, sino que responde a una estructura territorial asociada al estrato socioeconómico.
Mientras que el PCA y el clustering mostraron segmentación por características estructurales (precio, tamaño), el MCA confirma que dicha segmentación está alineada con patrones territoriales y sociales.
Esto sugiere que las decisiones estratégicas deben considerar no solo variables físicas de la vivienda, sino también la dinámica geográfica y socioeconómica del entorno.
El análisis realizado permitió identificar una estructura clara y consisa del mercado inmobiliario urbano. Se evidenció que el precio de la vivienda está principalmente determinado por variables estructurales como el área construida, el número de baños y los parqueaderos, confirmando que el tamaño y el nivel de equipamiento influyen directamente en su valorización.
La segmentación mediante conglomerados mostró que el mercado se organiza en cuatro niveles diferenciados: económico, medio, medio-alto y premium, lo que demuestra que la oferta no es homogénea, sino escalonada y claramente segmentada.
Adicionalmente, el análisis de correspondencias reveló que la ubicación geográfica y el estrato socioeconómico son factores fundamentales en la organización del mercado, reforzando la importancia de las dinámicas territoriales en la estructuración de la oferta.
En conjunto, los resultados evidencian que el mercado inmobiliario responde a una interacción entre características físicas, valor económico y contexto territorial, lo que permite una comprensión más integral para la toma de decisiones estratégicas.