Introducción

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

Cargue Librería y base
# 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>


1. Análisis de Componentes Principales

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.

Entendimiento de la base de datos
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
  • Cantidad de registros
## [1] 8322   13

La base contiene 8.322 regitros y 13 columnas

  • Tipo de datos
##           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"
  • Revisión datos faltantes
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.

  • Eliminación de otros NAs
# 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
PCA
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
# 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
# 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.



2. Análisis de Conglomerados

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.

  • Método del codo:

  • Distancias euclidianas
dist_viv <- dist(cluster_scaled, method = "euclidean")
  • Comparación de métodos de enlace
Comparación de métodos de enlace (k = 4)
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.



3. Análisis de Correspondencias

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

Conclusiones y recomendaciones

  • 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:

  • Cluster 1: Familiar accesible (Estrato 3, más casas): tamaño/valor medio-bajo.
  • Cluster 2 : Medio-alto urbano (Estrato 4, más apartamentos): precio/tamaño intermedios.
  • Cluster 3: Alto urbano en altura (Estrato 5, apartamentos): pisos altos, valor medio-alto
  • Cluster 4: Premium (Estrato 6): mayor valor/ tamaño

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