1. Problema

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.

Fuente: Actividad 1 - Modelos estadísticos para la toma de decisiones.

2. Retos

El reto principal consiste en realizar un análisis integral y multidimensional de la base de datos para obtener una comprensión del mercado inmobiliario urbano. Se requiere aplicar diversas técnicas de análisis de datos, incluyendo:

2.1. Análisis de Componentes Principales

  • Entregar a la empresa B&C un informe detallado en relación al análisis descriptivo del mercado inmobiliario en la ciudad de Cali, a partir de la base de datos remitida por el cliente.

2.2. Análisis de Conglomerados

  • Entregar a la empresa B&C un informe detallado en relación al análisis descriptivo del mercado inmobiliario en la ciudad de Cali, a partir de la base de datos remitida por el cliente.

2.3. Análisis de Correspondencia

  • Entregar a la empresa B&C un informe detallado en relación al análisis descriptivo del mercado inmobiliario en la ciudad de Cali, a partir de la base de datos remitida por el cliente.

2.4. Visualización de resultados

  • Entregar a la empresa B&C un informe detallado en relación al análisis descriptivo del mercado inmobiliario en la ciudad de Cali, a partir de la base de datos remitida por el cliente.

El informe final debe incluir análisis detallados de los resultados obtenidos, las conclusiones clave y las recomendaciones específicas para guiar las decisiones estratégicas de la empresa inmobiliaria. Se espera que este análisis de datos proporcione ventajas competitivas en el mercado, optimizando la inversión y maximizando los beneficios en un entorno altamente competitivo y en constante cambio

Fuente: Actividad 1 - Modelos estadísticos para la toma de decisiones.

3. Informe

Teniendo en cuenta la base de datos suministrada por su empresa, se procede a presentar los diferentes análisis realizados a la misma, para poder brindarle a su empresa recomendaciones y conclusiones que le permitan establecer estrategias para su proceso de compra y venta de inmuebles.

  • Inicialmente, procedemos presentando la información de la base de datos:
#Carga de librerías a utilizar en el desarrollo del informe
# devtools::install_github("dgonxalex80/paqueteMODELOS", force = TRUE)
suppressMessages(library(paqueteMET))
suppressMessages(library(knitr))
suppressMessages(library(janitor))
suppressMessages(library(ggplot2))
knitr::opts_chunk$set(echo = TRUE)
suppressMessages(library(tidyverse)) # Manejo de datos y gráficos
suppressMessages(library(factoextra)) # Visualización de PCA y clustering
suppressMessages(library(cluster)) # Análisis de clustering
suppressMessages(library(FactoMineR)) # Análisis de correspondencia
suppressMessages(library(leaflet)) # Mapas interactivos

# Resumen de los datos
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
# Estructura de los datos
head(vivienda, 20)
## # A tibble: 20 × 13
##       id zona   piso  estrato preciom areaconst parqueaderos banios habitaciones
##    <dbl> <chr>  <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
##  1  1147 Zona … <NA>        3     250        70            1      3            6
##  2  1169 Zona … <NA>        3     320       120            1      2            3
##  3  1350 Zona … <NA>        3     350       220            2      2            4
##  4  5992 Zona … 02          4     400       280            3      5            3
##  5  1212 Zona … 01          5     260        90            1      2            3
##  6  1724 Zona … 01          5     240        87            1      3            3
##  7  2326 Zona … 01          4     220        52            2      2            3
##  8  4386 Zona … 01          5     310       137            2      3            4
##  9  1209 Zona … 02          5     320       150            2      4            6
## 10  1592 Zona … 02          5     780       380            2      3            3
## 11  4057 Zona … 02          6     750       445           NA      7            6
## 12  4460 Zona … 02          4     625       355            3      5            5
## 13  6081 Zona … 02          5     750       237            2      6            6
## 14  7497 Zona … 02          6     520        98            2      2            2
## 15  7824 Zona … 02          4     600       160            1      4            5
## 16  7987 Zona … 02          5     420       200            4      4            5
## 17  3495 Zona … 03          5     490       118            2      4            4
## 18  5424 Zona … 03          4     320       108            2      3            3
## 19  6271 Zona … 03          5     385       103            2      2            3
## 20  6857 Zona … 03          3     100        49           NA      1            2
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
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>

De la información anterior, le presentamos el siguiente resumen de la base de datos:

  • La base de datos contiene información sobre 8,322 propiedades.
  • Hay una variabilidad de estrato que va desde el 3 hasta el 6, lo que sugiere una diversidad de nivel socioeconómico de las propiedades a evaluar.
  • Los precios varían significativamente, con un mínimo de 58 y un máximo de 1,999 (Unidades: Millones de pesos colombianos). La mediana del precio es de 330, sugiriendo que la mitad de las propiedades están por debajo de este valor, mientras que la otra mitad está por encima.
  • El promedio de precio es de 433.9 millones de pesos, lo cual es mayor que la mediana.
  • El área de construcción varía desde 30 hasta 1,745 metros cuadrados, con una mediana de 123. Esto indica que hay propiedades de diversos tamaños en el mercado.
  • Las propiedades cuentan con entre 1 y 10 parqueaderos, aunque el promedio y la mediana cercanos a 2 indican que la mayoría de las propiedades tienen 1 o 2 espacios de estacionamiento. Sin embargo, hay una cantidad considerable de datos faltantes en esta variable (1605 NA’s).
  • Hay desde propiedades sin baños hasta propiedades con 10, pero la mayoría tiene entre 2 y 4 baños.
  • Similar a los baños, las propiedades tienen de 1 a 10 habitaciones, con una mediana y moda de 3, lo que indica que la mayoría de las propiedades tienen 3 habitaciones.
  • Las variables Zona, Tipo y Barrio, son variables categóricas, ya que se presentan como carácteres. Se recomienda una conversión a numéricos para su correcto análisis.
  • Muchos registros tienen valores faltantes (NA’s), que deberán ser tratados adecuadamente, ya sea mediante imputación o eliminación, antes de realizar cualquier análisis posterior.

Este resumen estadístico le puede ayudar a su empresa a comprender mejor la distribución de las características de las propiedades disponibles en la base de datos.

  • Una vez presentado el resumen estadístico de la información suministrada, procedemos con le etapa de tratamiento de información, asociada con procesos de imputación de datos faltantes, para poder obtener resultados lógicos y asertivos para su empresa:

Como primera medida, identificamos cual es la cantidad de datos faltantes que tiene la base de datos:

na_count <- vivienda %>% 
  summarise(across(everything(), ~sum(is.na(.))))

# Ver los resultados
print(na_count)
## # A tibble: 1 × 13
##      id  zona  piso estrato preciom areaconst parqueaderos banios habitaciones
##   <int> <int> <int>   <int>   <int>     <int>        <int>  <int>        <int>
## 1     3     3  2638       3       2         3         1605      3            3
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>

Se encuentra que para la variable ID, existen 3 registros con información clasificada como NA, al igual, que el valor que adquieren todos los registros de esa fila, ya que también se registraron como NA.

Por lo tanto, se procede a eliminar estos 3 registros, ya que no aportan al análisis de la información. Una vez realizada la eliminación, se presenta nuevamente la cantidad de información con datos clasificados como NA, para confirmar la ejecución exitosa del proceso:

vivienda <- vivienda %>% 
  filter(!is.na(id))

na_count <- vivienda %>% 
  summarise(across(everything(), ~sum(is.na(.))))

# Ver los resultados
print(na_count)
## # A tibble: 1 × 13
##      id  zona  piso estrato preciom areaconst parqueaderos banios habitaciones
##   <int> <int> <int>   <int>   <int>     <int>        <int>  <int>        <int>
## 1     0     0  2635       0       0         0         1602      0            0
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>

Para la continuidad del proceso de imputación de datos, se establecen los siguientes criterios, para poder realizar la conversión de los datos clasificados como NA:

  • Para la variable Piso:
    • Si la variable Tipo es una Casa, será considerado como casa de 1 Piso.
    • Si la variable Tipo es apartamento, será considerado como apartamento de 1 Piso.
  • Para la variable Parqueaderos:
    • Se imputan los registros NA como 0, bajo la asunción que la falta de información indica la ausencia de parqueaderos

Es importante mencionar, que bajo ningún motivo se considera la eliminación de estos datos faltantes, dado que por el alto volumen de estos registros, se perdería información valiosa para nuestro análisis:

vivienda <- vivienda %>%
  mutate(piso = ifelse(is.na(piso) , 1, piso))

vivienda <- vivienda %>%
  mutate(parqueaderos = replace_na(parqueaderos, 0))

na_count <- vivienda %>% 
summarise(across(everything(), ~sum(is.na(.))))

vivienda2 <- vivienda 
# Ver los resultados
print(na_count) 
## # A tibble: 1 × 13
##      id  zona  piso estrato preciom areaconst parqueaderos banios habitaciones
##   <int> <int> <int>   <int>   <int>     <int>        <int>  <int>        <int>
## 1     0     0     0       0       0         0            0      0            0
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>

Una vez procesada la información y confirmada la no existencia de datos faltantes, se presentan gráficos de frecuencia por variable para observar los rangos entre los que se encuentran los registros de cada variable:

# Seleccionar las variables deseadas de la base de datos vivienda2
selected_vars <- vivienda[, c("preciom", "zona", "piso", "estrato", "parqueaderos", "banios", "habitaciones", "tipo")]

# Crear gráficos de frecuencia para cada variable
library(ggplot2)

# Gráfico de frecuencia para la variable 'zona'
ggplot(selected_vars, aes(x = zona)) +
  geom_bar(fill = "#DDB4EB") +
  labs(title = "Frecuencia de Zonas", x = "Zona", y = "Frecuencia")

# Gráfico de frecuencia para la variable 'piso'
ggplot(selected_vars, aes(x = piso)) +
  geom_bar(fill = "#FFD4A5") +
  labs(title = "Frecuencia de Pisos", x = "Piso", y = "Frecuencia")

# Gráfico de frecuencia para la variable 'estrato'
ggplot(selected_vars, aes(x = estrato)) +
  geom_bar(fill = "#41894A") +
  labs(title = "Frecuencia de Estratos", x = "Estrato", y = "Frecuencia")

# Gráfico de frecuencia para la variable 'parqueaderos'
ggplot(selected_vars, aes(x = parqueaderos)) +
  geom_bar(fill = "#FFD4A5") +
  labs(title = "Frecuencia de Parqueaderos", x = "Parqueaderos", y = "Frecuencia")

# Gráfico de frecuencia para la variable 'banios'
ggplot(selected_vars, aes(x = banios)) +
  geom_bar(fill = "#41894A") +
  labs(title = "Frecuencia de Baños", x = "Baños", y = "Frecuencia")

# Gráfico de frecuencia para la variable 'habitaciones'
ggplot(selected_vars, aes(x = habitaciones)) +
  geom_bar(fill = "#DDB4EB") +
  labs(title = "Frecuencia de Habitaciones", x = "Habitaciones", y = "Frecuencia")

# Gráfico de frecuencia para la variable 'tipo'
ggplot(selected_vars, aes(x = tipo)) +
  geom_bar(fill = "#FFD4A5") +
  labs(title = "Frecuencia de Tipo de Vivienda", x = "Tipo de Vivienda", y = "Frecuencia")

Una vez presentandos las datos de frecuencia de las variables que hacen parte de la base de datos, se procede con el cumplimiento de los siguientes análisis:

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

Para la ejecución del análisis PCA, previamente se realiza el siguiente procesamiento a la base de datos:

  • Las variables ID, latitud y longitud son eliminadas, ya que se considera que no influyen en la variación de precios y oferta del mercado
  • La variable Barrio, se elimina, dado que las conclusiones se darán por zonas. Lo anterior, teniendo en cuenta que el registro de la información de barrrios es muy amplia y presenta errores de redacción.
  • La variable zona, es categórica, por lo tanto, sus registros se convierten a numéricos por medio de la siguiente asignación:
    Zona Oriente:1
    Zona Sur: 2
    Zona Norte: 3
    Zona Oeste: 4
    Zona Centro: 5
  • La variable tipo, es categórica, por lo tanto, sus registros se convierten a numéricos por medio de la siguiente asignación:
    Casa:1
    Apartamento: 2
     library(dplyr)

# Preparar los datos
vivienda_pca <- vivienda %>%
  select(-id, -barrio, -longitud, -latitud) %>% # Eliminar variables no deseadas
  mutate(
    zona = case_when(
      zona == "Zona Oriente" ~ 1,
      zona == "Zona Sur" ~ 2,
      zona == "Zona Norte" ~ 3,
      zona == "Zona Oeste" ~ 4,
      zona == "Zona Centro" ~ 5,
      TRUE ~ NA_real_  # Asegura que cualquier valor no especificado se trate como NA
    ),
    tipo = case_when(
      tipo == "Casa" ~ 1,
      tipo == "Apartamento" ~ 2,
      TRUE ~ NA_real_
    )
  ) %>%
  mutate(
    zona = as.numeric(zona),
    tipo = as.numeric(tipo)
  )

vivienda_pca <- vivienda_pca %>%
  mutate(piso = as.numeric(piso))

head(vivienda_pca, 20)
## # A tibble: 20 × 9
##     zona  piso estrato preciom areaconst parqueaderos banios habitaciones  tipo
##    <dbl> <dbl>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl> <dbl>
##  1     1     1       3     250        70            1      3            6     1
##  2     1     1       3     320       120            1      2            3     1
##  3     1     1       3     350       220            2      2            4     1
##  4     2     2       4     400       280            3      5            3     1
##  5     3     1       5     260        90            1      2            3     2
##  6     3     1       5     240        87            1      3            3     2
##  7     3     1       4     220        52            2      2            3     2
##  8     3     1       5     310       137            2      3            4     2
##  9     3     2       5     320       150            2      4            6     1
## 10     3     2       5     780       380            2      3            3     1
## 11     3     2       6     750       445            0      7            6     1
## 12     3     2       4     625       355            3      5            5     1
## 13     3     2       5     750       237            2      6            6     1
## 14     3     2       6     520        98            2      2            2     2
## 15     3     2       4     600       160            1      4            5     1
## 16     3     2       5     420       200            4      4            5     1
## 17     3     3       5     490       118            2      4            4     1
## 18     3     3       4     320       108            2      3            3     2
## 19     3     3       5     385       103            2      2            3     2
## 20     3     3       3     100        49            0      1            2     2

A continuación, se realiza el análisis PCA, con la base de datos procesada en la sección anterior:

library(factoextra)
# Ejecutamos PCA 
res.pca <- PCA(vivienda_pca,graph = FALSE )
res.pca$eig
##        eigenvalue percentage of variance cumulative percentage of variance
## comp 1  3.6750890              40.834323                          40.83432
## comp 2  1.8850107              20.944564                          61.77889
## comp 3  0.9370840              10.412044                          72.19093
## comp 4  0.8311650               9.235167                          81.42610
## comp 5  0.4806685               5.340761                          86.76686
## comp 6  0.4287903               4.764336                          91.53119
## comp 7  0.3391565               3.768406                          95.29960
## comp 8  0.2403053               2.670059                          97.96966
## comp 9  0.1827308               2.030342                         100.00000
fviz_eig(res.pca, addlabels = TRUE, ylim = c(0, 50))

  • Reducción de dimensionalidad PCA

Al visualizar la varianza por cada componente, se establece, que teniendo en cuenta que los 4 primeros componentes explican un total del 80% aproximadamente de la varianza, se realizará la reducción de dimensionalidad a estos componentes (4).

Notas generales para lectura del gráfico:

  • Las flechas muestran cómo cada variable influye en los dos componentes principales. La dirección y longitud de las flechas indican la correlación con cada componente y la importancia relativa de la variable, respectivamente.
  • Las variables que están más correlacionadas con el primer componente principal tendrán flechas que apuntan hacia la derecha o izquierda a lo largo del eje horizontal (Componente 1).
  • Las variables que están más correlacionadas con el segundo componente principal tendrán flechas que apuntan hacia arriba o abajo a lo largo del eje vertical (Componente 2).
# Realizar PCA especificando el número de componentes principales a retener
pca_res <- PCA(vivienda_pca, scale.unit = TRUE, ncp = 4, graph = FALSE)

loadings <- pca_res$var$coord[, 1:4]

# Ordenar las variables por su contribución al primer componente principal
loadings_sorted_comp1 <- sort(loadings[, 1], decreasing = TRUE)


# Visualización de las variables para los primeros cuatro componentes principales
fviz_pca_var(pca_res, axes = c(1, 2)) # Para los componentes 1 y 2

Todas las variables numéricas que se incluyeron en el análisis PCA estarán representadas por flechas en el gráfico. Esto permite interpretar las relaciones entre las variables, en el contexto de los componentes principales seleccionados (Para este caso, 1 y 2)

  • Conclusiones:
    • El Dim1 (Primer Componente Principal) que explica el 40.8% de la varianza, parece estar fuertemente influenciado por variables como areaconst (área de construcción), banios (número de baños), y habitaciones (número de habitaciones). Esto sugiere que el tamaño y las características de una propiedad son factores significativos en la variación de los datos.
    • El Dim2 (Segundo Componente Principal), que explica el 20.9% de la varianza, parece ser influenciado por estrato, zona y en menor medida por parqueaderos. Esto puede indicar que la ubicación socioeconómica y la disponibilidad de estacionamiento son también diferenciadores importantes en el mercado.
    • Dado que las variables relacionadas con el tamaño de la propiedad (área construida, número de habitaciones y baños) están alineadas con el primer componente principal, una estrategia de mercado podría enfocarse en destacar estas características en las propiedades más grandes para atraer a compradores interesados en propiedades espaciosas.
    • La empresa inmobiliaria podría considerar estrategias de segmentación de mercado basadas en la ubicación y el estrato, ajustando el marketing y lOS precios de venta según estos factores.
    • Su empresa debería tener en cuenta para valoraciones de futuros proyectos, que variables como tamaño y las comodidades internas (número de baños y habitaciones) son importantes para los compradores y pueden ser un punto de venta clave.
# Repite con axes = c(3, 4) para los componentes 3 y 4 si es necesario
fviz_pca_var(pca_res, axes = c(3, 4)) # Para los componentes 3 y 4

Todas las variables numéricas que se incluyeron en el análisis PCA estarán representadas por flechas en el gráfico. Esto permite interpretar las relaciones entre las variables, en el contexto de los componentes principales seleccionados (Para este caso, 3 y 4)

  • Conclusiones:
    • Los componentes 3 y 4 explican un porcentaje menor de la varianza (10.4% y 9.2% respectivamente) en comparación con los componentes 1 y 2. Por lo tanto, las conclusiones que se puedan obtener del análisis de la gráfica, tienen menor nivel de influencia en la consolidación de estrategias para definir procesos de marketing, establecimiento de precios, entre otros. Es decir, que para este segmento no le presenteramos propuestas para la consolidación de sus estrategias. Lo anterior, dado que los componentes 3 y 4 son menos explicativos en términos de varianza, y por ende, las estrategias derivadas de ellos recomendamos sean consideradas en un segundo informe, para establecer estrategias complementarias.


  • Análisis Conglomerados : Entregar a la empresa B&C un informe detallado en relación al análisis descriptivo del mercado inmobiliario en la ciudad de Cali, a partir de la base de datos remitida por el cliente.

Para esta sección, y teniendo en cuenta que a partir de la redacción de la literatura, se recomienda hacer procesos de análisis de cluster sin incluir datos categóricos, se utilizara la base de datos procesada para el análisis PCA, que se presenta a continuación y que tiene en cuenta la siguiente convención:

  • La variable zona, es categórica, por lo tanto, sus registros se convierten a numéricos por medio de la siguiente asignación:
    Zona Oriente:1
    Zona Sur: 2
    Zona Norte: 3
    Zona Oeste: 4
    Zona Centro: 5
  • La variable tipo, es categórica, por lo tanto, sus registros se convierten a numéricos por medio de la siguiente asignación:
    Casa:1
    Apartamento: 2

El análisis de clustering es considerado útil para la identificación de agrupaciones dentro de los datos, y a su vez, ayudar a descubrir patrones o estructuras subyacentes. Para nuestro caso, cuya información corresponde a una base de datos inmobiliarios, podría indicar grupos de propiedades con características similares, como ubicación, tamaño y precio, lo que podría ser implementado para fortalecer la toma de decisiones en el marketing o la estrategia de precios.

suppressMessages(library(stats))
suppressMessages(library(ggplot2))
suppressMessages(library(dplyr))
suppressMessages(library(tidyr))

# Paso 1: Determinar el número óptimo de clústeres
# Utilizamos el método del codo para encontrar un número adecuado de clústeres
set.seed(123) # Establecer una semilla para reproducibilidad
wss <- sapply(1:10, function(k){kmeans(vivienda_pca, k, nstart = 10)$tot.withinss})
elbow_plot <- data.frame(k = 1:10, wss = wss)
ggplot(elbow_plot, aes(x = k, y = wss)) + geom_line() + geom_point() +
  ggtitle("Método del codo para elegir k") +
  xlab("Número de clústeres (k)") +
  ylab("Suma de cuadrados dentro del grupo (WSS)")

A partir del gráfico, se identifica que el número óptimo de cluster, corresponde a 4, basado en el método del “codo”

# Aquí seleccionamos 'k' basado en el método del codo
k <- 4 # Asumiendo que el método del codo sugiere 4 clústeres
kmeans_result <- kmeans(vivienda_pca, centers = k, nstart = 10)
# Paso 3: Anexar la clasificación de clústeres al dataframe original
vivienda_pca$cluster <- kmeans_result$cluster
# Paso 4: Analizar los centroides de cada clúster
centroids_df <- as.data.frame(kmeans_result$centers)

# Puedes examinar los centroides para ver qué caracteriza a cada clúster
print(centroids_df)
##       zona     piso  estrato   preciom areaconst parqueaderos   banios
## 1 2.835271 2.810078 5.798450 1389.8740 444.22180    3.4864341 5.189922
## 2 2.625987 2.721564 4.851106  436.4115 198.16067    1.6477093 3.521722
## 3 2.733163 2.664109 5.531969  780.4893 306.57116    2.4509804 4.538789
## 4 2.356515 3.075403 4.095412  212.7789  88.99817    0.8494388 2.187408
##   habitaciones     tipo
## 1     4.315891 1.383721
## 2     4.032780 1.456161
## 3     4.255754 1.415175
## 4     3.065642 1.795510

A partir del análisis de cluster, se establecen los siguientes análisis:

Clúster 1:

Registra los valores más altos en estrato, preciom (precio), areaconst (área construida), parqueaderos, banios (baños) y habitaciones. Esto quiere decir, que las propiedades en este clúster son probablemente de lujo, ubicadas en estratos altos, con precios elevados, más espacio, y mayor número de comodidades. La estrategia puede enfocarse en el marketing de alta gama y la venta a compradores adinerados.

Clúster 2:

Registra valores moderados en todas las variables, sugiriendo propiedades de tamaño medio, con características y precios promedio.Esto quiere decir, que este clúster puede apuntar al segmento medio del mercado, con propiedades que ofrecen un balance entre costo y comodidades. Las estrategias de marketing pueden ser más generalizadas, apuntando a familias de clase media.

Clúster 3:

Registra valores intermedios entre el clúster 1 y 2 en términos de preciom, areaconst, parqueaderos, banios y habitaciones, pero con un estrato alto, similar al clúster 1.Esto quiere decir, que las propiedades aquí pueden ser de un nivel alto, pero no tanto como las del clúster 1. Por lo tanto, la estrategia podría centrarse en compradores que buscan lujo a un precio ligeramente más accesible.

Clúster 4:

Registra valores más bajos en preciom, areaconst, parqueaderos, banios y habitaciones, con un estrato más bajo que los clústeres 1 y 3. Esto quiere decir, que estas propiedades pueden ser más asequibles y más pequeñas, dirigidas a compradores por primera vez o a aquellos con presupuestos más limitados. Por lo tanto, las estrategias podrían incluir promociones o facilidades de financiamiento.

  • Análisis de Correspondencia: Entregar a la empresa B&C un informe detallado con relación al análisis descriptivo del mercado inmobiliario en la ciudad de Cali, a partir de la base de datos remitida por el cliente.

A continuación, se realiza un análisis descriptivo de correspondencia, únicamente de las variables categóricas, tal como registra la literatura:

library(gridExtra)
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine
# Seleccionar solo las variables cualitativas de la base de datos
categorical_data <- vivienda2[, c("zona", "tipo", "barrio")]

Zona <- categorical_data$zona
Tipo <- categorical_data$tipo
Barrio <- categorical_data$barrio

Datos <- cbind(categorical_data,Zona,Tipo,Barrio)
Datos[,1:3] <- NULL

# Gráficos individuales
F1 <- ggplot(Datos, aes(x = Zona)) + geom_bar(fill = "#DDB4EB") +
      theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
F2 <- ggplot(Datos, aes(x = Tipo)) + geom_bar(fill = "#FFD4A5") +
      theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))


# Combinar los gráficos en uno solo
combined_plot <- grid.arrange(F1, F2, nrow = 1)

# Mostrar el gráfico combinado
print(combined_plot)
## TableGrob (1 x 2) "arrange": 2 grobs
##   z     cells    name           grob
## 1 1 (1-1,1-1) arrange gtable[layout]
## 2 2 (1-1,2-2) arrange gtable[layout]

Para esta sección no se presenta el gráfica de frecuencia de los barrios dado que tienen un registro individual bastante alto, y no permite una visualuzación clara y práctica.

uni.mca <- MCA(Datos, graph = FALSE)
print(uni.mca)
## **Results of the Multiple Correspondence Analysis (MCA)**
## The analysis was performed on 8319 individuals, described by 3 variables
## *The results are available in the following objects:
## 
##    name              description                       
## 1  "$eig"            "eigenvalues"                     
## 2  "$var"            "results for the variables"       
## 3  "$var$coord"      "coord. of the categories"        
## 4  "$var$cos2"       "cos2 for the categories"         
## 5  "$var$contrib"    "contributions of the categories" 
## 6  "$var$v.test"     "v-test for the categories"       
## 7  "$var$eta2"       "coord. of variables"             
## 8  "$ind"            "results for the individuals"     
## 9  "$ind$coord"      "coord. for the individuals"      
## 10 "$ind$cos2"       "cos2 for the individuals"        
## 11 "$ind$contrib"    "contributions of the individuals"
## 12 "$call"           "intermediate results"            
## 13 "$call$marge.col" "weights of columns"              
## 14 "$call$marge.li"  "weights of rows"

Eigenvalues / Varianzas

library(pander)
eigenval <- get_eigenvalue(uni.mca)
pander(head(eigenval))
  eigenvalue variance.percent cumulative.variance.percent
Dim.1 0.711 0.4848 0.4848
Dim.2 0.6602 0.4501 0.9349
Dim.3 0.6508 0.4438 1.379
Dim.4 0.6232 0.4249 1.804
Dim.5 0.4442 0.3029 2.106
Dim.6 0.3333 0.2273 2.334
  fviz_mca_var(uni.mca, choice = "mca.cor",
               repel = TRUE,
               ggtheme = theme_grey())

Conclusiones:

  • La variable “Zona” está más alejada del origen (el punto de cruce entre Dim1 y Dim2), lo que sugiere que puede tener una contribución más significativa a la variabilidad en los datos en comparación con “Barrio” y “Tipo”. Esto podría indicar que la ‘Zona’ en la que se encuentra una propiedad es un factor distintivo.

  • El hecho de que “Barrio” y “Zona” estén en la misma dirección pero a diferentes distancias del origen en Dim1 sugiere que estas dos categorías pueden estar correlacionadas, pero con diferentes grados de influencia. Es posible que ‘Barrio’ sea una subdivisión dentro de una ‘Zona’ más amplia y que ambos compartan una relación, pero ‘Zona’ podría ser una clasificación más amplia que afecta a los datos.

  • La primera dimensión (Dim1) explica el 0.5% de la inercia (variabilidad), lo cual es bastante bajo. Esto podría sugerir que la variabilidad global de las categorías no está muy bien representada en estas dos primeras dimensiones y que puede ser necesario explorar dimensiones adicionales para comprender mejor la estructura de los datos.

  • Potencial para la segmentación del mercado: Si ‘Zona’ y ‘Barrio’ son indicativos de diferentes segmentos del mercado inmobiliario, el análisis sugiere que las políticas o estrategias de marketing podrían necesitar ser adaptadas específicamente para cada ‘Zona’ debido a su mayor distinción en los datos.

  • Por lo tanto, es importante que su empresa combine la información brindada con su conocimiento detallado del mercado local, tendencias de precios, preferencias de los compradores, y otros factores cualitativos que podrían no estar representados en el análisis cualitativo presentado.

fviz_ellipses(uni.mca, 1:3, 
              geom = "point")

El gráfico presentado muestra un mapa de factores de un Análisis de Correspondencia Múltiple (MCA). Este tipo de análisis es útil para entender y visualizar las relaciones entre diferentes niveles de variables categóricas. Este mapa, presenta tres paneles que representan las categorías de las variables “Barrio”, “Tipo” y “Zona”.

  • Distribución de categorías: Las categorías de las variables están dispersas a lo largo de las dos primeras dimensiones principales. La primera dimensión (Dim1) parece distinguir entre diferentes tipos de propiedades y zonas, mientras que la segunda dimensión (Dim2) podría representar variaciones dentro de los barrios.

  • Existen diferencias claras entre las zonas (Norte, Sur, Este, Oeste, Centro), lo que implica que la ubicación es un factor relevante en el mercado inmobiliario.

  • Los barrios se distribuyen a lo largo de ambas dimensiones, lo que indica diferencias sutiles y tal vez características únicas asociadas con cada barrio.

  • Recomendamos utilizar las diferencias que se registran entre las categorías de “Tipo” y “Zona” para desarrollar estrategias de segmentación de mercado. Por ejemplo, marketing diferenciado para apartamentos versus casas, y promociones adaptadas a las preferencias de cada zona.

  • A su vez, le recomendamos invertir en propiedades en barrios que se destacan en las zonas con alta demanda, identificados por su distancia desde el centro en la Dim1 y Dim2.

  • Le recomendamos desarrollar productos inmobiliarios que se alineen con las características únicas de barrios específicos, aprovechando su posición en el espacio del MCA para destacar y potenciar sus atributos.

  • Ajuste los precios de acuerdo con la demanda y las características de las propiedades identificadas en las diferentes zonas y tipos de vivienda.

  • Para los barrios que están cerca de las fronteras entre zonas, recomendamos que considera estrategias de publicidad que destaquen la accesibilidad y las ventajas de la ubicación.

Es importante mencionar, que el MCA es una herramienta exploratoria. Por lo tanto, las estrategias sugeridas se deben validar con un análisis más profundo, como un estudio de mercado o una evaluación financiera, y combinarlas con su conocimiento en el área y la experiencia en el sector inmobiliario.