El presente informe tiene como objetivo analizar el mercado inmobiliario urbano a partir de una base de datos real de viviendas ofertadas.
Se aplican técnicas de análisis multivariado como:
Con el fin de identificar patrones, segmentaciones y relaciones relevantes para la toma de decisiones estratégicas.
library(dplyr)
library(ggplot2)
library(FactoMineR)
library(factoextra)
library(cluster)
library(corrplot)
library(paqueteMODELOS)
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")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ";"
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
head(vivienda)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1147 Zona O… <NA> 3 250 70 1 3 6
## 2 1169 Zona O… <NA> 3 320 120 1 2 3
## 3 1350 Zona O… <NA> 3 350 220 2 2 4
## 4 5992 Zona S… 02 4 400 280 3 5 3
## 5 1212 Zona N… 01 5 260 90 1 2 3
## 6 1724 Zona N… 01 5 240 87 1 3 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
summary(vivienda)
## id zona piso estrato
## Min. : 1 Length:8322 Length:8322 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## NA's :3 NA's :3
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1605 NA's :3
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8322 Length:8322 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## NA's :3 NA's :3
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
## NA's :3
La base de datos contiene 8.322 registros de viviendas y 13 variables que describen características físicas, ubicación y precio.
Se identifican variables numéricas como precio, área construida, número de baños y habitaciones, así como variables categóricas como zona, tipo de vivienda y barrio.
Se observan algunos valores faltantes (NA), especialmente en parqueaderos.
colSums(is.na(vivienda))
## id zona piso estrato preciom areaconst
## 3 3 2638 3 2 3
## parqueaderos banios habitaciones tipo barrio longitud
## 1605 3 3 3 3 3
## latitud
## 3
Se realizó un análisis de valores faltantes en las variables numéricas.Se encontró que la mayoría de variables presentaban menos del 1% de datos faltantes, por lo cual se imputaron usando la media.
La variable parqueaderos presentó aproximadamente un 19% de valores faltantes. Por lo que al proceder a hacer una eliminación se piede casi un quinto de la base de datos, por lo que en este caso es mejor hacer una imputación. En este caso, se utilizó la mediana para la imputación, dado que es una variable de conteo y la mediana es más robusta ante valores extremos.
Esta estrategia permitió conservar la totalidad de las observaciones sin introducir sesgos significativos.
vars <- vivienda %>%
select(preciom, areaconst, parqueaderos, banios, habitaciones, estrato)
vivienda_num <- vars %>%
mutate(
parqueaderos = ifelse(is.na(parqueaderos),
median(parqueaderos, na.rm=TRUE),
parqueaderos)
) %>%
mutate(across(-parqueaderos,
~ifelse(is.na(.), mean(., na.rm=TRUE), .)))
colSums(is.na(vivienda_num))
## preciom areaconst parqueaderos banios habitaciones estrato
## 0 0 0 0 0 0
cor_mat <- cor(vivienda_num)
corrplot(cor_mat, method="color", addCoef.col="black")
La matriz de correlaciones muestra asociaciones importantes entre las variables analizadas. Se observa una fuerte correlación positiva entre el precio y el área construida (0.69), lo cual indica que viviendas de mayor tamaño tienden a tener mayor valor comercial.
El precio también presenta alta correlación con el número de baños (0.67) y parqueaderos (0.62), sugiriendo que estas características influyen significativamente en el valor de la vivienda. Asimismo, el estrato muestra una correlación positiva con el precio (0.61), lo cual refleja la relación entre nivel socioeconómico y valor del inmueble. Por otro lado, el número de habitaciones presenta correlaciones moderadas, lo que indica que no siempre más habitaciones implican mayor precio si no están acompañadas de mayor área o calidad.
Al encontrar estas relaciones, se justifica la aplicación de técnicas multivariadas como el Análisis de Componentes Principales (PCA) para sintetizar la información, y obtener mejores resultados.
La variable piso no fue considerada en los análisis multivariados debido a que presentaba una alta proporción de valores faltantes y no aplicaba de manera homogénea a todos los tipos de vivienda. Su inclusión podría introducir sesgos y distorsiones en los modelos, por lo que se decidió excluirla del análisis.
La variable estrato, aunque corresponde a una categoría socioeconómica ordinal, fue tratada como variable numérica en el PCA y el análisis de conglomerados con el fin de capturar su naturaleza ordenada y su relación progresiva con el valor de la vivienda. En el análisis de correspondencias múltiples se consideró como variable categórica.
Si bien la base de datos incluye variables geográficas como latitud y longitud, estas no fueron incorporadas en los análisis multivariados realizados.
Dado que el objetivo del estudio es identificar patrones asociados a características físicas, tipológicas y socioeconómicas de las viviendas, se priorizaron variables directamente relacionadas con el valor y estructura del inmueble.
La dimensión espacial fue considerada a través de la variable categórica zona, lo que permitió capturar diferencias territoriales de manera interpretativa sin introducir complejidad geoespacial adicional en los modelos.
Antes de aplicar el PCA, las variables fueron estandarizadas para eliminar el efecto de las diferentes escalas de medición.
Este proceso asegura que todas las variables contribuyan de manera equitativa al análisis.
datos_scaled <- scale(vivienda_num)
pca <- prcomp(datos_scaled)
summary(pca)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6
## Standard deviation 1.835 1.0958 0.7890 0.62298 0.48690 0.43076
## Proportion of Variance 0.561 0.2001 0.1038 0.06468 0.03951 0.03093
## Cumulative Proportion 0.561 0.7611 0.8649 0.92956 0.96907 1.00000
El Análisis de Componentes Principales permitie reducir la dimensionalidad del conjunto de datos.
El primer componente principal explica el 56.1% de la variabilidad total, mientras que el segundo componente explica un 20.0%. Por lo que, los dos primeros componentes representan el 76.1% de la variabilidad acumulada, lo cual indica que una gran parte de la información original puede resumirse en solo dos dimensiones.
Esto evidencia la existencia de patrones comunes entre las variables analizadas.
fviz_eig(pca, addlabels=TRUE)
Lo anterior se representa graficamente en el gráfico de sedimentación (Scree Plot) muestra que los dos primeros componentes concentran la mayor proporción de varianza, confirmando que son suficientes para representar la estructura de los datos.
El gráfico de variables del PCA permite interpretar la contribución de cada variable a los componentes principales.
fviz_pca_var(pca, col.var="contrib")
El primer componente (56.1% de varianza) está fuertemente asociado con el precio, el área construida, el número de baños y parqueaderos. Esto sugiere que este componente representa el tamaño y valor general de la vivienda.Es decir, viviendas con mayor área, más baños y parqueaderos tienden a tener precios más altos.
El segundo componente (20%) muestra un contraste entre el estrato y el número de habitaciones. Esto indica que un mayor número de habitaciones no necesariamente implica un mayor nivel socioeconómico. Este hallazgo sugiere que la calidad y ubicación de la vivienda pueden ser más determinantes que la cantidad de habitaciones.
Resumiendo, el PCA revela que el valor de la vivienda depende más de su tamaño, calidad y ubicación que del número de habitaciones por sí solo.
Por último para hacer el análisis mas profundo, se intentó visualizar un biplot del PCA; sin embargo, debido al gran número de observaciones, la gráfica resultó poco interpretable. Por esta razón, se priorizó el análisis de cargas y varianza explicada.
El análisis de conglomerados tiene como objetivo identificar grupos de viviendas con características similares, permitiendo segmentar el mercado inmobiliario.
Esta técnica facilita reconocer patrones en los datos y clasificar las viviendas en segmentos homogéneos, lo cual resulta útil para la toma de decisiones comerciales y estrategias de mercado.
fviz_nbclust(datos_scaled, kmeans, method = "wss")
Al analizar el gráfico del método del codo, no se observa facilmente un
punto de inflexión completamente definido. Sin embargo, se evidencia una
disminución pronunciada en la variabilidad al pasar de 1 a 2
conglomerados, y reducciones progresivamente menores a partir de
allí.
A partir de 4 conglomerados la curva comienza a estabilizarse, lo que indica que agregar más grupos no genera mejoras sustanciales. Por esta razón, se decidió trabajar con 4 clusters, ya que representan un balance adecuado entre capacidad explicativa e interpretabilidad de los segmentos.
Por lo tanto, se seleccionaron 4 clusters, logrando un equilibrio entre capacidad explicativa e interpretabilidad de los segmentos.
set.seed(123)
km <- kmeans(datos_scaled, centers = 4, nstart = 25)
km$size
## [1] 2520 3962 941 899
La segmentación generó cuatro conglomerados con tamaños relativamente balanceados.
Esto indica que la clasificación logró identificar grupos representativos dentro del mercado inmobiliario, evitando la formación de segmentos demasiado pequeños o poco significativos.
vivienda_cluster <- vivienda_num %>%
mutate(cluster = km$cluster)
aggregate(. ~ cluster, vivienda_cluster, mean)
## cluster preciom areaconst parqueaderos banios habitaciones estrato
## 1 1 515.5547 173.68943 1.967063 3.526323 3.391594 5.450357
## 2 2 220.1055 91.12276 1.373801 2.072438 2.892983 4.042655
## 3 3 444.4346 298.11068 1.834219 4.453773 6.433581 3.893730
## 4 4 1136.1290 418.86615 3.794216 5.121246 4.383760 5.723026
El análisis de conglomerados permitió identificar cuatro segmentos diferenciados en el mercado inmobiliario.
Un primer segmento corresponde a viviendas económicas, con menor precio, área y número de baños, orientadas a estratos medios.
Un segundo grupo representa viviendas de nivel medio, con características balanceadas en tamaño y precio.
Se identificó además un segmento de viviendas amplias con muchas habitaciones pero ubicadas en estratos no tan altos, lo cual sugiere propiedades grandes en zonas menos exclusivas.
Finalmente, se observa un segmento de viviendas que podemos llamar premium, con altos precios, gran área construida y mayor número de parqueaderos y baños, asociado a estratos altos.
Ahora veamos cómo se ve esta distribución graficamente
fviz_cluster(km, data = datos_scaled)
El gráfico de conglomerados permite visualizar la segmentación de las
viviendas en los cuatro grupos con características relativamente
diferenciadas. Se observa que los clusters se separan principalmente a
lo largo de la primera componente principal, lo que indica que variables
como precio, área construida y número de baños tienen un papel
importante en la diferenciación de los segmentos. Cada conglomerado
representa perfiles de vivienda distintos, desde propiedades de menor
valor y tamaño hasta viviendas de mayor precio y características más
amplias. La segmentación facilita la identificación de patrones en el
mercado inmobiliario y puede apoyar la toma de decisiones estratégicas
según el tipo de vivienda analizada.
El análisis de correspondencias múltiples (MCA) se aplicó a las variables categóricas con el fin de explorar asociaciones entre categorías de zona, tipo de vivienda, barrio y estrato.
Esta técnica permite representar las relaciones entre categorías en un espacio bidimensional, facilitando la identificación de patrones de asociación en el mercado inmobiliario.
La variable barrio no fue incluida en el análisis de correspondencias debido a su alta cantidad de categorías, lo que puede generar dispersión excesiva y reducir la claridad interpretativa del modelo.
vivienda_cat <- vivienda %>%
select(zona, tipo, estrato) %>%
na.omit() %>%
mutate(across(everything(), as.factor))
mca_res <- MCA(vivienda_cat, graph = FALSE)
fviz_mca_var(mca_res, repel = TRUE)
El análisis de correspondencias múltiples permitió examinar las relaciones estructurales entre las variables categóricas zona, tipo de vivienda y estrato socioeconómico, identificando patrones de asociación dentro del mercado inmobiliario urbano.
La primera dimensión (21.1% de la inercia explicada) refleja principalmente diferencias territoriales y socioeconómicas, evidenciando que ciertas zonas de la ciudad se asocian con determinados niveles de estrato. En particular, se observa una diferenciación clara entre zonas con mayor concentración de estratos altos y aquellas con predominancia de estratos medios.
La segunda dimensión (17% de la inercia explicada) introduce un contraste adicional entre zonas y niveles socioeconómicos, sugiriendo que la configuración espacial de la oferta inmobiliaria no es homogénea y responde a patrones estructurales del mercado urbano.
Asimismo, el tipo de vivienda presenta una diferenciación moderada en el espacio factorial, lo que indica que casas y apartamentos tienden a concentrarse en determinadas zonas y estratos específicos. Estos resultados evidencian que la oferta inmobiliaria no solo depende de características físicas, sino también de dinámicas territoriales y socioeconómicas claramente definidas.
Desde una perspectiva estratégica, estos resultados permiten a la empresa inmobiliaria identificar patrones territoriales en la oferta, facilitando la segmentación comercial según tipo de vivienda y nivel socioeconómico predominante en cada zona.
Este análisis cualitativo complementa los hallazgos del PCA y del clustering, aportando una visión integral del mercado inmobiliario urbano.
El análisis integral del mercado inmobiliario urbano permitió identificar patrones estructurales relevantes en la oferta de viviendas, combinando técnicas de reducción de dimensionalidad, segmentación y análisis de asociaciones categóricas.
El Análisis de Componentes Principales evidenció que el precio de la vivienda está fuertemente asociado con el área construida, el número de baños y parqueaderos, lo que confirma que el tamaño y las características físicas del inmueble son determinantes clave del valor comercial. Además, se identificó que el nivel socioeconómico (estrato) introduce diferenciaciones adicionales en la estructura del mercado.
El análisis de conglomerados permitió segmentar el mercado en cuatro grupos claramente diferenciados: viviendas económicas, viviendas de nivel medio, viviendas amplias en estratos intermedios y viviendas premium. Esta segmentación facilita la identificación de perfiles específicos de clientes y oportunidades estratégicas según tipo de inmueble.
Por su parte, el análisis de correspondencias múltiples reveló asociaciones territoriales entre zona, tipo de vivienda y estrato socioeconómico, evidenciando que la distribución espacial de la oferta no es homogénea y responde a dinámicas estructurales del mercado urbano.
En conjunto, los resultados permiten concluir que el mercado inmobiliario presenta una segmentación clara tanto en términos físicos como territoriales, lo que proporciona a la empresa inmobiliaria información estratégica para optimizar decisiones de inversión, comercialización y posicionamiento competitivo.