Análisis de Mercado Inmobiliario de Cali

Para realizar el análisis del mercado inmobiliario en la ciudad de Cali se parte de la base de datos suministrada “vivienda” la cual consta de 9 atributos y 8,322 registros.

# Realizar un análisis univariado de todas las variables
skim(vivienda)
Data summary
Name vivienda
Number of rows 8322
Number of columns 13
_______________________
Column type frequency:
character 4
numeric 9
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
zona 3 1.00 8 12 0 5 0
piso 2638 0.68 2 2 0 12 0
tipo 3 1.00 4 11 0 2 0
barrio 3 1.00 4 29 0 436 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id 3 1.00 4160.00 2401.63 1.00 2080.50 4160.00 6239.50 8319.00 ▇▇▇▇▇
estrato 3 1.00 4.63 1.03 3.00 4.00 5.00 5.00 6.00 ▅▆▁▇▆
preciom 2 1.00 433.89 328.65 58.00 220.00 330.00 540.00 1999.00 ▇▂▁▁▁
areaconst 3 1.00 174.93 142.96 30.00 80.00 123.00 229.00 1745.00 ▇▁▁▁▁
parqueaderos 1605 0.81 1.84 1.12 1.00 1.00 2.00 2.00 10.00 ▇▁▁▁▁
banios 3 1.00 3.11 1.43 0.00 2.00 3.00 4.00 10.00 ▇▇▃▁▁
habitaciones 3 1.00 3.61 1.46 0.00 3.00 3.00 4.00 10.00 ▂▇▂▁▁
longitud 3 1.00 -76.53 0.02 -76.59 -76.54 -76.53 -76.52 -76.46 ▁▅▇▂▁
latitud 3 1.00 3.42 0.04 3.33 3.38 3.42 3.45 3.50 ▃▇▅▇▅
barrasPiso = ggplot(vivienda, aes(x = piso)) + 
  geom_bar(fill = "#0073C2FF")+
  labs(title = "Cantidad de Viviendas por Piso", x = "Viviendas por Piso", y = "Frecuencia") +
  theme_minimal()
barrasPiso

barrasParqueadero = ggplot(vivienda, aes(x = as.factor(parqueaderos))) + 
  geom_bar(fill = "#0073C2FF")+
  labs(title = "Cantidad de Viviendas por Parqueadero", x = "Viviendas por Parqueadero", y = "Frecuencia") +
  theme_minimal()
barrasParqueadero

Al realizar un análisis inicial de la base de datos se encuentran registros con datos faltantes los cuales serán eliminados para continuar con el análisis, conservando un 57.8% de la data original.

# Convertir 'parqueaderos' y'piso' de factor a numérico
vivienda$parqueaderos = as.numeric(as.character(vivienda$parqueaderos))
vivienda$piso = as.numeric(as.character(vivienda$piso))

# Preparar los datos eliminando columnas no representativas
datos_limpios = vivienda
datos_limpios = subset(datos_limpios, select = -c(barrio, longitud, latitud))
datos_limpios =  na.omit(datos_limpios)

summary(datos_limpios)
       id           zona                piso           estrato     
 Min.   :   1   Length:4808        Min.   : 1.000   Min.   :3.000  
 1st Qu.:2479   Class :character   1st Qu.: 2.000   1st Qu.:4.000  
 Median :4474   Mode  :character   Median : 3.000   Median :5.000  
 Mean   :4427                      Mean   : 3.886   Mean   :4.838  
 3rd Qu.:6413                      3rd Qu.: 5.000   3rd Qu.:6.000  
 Max.   :8316                      Max.   :12.000   Max.   :6.000  
    preciom         areaconst       parqueaderos        banios      
 Min.   :  58.0   Min.   :  40.0   Min.   : 1.000   Min.   : 0.000  
 1st Qu.: 244.5   1st Qu.:  85.0   1st Qu.: 1.000   1st Qu.: 2.000  
 Median : 350.0   Median : 123.0   Median : 2.000   Median : 3.000  
 Mean   : 457.2   Mean   : 174.8   Mean   : 1.815   Mean   : 3.219  
 3rd Qu.: 560.0   3rd Qu.: 225.0   3rd Qu.: 2.000   3rd Qu.: 4.000  
 Max.   :1999.0   Max.   :1500.0   Max.   :10.000   Max.   :10.000  
  habitaciones        tipo          
 Min.   : 0.000   Length:4808       
 1st Qu.: 3.000   Class :character  
 Median : 3.000   Mode  :character  
 Mean   : 3.564                     
 3rd Qu.: 4.000                     
 Max.   :10.000                     

Análisis de componentes principales - PCA

Para el análisis de componentes principales se tienen encuentra solo las variables cuantitativas: Piso, Preciom, Areaconst, Parqueaderos, Banios y Habitaciones.

#PCA


#Se identifican como variables cuantitativas Piso, Preciom, Areaconst, Parqueaderos, Banios y Habitaciones
datosPCA = subset(datos_limpios, select = -c(id, zona, estrato, tipo))
datosZ = scale(datosPCA)

res.pca = PCA(datosZ, ncp = 3, graph = FALSE)

# Gráfico de individuos
fviz_pca_ind(res.pca, 
             geom.ind = "point",         # Mostrar individuos como puntos
             col.ind = "cos2",           # Color por calidad de representación
             gradient.cols = c("#0073C2FF", "#E7B800", "#FC4E07"), # Gradiente de color
             repel = TRUE,               # Evita la superposición de textos
             addEllipses = TRUE,         # Agrega elipses de confianza
             ellipse.level = 0.95,       # Nivel de confianza
             label = "var",              # Etiquetas de variables
             title = "Gráfico de Individuos - PCA")

# Gráfico de variables
fviz_pca_var(res.pca, 
             col.var = "contrib",        # Color por contribución al PCA
             gradient.cols = c("#0073C2FF", "#E7B800", "#FC4E07"), # Gradiente de color
             repel = TRUE,               # Evita la superposición de textos
             title = "Gráfico de Variables - PCA")

La dimensión 1 o el componente principal 1 explica cerca del 56% de la varianza total de los datos, este componente se encuentra fuertemente relacionado con las variables preciom, areaconst, parqueadero y banios.

Mientras que el componente principal 2 explica el 17.8% de la varianza total de los datos, este componente está relacionado con las variables piso y habitaciones.

Entre las variables Preciom y piso parece haber una relación linealmente independiente ya que forman un ángulo de 90° en el gráfico.

# Graficar la varianza explicada por cada componente principal
fviz_eig(res.pca, 
         addlabels = TRUE,
         ylim = c(0, 100),
         main = "Explicación de la Varianza por Componentes",
         xlab = "Número de Componentes Principales",
         ylab = "Varianza Explicada (%)",
         barfill = "#0073C2FF",
         barcolor = "#0073C2FF")

Se puede reducir el modelo de datos en 2 dimensiones simplificando la complejidad del modelo y obteniendo el 73.8% de la varianza total del modelo sumando la varianza de los primeros 2.

res.pca$eig
       eigenvalue percentage of variance cumulative percentage of variance
comp 1  3.3619994              56.033324                          56.03332
comp 2  1.0691744              17.819573                          73.85290
comp 3  0.7316149              12.193581                          86.04648
comp 4  0.3460375               5.767291                          91.81377
comp 5  0.3047888               5.079814                          96.89358
comp 6  0.1863850               3.106417                         100.00000
res.pca$var
$coord
                  Dim.1       Dim.2       Dim.3
piso         -0.2390693  0.86046275  0.44263091
preciom       0.8360373  0.33344522 -0.22622334
areaconst     0.8797799 -0.04425612  0.00773951
parqueaderos  0.7913655  0.24521109 -0.32348601
banios        0.8775113  0.03536707  0.17583625
habitaciones  0.6599914 -0.39275261  0.59067271

$cor
                  Dim.1       Dim.2       Dim.3
piso         -0.2390693  0.86046275  0.44263091
preciom       0.8360373  0.33344522 -0.22622334
areaconst     0.8797799 -0.04425612  0.00773951
parqueaderos  0.7913655  0.24521109 -0.32348601
banios        0.8775113  0.03536707  0.17583625
habitaciones  0.6599914 -0.39275261  0.59067271

$cos2
                  Dim.1       Dim.2        Dim.3
piso         0.05715414 0.740396139 1.959221e-01
preciom      0.69895845 0.111185715 5.117700e-02
areaconst    0.77401271 0.001958604 5.990001e-05
parqueaderos 0.62625929 0.060128479 1.046432e-01
banios       0.77002616 0.001250830 3.091839e-02
habitaciones 0.43558868 0.154254613 3.488942e-01

$contrib
                 Dim.1      Dim.2        Dim.3
piso          1.700005 69.2493341 26.779406959
preciom      20.789963 10.3992124  6.995073955
areaconst    23.022393  0.1831885  0.008187369
parqueaderos 18.627585  5.6238234 14.303044847
banios       22.903816  0.1169902  4.226047005
habitaciones 12.956239 14.4274513 47.688239865

Para la dimensión 1 se puede observar que las variables que tienen una mayor contribución son areaconst, banios, preciom y parqueaderos por encima del 18% de contribución.

Para la dimensión 2 las variables que tienen una mayor contribución serian piso y habitaciones con un 69% y un 14% respectivamente.

Análisis de Conglomerados

Para el análisis de conglomerados se tomo la base de datos normalizada utilizada para el analisis de componentes principales es decir se tuvieron en cuenta las variables cuantitativas: Piso, Preciom, Areaconst, Parqueaderos, Banios y Habitaciones.

# Conglomerados

# Calculo distancia euclidiana
dist_emp <- dist(datosZ, method = 'euclidean')

# Cluster jerarquico con el método complete
hc_emp <- hclust(dist_emp, method = 'complete')

# Determinamos a dónde pertenece cada observación
cluster_assigments <- cutree(hc_emp, k = 2)

datosZ_df <- as.data.frame(datosZ)

# Asignar los clústeres
assigned_cluster <- datosZ_df %>% mutate(cluster = as.factor(cluster_assigments))

ggplot(assigned_cluster, aes(x = areaconst, y = preciom, color = cluster)) +
  geom_point(size = 1) +
  geom_text(aes(label = cluster), vjust = -.8) +
  theme_classic()

library(cluster)

# Asegúrate de que los clústeres están en un vector
clusters <- as.numeric(assigned_cluster$cluster)

# Calcular la distancia euclidiana usando los datos PCA (sin la columna de clústeres)
distances <- dist(datosZ)

# Calcular el coeficiente de Silhouette
sil <- silhouette(clusters, distances)

# Calcular el coeficiente de Silhouette promedio
sil_avg <- mean(sil[, 3])

# Imprimir el coeficiente de Silhouette promedio
cat("Coeficiente de Silhouette promedio k=2: ", sil_avg)
Coeficiente de Silhouette promedio k=2:  0.5466439

Dentro del análisis realizado se pudieron identificar 2 clusters de datos donde la mayoría de los individuos fueron identificados dentro del cluster 1, los individuos del cluster 2 se encuentran dispersos pero tienen la particularidad de que al tener un área mayor construida su precio no aumenta significativamente y se encuentra dentro de un rango de precios razonable por metro cuadrado construido pudiendo ser un posible target de mercado en la ciudad de Cali.

Análisis de correspondencia

#Analisis de correspondencia

#preparando bases de datos

tablaVivienda_zona = table(datos_limpios$estrato, datos_limpios$zona)
#colnames(tablaVivienda_zona) = c("Zona Centro", "Zona Norte", "Zona Oeste", "Zona Oriente", "Zona Sur") 
tablaVivienda_zona
   
    Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
  3          33        141         19           94      147
  4           3        184         51            2      973
  5           0        482        181            1     1195
  6           0         79        502            0      721
chisq.test(tablaVivienda_zona)

    Pearson's Chi-squared test

data:  tablaVivienda_zona
X-squared = 2172.8, df = 12, p-value < 2.2e-16

Dado el valor extremadamente bajo del p-value, podemos concluir que hay una asociación significativa entre las variables en la tabla de contingencia. Es decir, la distribución de la variable de respuesta (como tipo de vivienda o barrio) varía significativamente según la zona.

resultados_ac <- CA(tablaVivienda_zona)

Al revisar el grafico de correspondencia se puede concluir que:

  1. Las Zonas Oriente y Centro se encuentran agrupadas cerca de la misma región en el gráfico, lo que sugiere que estas zonas tienen un comportamiento similar y mayormente están conformadas por viviendas de estrato 3.

  2. Las Zonas Sur y Norte también se encuentran cercanas, presentar características similares y se encuentran conformadas por viviendas de estrato 4 y 5.

  3. En la Zona Oeste se encuentra conformado por viviendas de estrato 6.

Conclusiones

  • El análisis de componentes principales (PCA) podría simplificar la complejidad de un modelo predictivo o de clasificación que se desee implementar sobre los datos analizados.

  • Dentro de las variables analizadas se encontró que las variables preciom, areaconst, parqueaderos y banios tiene una relación fuerte con el primer componente explicado cerca del 56% de la varianza total de los datos.

  • Los datos analizados pueden agruparse en 2 grupos principales , donde el cluster 2 presentan condiciones interesantes para el mercado como áreas grandes y precios razonables por metro cuadrado.

  • Las viviendas de estrato 6 se encuentran en su mayor parte en la Zona Oeste de la ciudad mientras hacia la Zona Centro y Oriente se encuentran viviendas de clase media.

Recomendaciones

  1. Realizar una segmentación de mercado asociando los perfiles de los clientes de acuerdo al estrato socioeconómico que desean comprar resaltando características claves de cada grupo de viviendas, es decir grandes espacios, zonas exclusivas o bajos precios de las viviendas y zonas accesibles o cercanas.
  2. Priorizar la compra y venta de viviendas caracterizadas como el cluster 2 donde se puede ofertar un área construida considerable a precios por metro cuadrado razonables.