Una empresa inmobiliaria líder en una gran ciudad está buscando comprender en profundidad el mercado de viviendas urbanas para tomar decisiones estratégicas más informadas. La empresa posee una base de datos extensa que contiene información detallada sobre diversas propiedades residenciales disponibles en el mercado. Se requiere realizar un análisis holístico de estos datos para identificar patrones, relaciones y segmentaciones relevantes que permitan mejorar la toma de decisiones en cuanto a la compra, venta y valoración de propiedades
# Cargar librería y base
library(paqueteMODELOS)
library(factoextra)
library(tidyverse)
library(cluster)
library(fastDummies)
library(FactoMineR)
library(gridExtra)
data("vivienda")
# Estructura de la base
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>
Reducir la dimensionalidad del conjunto de datos y visualizar la estructura de las variables en componentes principales para identificar características clave que influyen en la variación de precios y oferta del mercado.
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1147 | Zona Oriente | NA | 3 | 250 | 70 | 1 | 3 | 6 | Casa | 20 de julio | -76.51168 | 3.43382 |
| 1169 | Zona Oriente | NA | 3 | 320 | 120 | 1 | 2 | 3 | Casa | 20 de julio | -76.51237 | 3.43369 |
| 1350 | Zona Oriente | NA | 3 | 350 | 220 | 2 | 2 | 4 | Casa | 20 de julio | -76.51537 | 3.43566 |
| 5992 | Zona Sur | 02 | 4 | 400 | 280 | 3 | 5 | 3 | Casa | 3 de julio | -76.54000 | 3.43500 |
| 1212 | Zona Norte | 01 | 5 | 260 | 90 | 1 | 2 | 3 | Apartamento | acopi | -76.51350 | 3.45891 |
| 1724 | Zona Norte | 01 | 5 | 240 | 87 | 1 | 3 | 3 | Apartamento | acopi | -76.51700 | 3.36971 |
| 2326 | Zona Norte | 01 | 4 | 220 | 52 | 2 | 2 | 3 | Apartamento | acopi | -76.51974 | 3.42627 |
| 4386 | Zona Norte | 01 | 5 | 310 | 137 | 2 | 3 | 4 | Apartamento | acopi | -76.53105 | 3.38296 |
| 1209 | Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
| 1592 | Zona Norte | 02 | 5 | 780 | 380 | 2 | 3 | 3 | Casa | acopi | -76.51674 | 3.48721 |
## [1] 8322 13
La base contiene 8.322 regitros y 13 columnas
## id zona piso estrato preciom areaconst
## "numeric" "character" "character" "numeric" "numeric" "numeric"
## parqueaderos banios habitaciones tipo barrio longitud
## "numeric" "numeric" "numeric" "character" "character" "numeric"
## latitud
## "numeric"
library(mice)
md.pattern(vivienda,rotate.names = TRUE)
## preciom id zona estrato areaconst banios habitaciones tipo barrio longitud
## 4808 1 1 1 1 1 1 1 1 1 1
## 1909 1 1 1 1 1 1 1 1 1 1
## 876 1 1 1 1 1 1 1 1 1 1
## 726 1 1 1 1 1 1 1 1 1 1
## 1 1 0 0 0 0 0 0 0 0 0
## 2 0 0 0 0 0 0 0 0 0 0
## 2 3 3 3 3 3 3 3 3 3
## latitud parqueaderos piso
## 4808 1 1 1 0
## 1909 1 1 0 1
## 876 1 0 1 1
## 726 1 0 0 2
## 1 0 0 0 12
## 2 0 0 0 13
## 3 1605 2638 4275
Se identifica que las dos variables con mayor faltantes son ‘parqueadero’ y ‘piso’
Se realizará imputación de datos con paquete mice, el cual imputa usando modelos predictivos, dependiendo del tipo de dato.
##
## iter imp variable
## 1 1 piso parqueaderos
## 2 1 piso parqueaderos
## 3 1 piso parqueaderos
## 4 1 piso parqueaderos
## 5 1 piso parqueaderos
## piso parqueaderos
## 0 0
Aunque la base de datos contiene varias variables numéricas, no todas son apropiadas para un Análisis de componentes principales. Por lo que para efectos del ejercicio se incluirán: ‘piso’, ‘precio’, ‘areaconst’, ‘parqueaderos’, ‘banios’, ‘habitaciones’. Estas variables representan características fisicas o de valor de las propiedades.
Se excluirán las variables como latitud, longitud y id, aunque son numéricas se emplean para elaboración de mapas o análisis espaciales. Lo que no aportan para PCA, al igual que la variable id. Así mismo se aplicará imputación de las demás variables.
# Selección de variables numéricas para PCA (sin estrato, lat, long)
vivienda_num <- vivienda %>%
select(piso, preciom, areaconst, parqueaderos, banios, habitaciones)
# Eliminar registros con NA en estas variables
vivienda_num <- na.omit(vivienda_num)
# Verificar que no quedan NAs
colSums(is.na(vivienda_num))
## piso preciom areaconst parqueaderos banios habitaciones
## 0 0 0 0 0 0
#Escalar datos
vivienda_scaled <- scale(vivienda_num)
head(vivienda_num)
## # A tibble: 6 × 6
## piso preciom areaconst parqueaderos banios habitaciones
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 3 250 70 1 3 6
## 2 5 320 120 1 2 3
## 3 3 350 220 2 2 4
## 4 2 400 280 3 5 3
## 5 1 260 90 1 2 3
## 6 1 240 87 1 3 3
res.pca <- prcomp(vivienda_scaled, center = TRUE, scale. = TRUE)
#Varianza explicada
fviz_eig(res.pca, addlabels = TRUE)
El gráfico Scree plot muestra el porcentaje de varianza explicada por cada componente principal, observando que el componente 1 explica el 51.5% de la variabilidad total, concentrando más de la mitad de la información del conjunto de datos. Entre los tres primeros componentes, se alcanza un acumulado de 82,9% de la varianza.
# Matriz de cargas de cada variable en los componentes
res.pca$rotation
## PC1 PC2 PC3 PC4 PC5
## piso 0.0977940 -0.87787155 0.43553879 0.1208656 0.11957345
## preciom -0.4707756 -0.27977198 -0.24856139 -0.4288363 -0.14095552
## areaconst -0.4920496 0.02738970 0.03016489 -0.3227270 0.70885651
## parqueaderos -0.3859612 -0.19721206 -0.53072613 0.7224213 0.04796004
## banios -0.4924778 -0.02802988 0.23008466 -0.1112728 -0.66993764
## habitaciones -0.3676865 0.33262698 0.64265395 0.4038118 0.11063259
## PC6
## piso -0.03431518
## preciom 0.65920112
## areaconst -0.38677742
## parqueaderos -0.07923653
## banios -0.49248644
## habitaciones 0.40725699
De esta matriz se puede observar que para PC1, las variables areaconst (-0,49), banios (-0,49), preciom(-0,47) y habitaciones (-0,37) tiene valores negativos altos indicando que este componente esta fuertemente relacionado con tamaña y valor de la vivienda (a mayor área, baños, habitaciones y precio, mayor peso absoluto en PC1). PC2 esta dominado por piso (-0,877), lo que sugiere que PC2 representa principalmente la altura o nivel del inmueble.
# Contribución de variables
fviz_pca_var(res.pca, col.var = "contrib",
gradient.cols = c("blue", "orange", "red"), repel = TRUE)
El gráfico muestra la proyección de las variables originales sobre los dos primeros componentes principales (Dim1 y Dim2),que explican conjuntamente el 68.7% de la variabilidad total del conjunto de datos
Dim1: Agrupa las variables habitaciones, areaconst,banios,parqueaderos y preciom, todas orientadas a la misma dirección, indicando una fuerte correlación entre sí. Dimesión 1 representa un factor de tamaño y valor de la vivienda
Dim2: esta influenciada por la variable piso, indicando que esta característica aporta información diferente a las demás variables. Este componente esta relacionado con la ubicación de la vivienda
Para explicar el sentido de los ejes, se escogen cuatro casos extremos conformados por los siguientes clientes:
datos<- rbind(vivienda_num[100,],
vivienda_num[280,],
vivienda_num[10,],
vivienda_num[500,])
datos <- as.data.frame(datos)
rownames(datos) = c("vivienda 100","vivienda 280","vivienda 10","vivienda 500")
datos
## piso preciom areaconst parqueaderos banios habitaciones
## vivienda 100 3 310 93 1 3 3
## vivienda 280 3 610 750 1 8 10
## vivienda 10 2 780 380 2 3 3
## vivienda 500 5 750 220 2 4 3
La vivienda 280 representa un área de 750m2, 10 habitaciones y un precio alto de 610. Se destaca por gran tamaño y gran cantidad de habitaciones. A diferencia de la vivienda 100 con variables de precio y área muy por debajo.
La Vivienda 10: Precio y área altas, pero menos habitaciones que 280. Muestra que se puede tener valor alto sin necesariamente tener muchas habitaciones.
Vivienda 500: Precio alto y área moderada. Caso intermedio en PC1 y cercano al promedio en PC2.
El PCA permitió reducir las variables numéricas a dos dimensiones principales que explican casi el 69% de la variabilidad del mercado:
PC1: tamaño + valor económico de la propiedad.
PC2: distribución interna (habitaciones) vs. ubicación en pisos altos.
Agrupar las propiedades residenciales en segmentos homogéneos con características similares para entender las dinámicas de las ofertas específicas en diferentes partes de la ciudad y en diferentes estratos socioeconómicos.
Para este análsis se incluirá la variable estrato y se aplicarán las normalizaciones correspondientes.
dist_viv <- dist(cluster_scaled, method = "euclidean")
| metodo | silhouette_prom |
|---|---|
| complete | 0.137 |
| average | 0.269 |
| ward.D2 | 0.499 |
En el material de la clase se ilustraron clustering jerárquico con enlaces de complete y average. Al aplicarlos fueron muy bajos (0,14 y 0,26) por lo que se evaluó con Ward-D2 un enlace estándar que minimiza la varianza. Entre ‘complete, average y Ward.D2’, este último obtuvo el mayor Silhouette (~0.50), por lo que se adoptó para reportar los resultados
## Silhouette promedio (ward.D2), k = 4 : 0.499
## cluster size ave.sil.width
## 1 1 1453 0.51
## 2 2 2129 0.54
## 3 3 2750 0.49
## 4 4 1987 0.47
Los 4 clústeres están razonablemente separados
El cluster 3: representa valores altos en Dim2 y medios altos en Dim1: Viviendas en pisos altos, tamaño y valor medio
El cluster 4 : es mayor en Dim1 y bajo en Dim2 representando grandes y de alto valor las viviendas, pero en pisos bajos o posiblemente casas
El cluster 1: medio/ bajo en Dim 1 y 2. Tamaño/valor medio en pisos medios (apartamento familiar).
Cluster 2 : bajo en Dim1 y bajo en Dim2. Más pequeños y económicos, pisos bajos (casas o aptos en pisos bajos).
El análisis de conglomerados, utilizando PC1 y PC2 obtenidos del PCA y la variable estrato, permiten identificar 4 segmentos diferenciados de viviendas. Estos grupos combinan factores de tamaño, valor económico y nivel socioeconómico, lo que facilita el diseño de estrategias diferenciadas
Del análisis de conglomerados, se puede concluir:
Cluster 3: Alto urbano, estrato 5, mayoría apartamentos: Pisos altos, valor medio-alto
Cluster 4: Estrato alto 6, mayor tamaño y valor de vivienda, oferta de gama alta.
Cluster 1: Estrato 3, mayor proporción en tipo de vivienda casas. Tamaño valor medio-bajo
Cluster 2: Estrato 4, más apartamentos. Precio / tamaño intermedio.
Examinar la relación entre las variables categóricas (tipo de vivienda, zona y estrato), para identificar patrones de comportamiento de la oferta en mercado inmobiliario.
## tipo zona estrato
## 8319 1 1 1 0
## 3 0 0 0 3
## 3 3 3 9
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
Para el analisis de correspondencia se utilizan inicialmente los campos tipo y zona
##
## Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
## Apartamento 24 1198 1029 62 2787
## Casa 100 722 169 289 1939
La mayor concentración de encuentra en la zona sur, tanto apartamentos como casas.
##
## Pearson's Chi-squared test
##
## data: tabla
## X-squared = 690.93, df = 4, p-value < 2.2e-16
El resultado indica que se rechaza la hipótesis de independencia de las variables (p-value: 0.0000), indicando grado tipo de relación entre ellas.
Ahora vamos a analizar las variables tipo de vivienda y 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
##
## Pearson's Chi-squared test
##
## data: tabla_ze
## X-squared = 3830.4, df = 12, p-value < 2.2e-16
Al igual que la comparación anterior el resultado indica que se rechaza la hipótesis de independencia de las variables (p-value: 0.0000), indicando grado tipo de relación entre ellas.
Finalmente se procede a realizar el análisis de correspondencia que consiste en estimar las coordenadas para cada uno de los niveles de ambas variables y representarlas en un plano cartesiano
El gráfico nos permite establecer relaciones y validarlas como son:
El estrato 6 se encuentra ubicado en la Zona Oeste Los estratos 4 y 5 están ubicados principalmente en la Zona Sur El estrato 3 está presente en las Zonas Oriente y Centro
Para medir el grado de representatividad del proceso calculas los valores de la varianza acumulada, utilizando para ellos los valores propios de la matriz de discrepancias
# Varianza explicada
fviz_screeplot(res_ze, addlabels = TRUE, ylim = c(0, 80)) +
labs(y = "Porcentaje de varianza explicado", x = "Ejes")
Los resultados indican que la primera componente resumen el 68.9% y los dos primeros componentes prepresentados en el plano factorial, mientras que los dos primeros ejes resumen un 96.4% de los datos
A partir del análisis de componentes principales se identificaron PC1 relacionada con el tamaño y valor de la vivienda (área, baños, habitaciones,precio y parqueadero) y PC2 relacionada con piso (altura)
El Análisis de correspondencia confirma asociación por territorio y nivel socioeconómico. Definiendo 4 segmentos comerciales con comportamientos diferentes en valor/ tamaño, pisos, estrato y tipo de vivienda. Los clústeres muestran ordenamiento por estrato y diferencias por tipo (casa/apartamento).
Del análisis de correspondencia, las variables categóricas estan asociadas. El mapa facatorial muestra relación de zonas con estratos altos y otras con bajos/ medios.
Segmentos propuestos:
Recomendaciones
Cluster 1: Campañas de financiación para casas y tambien aptos
Cluster 2: Campañas para familias de ingreso medio-alto. Ofertas de un conjunto que tenga más servicios como piscina, gimnasió, salon social, zona BBQ entre otros.
Cluster 3: Campañas “vida en las alturas”. Vistas relajantes, seguridad, club house
Cluster 4: Campañas “vistas privadas”/ Premium
Ofrecer tarifas diferenciadoras por estrato y zona. Priorizar zonas asociadas a los estratos 5 y 6