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.

Introduccion

El siguiente informe tiene como objetivo realizar un análisis estadístico integral de una base de datos de viviendas urbanas en la ciudad de Cali, con el fin de comprender los factores que influyen en el mercado inmobiliario y proporcionar insumos para la toma de decisiones estratégicas en una empresa del sector.

A partir de la información obtenida mediante técnicas de web scraping desde la plataforma OLX y contenida en el paquete paqueteMODELOS, se aplicara la siguiente metodologia.

  1. Carga de librerías y datos:
  2. Limpieza y conversión de tipos; detección de NA y duplicados
  3. Imputación de variables (k-NN)
  4. PCA: reducción de dimensionalidad y análisis de variables que más explican la variabilidad.
  5. Clustering: agrupamiento jerárquico, DBSCAN y HCPC para segmentar el mercado.
  6. ACM: análisis de asociaciones entre variables categóricas (zona, tipo, estrato).
  7. Visualización: mapas de clusters y gráficos biplot para interpretar los resultados.

Variables

A continuacion, comenzaremos con una descripcion de las variables que se trataron.

id → Identificador del inmueble en el dataset.

zona → Sector o región general donde está ubicado el inmueble.

piso → Número de piso en el que se encuentra la propiedad (para apartamentos) en el caso de las casas se toma como la cantidad de pisos que posee.

estrato → Clasificación socioeconómica oficial del inmueble.

preciom → Precio del inmueble expresado en millones de pesos.

areaconst → Área construida del inmueble en metros cuadrados.

parqueaderos → Número de parqueaderos.

banios → Número de baños disponibles en el inmueble.

habitaciones → Número de habitaciones o cuartos.

tipo → Tipo de inmueble (Apartamento - casa).

barrio → Nombre del barrio.

longitud → Coordenada geográfica de longitud donde está el inmueble.

latitud → Coordenada geográfica de latitud donde está el inmueble.

1. Carga de librerías y datos

Se procedio con la respectiva importanción de los datos desde el centromagis, asi como la descarga de las librerias.

# Librerías usadas

library(cli)
library(curl)
## Using libcurl 8.10.1 with Schannel
library(rlang)
library(purrr)
## 
## Adjuntando el paquete: 'purrr'
## The following objects are masked from 'package:rlang':
## 
##     %@%, flatten, flatten_chr, flatten_dbl, flatten_int, flatten_lgl,
##     flatten_raw, invoke, splice
library(Rcpp)

library(VIM)
## Cargando paquete requerido: colorspace
## Cargando paquete requerido: grid
## VIM is ready to use.
## Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues
## 
## Adjuntando el paquete: 'VIM'
## The following object is masked from 'package:datasets':
## 
##     sleep
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(FactoMineR)
## Warning: package 'FactoMineR' was built under R version 4.4.3
library(factoextra)
## Warning: package 'factoextra' was built under R version 4.4.3
## Cargando paquete requerido: ggplot2
## Warning: package 'ggplot2' was built under R version 4.4.3
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(dplyr)
library(tidyverse)
## Warning: package 'tibble' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.4     ✔ tibble    3.3.0
## ✔ readr     2.1.5     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ purrr::%@%()         masks rlang::%@%()
## ✖ dplyr::filter()      masks stats::filter()
## ✖ purrr::flatten()     masks rlang::flatten()
## ✖ purrr::flatten_chr() masks rlang::flatten_chr()
## ✖ purrr::flatten_dbl() masks rlang::flatten_dbl()
## ✖ purrr::flatten_int() masks rlang::flatten_int()
## ✖ purrr::flatten_lgl() masks rlang::flatten_lgl()
## ✖ purrr::flatten_raw() masks rlang::flatten_raw()
## ✖ purrr::invoke()      masks rlang::invoke()
## ✖ dplyr::lag()         masks stats::lag()
## ✖ readr::parse_date()  masks curl::parse_date()
## ✖ purrr::splice()      masks rlang::splice()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(mice)
## Warning: package 'mice' was built under R version 4.4.3
## 
## Adjuntando el paquete: 'mice'
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following objects are masked from 'package:base':
## 
##     cbind, rbind
# Instalacion del paquete: paqueteMODELOS
devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
## WARNING: Rtools is required to build R packages, but is not currently installed.
## 
## Please download and install Rtools 4.4 from https://cran.r-project.org/bin/windows/Rtools/.
## Downloading GitHub repo centromagis/paqueteMODELOS@HEAD
## rlang  (1.1.5  -> 1.1.6) [CRAN]
## purrr  (1.0.2  -> 1.1.0) [CRAN]
## cli    (3.6.3  -> 3.6.5) [CRAN]
## Rcpp   (1.0.14 -> 1.1.0) [CRAN]
## curl   (6.2.0  -> 6.4.0) [CRAN]
## magick (2.8.5  -> 2.8.7) [CRAN]
## Installing 6 packages: rlang, purrr, cli, Rcpp, curl, magick
## Warning: packages 'rlang', 'purrr', 'cli', 'Rcpp', 'curl' are in use and will
## not be installed
## Installing package into 'C:/Users/johan/AppData/Local/R/win-library/4.4'
## (as 'lib' is unspecified)
## Warning in download.file(url, destfile, method, mode = "wb", ...): downloaded
## length 15940658 != reported length 24804281
## Warning in download.file(url, destfile, method, mode = "wb", ...): URL
## 'https://cloud.r-project.org/bin/windows/contrib/4.4/magick_2.8.7.zip': Timeout
## of 60 seconds was reached
## Error in download.file(url, destfile, method, mode = "wb", ...) : 
##   download from 'https://cloud.r-project.org/bin/windows/contrib/4.4/magick_2.8.7.zip' failed
## Warning in download.packages(pkgs, destdir = tmpd, available = available, :
## download of package 'magick' failed
## ── R CMD build ─────────────────────────────────────────────────────────────────
## WARNING: Rtools is required to build R packages, but is not currently installed.
## 
## Please download and install Rtools 4.4 from https://cran.r-project.org/bin/windows/Rtools/.
##          checking for file 'C:\Users\johan\AppData\Local\Temp\RtmpQlLhBD\remotes228055f510b1\Centromagis-paqueteMODELOS-3b06257/DESCRIPTION' ...  ✔  checking for file 'C:\Users\johan\AppData\Local\Temp\RtmpQlLhBD\remotes228055f510b1\Centromagis-paqueteMODELOS-3b06257/DESCRIPTION' (689ms)
##       ─  preparing 'paqueteMODELOS': (7.3s)
##    checking DESCRIPTION meta-information ...  ✔  checking DESCRIPTION meta-information
##       ─  checking for LF line-endings in source and make files and shell scripts (446ms)
##       ─  checking for empty or unneeded directories
##       ─  building 'paqueteMODELOS_0.1.0.tar.gz'
##      
## 
## Installing package into 'C:/Users/johan/AppData/Local/R/win-library/4.4'
## (as 'lib' is unspecified)
library(paqueteMODELOS)
## Cargando paquete requerido: boot
## Cargando paquete requerido: broom
## Warning: package 'broom' was built under R version 4.4.3
## Cargando paquete requerido: GGally
## Warning: package 'GGally' was built under R version 4.4.3
## Cargando paquete requerido: gridExtra
## 
## Adjuntando el paquete: 'gridExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     combine
## 
## Cargando paquete requerido: knitr
## Warning: package 'knitr' was built under R version 4.4.3
## Cargando paquete requerido: summarytools
## Warning: package 'summarytools' was built under R version 4.4.3
## 
## Adjuntando el paquete: 'summarytools'
## 
## The following object is masked from 'package:tibble':
## 
##     view
# Base de datos viviendas
data("vivienda")

# Tipos de variables
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>

La base Vivienda tiene 8.322 observaciones y 13 variables distribuida (id, zona, piso, estrato, preciom, areaconst, parqueaderos, banios, habitaciones, tipo, barrio, longitud, latitud)

2. Limpieza y preparación

# Reorganizo las variables
vivienda$piso=as.numeric(vivienda$piso)
vivienda$estrato=as.factor(vivienda$estrato)

# Verifico que los cambios hayan quedado aplicados
sapply(vivienda, class)
##           id         zona         piso      estrato      preciom    areaconst 
##    "numeric"  "character"    "numeric"     "factor"    "numeric"    "numeric" 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##    "numeric"    "numeric"    "numeric"  "character"  "character"    "numeric" 
##      latitud 
##    "numeric"
# Cantidad de filas y columnas
dim(vivienda)
## [1] 8322   13
# Cantidad de datos faltantes por variable
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
# Filas que desde la columna id, como principal, no contienen datos
vivienda[is.na(vivienda$id), ]
## # A tibble: 3 × 13
##      id zona   piso estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <chr> <dbl> <fct>     <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1    NA <NA>     NA <NA>         NA        NA           NA     NA           NA
## 2    NA <NA>     NA <NA>         NA        NA           NA     NA           NA
## 3    NA <NA>     NA <NA>        330        NA           NA     NA           NA
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Se crea otro base llamada vivi_limpia, donde se excluyen las variables NA del id
vivi_limpia <- vivienda[!is.na(vivienda$id), ]

# Heatmap sobre los datos faltantes
aggr(vivi_limpia, 
     numbers = TRUE, 
     sortVars = TRUE, 
     cex.axis = 0.9, 
     gap = 1, 
     ylab = c("Porcentaje de datos faltantes", "Patrón de faltantes"))

## 
##  Variables sorted by number of missings: 
##      Variable     Count
##          piso 0.3167448
##  parqueaderos 0.1925712
##            id 0.0000000
##          zona 0.0000000
##       estrato 0.0000000
##       preciom 0.0000000
##     areaconst 0.0000000
##        banios 0.0000000
##  habitaciones 0.0000000
##          tipo 0.0000000
##        barrio 0.0000000
##      longitud 0.0000000
##       latitud 0.0000000
# Reviso duplicados
sum(duplicated(vivi_limpia$id))
## [1] 0
###### REVISAR TIPO Y PISOS
table(vivi_limpia$piso, vivi_limpia$tipo)
##     
##      Apartamento Casa
##   1          430  430
##   2          512  938
##   3          573  524
##   4          545   62
##   5          564    3
##   6          243    2
##   7          200    4
##   8          211    0
##   9          146    0
##   10         128    2
##   11          84    0
##   12          83    0
###### PROCEDEMOS A ELIMINAR LAS CASAS QUE TIENEN MAS DE 6 PISOS CON LA FINALIDAD DE NO TENER TANTA DISPERCION EN LOS DATOS

# Se crea otro base llamada vivi_limpia, donde se excluyen las CASAS que tienes mas de 6 pisos del id
vivi_limpia$piso <- ifelse(vivi_limpia$tipo == "Casa" & 
                             vivi_limpia$piso > 6,0,vivi_limpia$piso)


###### REVISAR TIPO Y PISOS
table(vivi_limpia$piso, vivi_limpia$tipo)
##     
##      Apartamento Casa
##   0            0    6
##   1          430  430
##   2          512  938
##   3          573  524
##   4          545   62
##   5          564    3
##   6          243    2
##   7          200    0
##   8          211    0
##   9          146    0
##   10         128    0
##   11          84    0
##   12          83    0
# Explicacopfmef
# No tendremos en cuenta la variable piso

#Revisamos cuantas valores faltantes hay 
colSums(is.na(vivi_limpia))
##           id         zona         piso      estrato      preciom    areaconst 
##            0            0         2635            0            0            0 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##         1602            0            0            0            0            0 
##      latitud 
##            0

Las variables piso y parqueaderos presentan la mayor cantidad de valores faltantes

Realizamos un histograma para observar si existe asimetria o simetria y saber cual tecnica de imputacion usar

hist(vivi_limpia$parqueaderos, main = "Histograma de Parqueaderos", col = "yellow", breaks = 10)

hist(vivi_limpia$piso, main = "Histograma de Pisos", col = "yellow", breaks = 10)

Observamos que los datos no tienen un comportamiento simetrico en parqueaderos, ni pisos

Para el tipo, utilizamos una tabla donde observamos que tenemos mas concentracion en los aptos que en las casas

barplot(table(vivi_limpia$tipo),
        main = "Distribución de la variable 'tipo'",
        col = "red", las = 2)

Al observar los resultados,evidenciamos que se debe imputar diferente a la moda o el promedio, procedemos a utilizar los vecinos cercanos (KNN)

3. Imputación k-NN

Se realizara la imputacion mediante los vecinos mas cercanos (10), por el tipo de variable

Graficamos los datos imputados, con los originales

vivi_limpia_impu <- kNN(vivi_limpia, variable = c("tipo", "parqueaderos"), k = 10)

par(mfrow = c(1,2))
boxplot(vivi_limpia$parqueaderos ~ vivi_limpia$tipo, main = " Antes de imputar")
boxplot(vivi_limpia_impu$parqueaderos ~ vivi_limpia_impu$tipo, main = "Imputacion por KKN")

# Observamos si todavia hay variables NA
colSums(is.na(vivi_limpia_impu))
##               id             zona             piso          estrato 
##                0                0             2635                0 
##          preciom        areaconst     parqueaderos           banios 
##                0                0                0                0 
##     habitaciones             tipo           barrio         longitud 
##                0                0                0                0 
##          latitud         tipo_imp parqueaderos_imp 
##                0                0                0

Después de la imputación no quedan NA en las variables objetivo

4. Preparación para el Modelo PCA

# Seleccionamos las variables numericas para el pca
pca_data <- vivi_limpia_impu[, c(12,13,5,2,10,4,6,7,8,3,9)]

# quitamos los valores NA, reduciendo la base de datos
pca_data <- na.omit(pca_data)

# Observamos si todavia hay variables NA
colSums(is.na(pca_data))
##     longitud      latitud      preciom         zona         tipo      estrato 
##            0            0            0            0            0            0 
##    areaconst parqueaderos       banios         piso habitaciones 
##            0            0            0            0            0
# Escalamos los datos
pca_data_sca <- scale(pca_data[, 7:11])

# Aplicamos el modelo PCA
pca_model <- prcomp(pca_data_sca, center = TRUE, scale. = TRUE)

# Realizamos un summary para ver pesos de los componentes principales
summary(pca_model)
## Importance of components:
##                           PC1    PC2    PC3     PC4     PC5
## Standard deviation     1.6524 0.9961 0.8252 0.56029 0.53167
## Proportion of Variance 0.5461 0.1984 0.1362 0.06279 0.05653
## Cumulative Proportion  0.5461 0.7445 0.8807 0.94347 1.00000

Graficamos las dimensiones y la varianza

fviz_eig(pca_model, addlabels = TRUE)

observaremos las primeras 2 dimensiones, las cuales aportan mas del 70% la explicacion de la variablidad de los datos

fviz_pca_var(pca_model,
             col.var = "contrib",
             gradient.cols = c("red",  "black"),
             repel = TRUE)

Observamos en un plano las dos dimensiones y vemos cuales son las que mas aportan

mediante un grafico de visalizacion analizaremos cuales son las caracteristicas que aportan a la compra de casa o apartamento en cali

fviz_pca_biplot(
  pca_model,
  repel = TRUE,
  habillage = pca_data$tipo,
  col.var = "black",
  gradient.cols = c("pink", "red"))

Contribución de las variables al primer componente

fviz_contrib(pca_model, choice = "var", axes = 1, top = 10)

En el primer componente, el area construida, numero de baños, habitaciones, parqueaderos explican la mayor variabilidad del conjunto de los datos

Al segundo componente

fviz_contrib(pca_model, choice = "var", axes = 2, top = 10)

En el segundo componente el piso (piso en el cual esta ubicado el apto) y (el numero de pisos que tiene la casa) es el que explica la variacion en el segundo componente

PC1 explica ~54.61% de la varianza y PC2 ~19.84% (las dos primeras suman ~74.45%).

PC1 está fuertemente cargado por: area construida, número de baños, habitaciones y parqueaderos.

PC2 está asociado principalmente al piso (ubicación vertical del inmueble).

5. Análisis de conglomerados (clustering)

#distancia euclidiana
comp_1=pca_data_sca[, 1:5]

dist_comp_1 <- dist(comp_1, method = "euclidian")

# Cluster jerarquico
hc_comp_1 <- hclust(dist_comp_1, method = "complete")

# Realizamos el dendograma, ya que usamos el cluster jerarquico, en 4 clusters
plot(hc_comp_1, cex = 0.6, main = "Dendograma", las=1, 
     ylab= "Distancia euclidiana", xlab= "Grupos")
rect.hclust(hc_comp_1, k = 3, border =2:5)

# Asignamos los grupos
asig_cluster <- cutree(hc_comp_1, k=3)

# Asignamos los clusteres
pca_data$cluster=asig_cluster


# Utilizamos la longitud y la latitud para realizar el mapa y ver la discriminacion
ggplot(pca_data, aes(x = longitud, y = latitud, color = as.factor(cluster))) +
  geom_point(size = 3) +
  scale_color_manual(values = c("black", "blue", "green", "brown")) +
  labs(color = "Cluster") +
  theme_minimal()

# OTRO METODO CON HCPC
res.ACP <- PCA(pca_data_sca, graph = FALSE)

clus.cali <- HCPC(res.ACP, nb.clust = -1)

plot(clus.cali)

# mapa de cluster
fviz_cluster(
  clus.cali,                     
  data = pca_data_sca,            
  geom = "point",                 
  show.clust.cent = TRUE,         
  palette = c("yellow","blue","red"),                
  ggtheme = theme_minimal(),  
  main = "Mapa de clusters"
  )

# Ahora caracterizamos los clusteres
pca1 <- pca_data
pca1$zona=as.factor(pca1$zona)

# Miramos la caracterizacion de los grupos, dependiendo las variables
boxplot(pca1$preciom ~ pca1$cluster)

boxplot(pca1$parqueaderos ~ pca1$cluster)

boxplot(pca1$habitaciones ~ pca1$cluster)

boxplot(pca1$piso ~ pca1$cluster)

boxplot(pca1$banios ~ pca1$cluster)

El clustering jerárquico mostró una segmentación interpretable en 3 clusters.

Cluster 1: al validar el cluster de precio, se Presentan precios significativamente más bajos frente a los demas grupos evidenciando muchos valores atípicos.

Cluster 2: Se videncian Propiedades con un menor numero de parqueaderos, concentrándose en varios espacios (1,2), con pocos valores atípicos, donde muestra que pueden ser inmuebles mejor construidas o ubicadas en zonas de Cali, donde el parqueo no es prioridad o simplemente no tiene.

Cluster 3: existen viviendas con menores habitaciones, o tienen una particularidad que suelen tener entre 1 y dos habitaciones. al interpretarse, puede tratarse de lugarse muchos mas pequeños.

Cluster 4: Existen viviendas en pisos muchos mas bajos en una escala entre 1 -5. al existir dicha variablidad podemos asociarlo a que pueden atraer familias mucho mas numerosas, personas mayores o con unas caracterisicas especiales.

Cluster 5: Podemos analizar que existen viviendas con menos bañados contruidos, entre 2 y 3.Podemos asociarlo a viviendas mas pequeñas, apartamentos en zonas urbanas, donde el espaccio es mas pequeño.

6. Análisis de Correspondencia Múltiple (ACM)

# Tomamos las variables categoricas
pca2 <- pca_data[,c(4,5,6)]

# Procedemos a renombrar   las categorias de las variables, para tener un mejor entendimiento de estas en las graficas
pca2$estrato <- recode(pca2$estrato,
                 "3" = "Estrato 3",
                 "4" = "Estrato 4",
                 "5" = "Estrato 5",
                 "6" = "Estrato 6")

# Revisamos si hay datos en blanco (no hay, este nuevo dataset, viene de una base de datos ya limpia)
md.pattern(pca2, rotate.name = TRUE)
##  /\     /\
## {  `---'  }
## {  O   O  }
## ==>  V <==  No need for mice. This data set is completely observed.
##  \  \|/  /
##   `-----'

##      zona tipo estrato  
## 5684    1    1       1 0
##         0    0       0 0
sapply(pca2, class)
##        zona        tipo     estrato 
## "character" "character"    "factor"
# Realizamos un modelo de correspondencia multiple, que permita agregar mas de 2 variables
acm_model <- MCA(pca2, graph = FALSE)
summary(acm_model)
## 
## Call:
## MCA(X = pca2, graph = FALSE) 
## 
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6   Dim.7
## Variance               0.550   0.454   0.389   0.334   0.326   0.267   0.202
## % of var.             20.620  17.010  14.605  12.512  12.233  10.002   7.571
## Cumulative % of var.  20.620  37.630  52.234  64.746  76.979  86.981  94.552
##                        Dim.8
## Variance               0.145
## % of var.              5.448
## Cumulative % of var. 100.000
## 
## Individuals (the 10 first)
##                 Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## 4            |  0.119  0.000  0.008 | -0.657  0.017  0.245 |  0.932  0.039
## 5            | -0.021  0.000  0.000 | -0.365  0.005  0.062 | -1.345  0.082
## 6            | -0.021  0.000  0.000 | -0.365  0.005  0.062 | -1.345  0.082
## 7            | -0.028  0.000  0.000 | -0.533  0.011  0.117 | -0.592  0.016
## 8            | -0.021  0.000  0.000 | -0.365  0.005  0.062 | -1.345  0.082
## 9            |  0.421  0.006  0.068 | -0.422  0.007  0.068 | -0.886  0.035
## 10           |  0.421  0.006  0.068 | -0.422  0.007  0.068 | -0.886  0.035
## 11           |  0.169  0.001  0.009 |  0.421  0.007  0.058 | -0.271  0.003
## 12           |  0.414  0.005  0.059 | -0.589  0.013  0.121 | -0.132  0.001
## 13           |  0.421  0.006  0.068 | -0.422  0.007  0.068 | -0.886  0.035
##                cos2  
## 4             0.493 |
## 5             0.846 |
## 6             0.846 |
## 7             0.144 |
## 8             0.846 |
## 9             0.302 |
## 10            0.302 |
## 11            0.024 |
## 12            0.006 |
## 13            0.302 |
## 
## Categories (the 10 first)
##                  Dim.1     ctr    cos2  v.test     Dim.2     ctr    cos2
## Zona Centro  |   3.154   7.323   0.122  26.361 |   1.149   1.177   0.016
## Zona Norte   |   0.472   2.707   0.056  17.814 |  -0.296   1.292   0.022
## Zona Oeste   |  -1.018   8.899   0.171 -31.175 |   1.808  34.006   0.539
## Zona Oriente |   3.371  25.214   0.432  49.533 |   1.453   5.677   0.080
## Zona Sur     |  -0.184   1.250   0.053 -17.315 |  -0.433   8.391   0.292
## Apartamento  |  -0.340   4.583   0.219 -35.253 |   0.040   0.076   0.003
## Casa         |   0.643   8.674   0.219  35.253 |  -0.075   0.143   0.003
## Estrato 3    |   1.858  32.310   0.630  59.853 |   0.633   4.547   0.073
## Estrato 4    |  -0.195   0.615   0.014  -8.870 |  -0.819  13.158   0.244
## Estrato 5    |  -0.179   0.671   0.017  -9.798 |  -0.480   5.841   0.121
##               v.test     Dim.3     ctr    cos2  v.test  
## Zona Centro    9.599 |   1.202   1.501   0.018  10.045 |
## Zona Norte   -11.180 |  -1.510  39.099   0.571 -56.980 |
## Zona Oeste    55.350 |  -0.210   0.536   0.007  -6.441 |
## Zona Oriente  21.347 |   0.651   1.329   0.016   9.569 |
## Zona Sur     -40.750 |   0.482  12.136   0.363  45.412 |
## Apartamento    4.114 |  -0.297   4.955   0.167 -30.848 |
## Casa          -4.114 |   0.563   9.377   0.167  30.848 |
## Estrato 3     20.393 |  -0.288   1.097   0.015  -9.281 |
## Estrato 4    -37.252 |   0.700  11.176   0.178  31.812 |
## Estrato 5    -26.249 |  -0.711  14.923   0.266 -38.879 |
## 
## Categorical variables (eta2)
##                Dim.1 Dim.2 Dim.3  
## zona         | 0.749 0.688 0.638 |
## tipo         | 0.219 0.003 0.167 |
## estrato      | 0.682 0.670 0.363 |
# Graficamos
fviz_mca_var(acm_model, 
             repel = TRUE, 
             ggtheme = theme_minimal())

Se Procedio a renombrar las categorias de las variables, para tener un mejor entendimiento de estas en las graficas

Eigenvalues: Dim1 = 20.62% var., Dim2 = 17.01%, Dim3 = 14.61% (cumulativa hasta Dim2 ~37.63% — en ACM se interpretan diferente que en PCA).

zona y estrato muestran alta asociación con las dimensiones (eta2 altos); tipo tiene menor aporte relativo.

Observaciones indicativas: Zona Oriente y Zona Centro presentan cargas positivas en la Dim1; Estrato 3 se asocia fuertemente a una de las dimensiones.

7. Conclusiones

  1. Las variables más relevantes para explicar la variabilidad del mercado en la muestra son: área construida, número de baños, habitaciones y parqueaderos (PC1).

  2. El piso es un factor secundario pero relevante (PC2).

  3. Existe una segmentación clara en 3 grupos (clusters) que muestran diferencias en precio, tamaño y ubicación: esto permite diseñar estrategias comerciales segmentadas.

  4. El ACM confirma patrones socio-espaciales: ciertos estratos se concentran en zonas específicas (información útil para valuación y mercadeo).