# Cargar librerías
library(paqueteMODELOS)
library(ggplot2)
library(factoextra)
library(cluster)
library(FactoMineR)
library(corrplot)

# Cargar datos
data("vivienda")

# Ver estructura inicial
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")=List of 3
##   ..$ cols   :List of 13
##   .. ..$ id          : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ zona        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ piso        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ estrato     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ preciom     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ areaconst   : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ parqueaderos: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ banios      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ habitaciones: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ tipo        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ barrio      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ longitud    : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ latitud     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   ..$ default: list()
##   .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
##   ..$ delim  : chr ";"
##   ..- attr(*, "class")= chr "col_spec"
##  - attr(*, "problems")=<externalptr>

#Análisis Multivariado del Mercado Inmobiliario Urbano

#Introducción

El mercado inmobiliario urbano es complejo y depende de múltiples variables como área, precio, ubicación y características estructurales. El objetivo es identificar patrones y segmentaciones estratégicas que permitan optimizar decisiones de compra y venta.

#METODOLOGÍA Y RESULTADOS

# Dimensiones
dim(vivienda)
## [1] 8322   13
# Primeras filas
head(vivienda)
## # A tibble: 6 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <chr>   <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1  1147 Zona O… <NA>        3     250        70            1      3            6
## 2  1169 Zona O… <NA>        3     320       120            1      2            3
## 3  1350 Zona O… <NA>        3     350       220            2      2            4
## 4  5992 Zona S… 02          4     400       280            3      5            3
## 5  1212 Zona N… 01          5     260        90            1      2            3
## 6  1724 Zona N… 01          5     240        87            1      3            3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Resumen estadístico
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
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
# Eliminar filas con NA
vivienda <- na.omit(vivienda)

# Verificar nuevamente
colSums(is.na(vivienda))
##           id         zona         piso      estrato      preciom    areaconst 
##            0            0            0            0            0            0 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##            0            0            0            0            0            0 
##      latitud 
##            0
# Seleccionar solo variables numéricas
vivienda_num <- vivienda[, sapply(vivienda, is.numeric)]

# Ver estructura de variables numéricas
str(vivienda_num)
## spc_tbl_ [4,808 × 9] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id          : num [1:4808] 5992 1212 1724 2326 4386 ...
##  $ estrato     : num [1:4808] 4 5 5 4 5 5 5 4 5 6 ...
##  $ preciom     : num [1:4808] 400 260 240 220 310 320 780 625 750 520 ...
##  $ areaconst   : num [1:4808] 280 90 87 52 137 150 380 355 237 98 ...
##  $ parqueaderos: num [1:4808] 3 1 1 2 2 2 2 3 2 2 ...
##  $ banios      : num [1:4808] 5 2 3 2 3 4 3 5 6 2 ...
##  $ habitaciones: num [1:4808] 3 3 3 3 4 6 3 5 6 2 ...
##  $ longitud    : num [1:4808] -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ latitud     : num [1:4808] 3.44 3.46 3.37 3.43 3.38 ...
##  - attr(*, "spec")=List of 3
##   ..$ cols   :List of 13
##   .. ..$ id          : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ zona        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ piso        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ estrato     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ preciom     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ areaconst   : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ parqueaderos: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ banios      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ habitaciones: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ tipo        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ barrio      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ longitud    : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ latitud     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   ..$ default: list()
##   .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
##   ..$ delim  : chr ";"
##   ..- attr(*, "class")= chr "col_spec"
##  - attr(*, "problems")=<externalptr> 
##  - attr(*, "na.action")= 'omit' Named int [1:3514] 1 2 3 11 20 28 29 30 31 32 ...
##   ..- attr(*, "names")= chr [1:3514] "1" "2" "3" "11" ...

#DETECCIÓN DE OUTLIERS (Boxplot)

boxplot(vivienda_num,
        main="Detección de Outliers",
        las=2)

El análisis exploratorio mediante diagramas de caja permitió identificar la presencia de valores atípicos principalmente en las variables precio por metro cuadrado y área construida. Esto es consistente con la naturaleza del mercado inmobiliario, donde existen propiedades de alta gama que generan dispersión significativa. No obstante, estos valores fueron conservados para el análisis al representar variabilidad real del mercado.

#MATRIZ DE CORRELACIÓN

cor_matrix <- cor(vivienda_num)
corrplot(cor_matrix, method="color", tl.cex=0.8)

La matriz de correlación evidencia una fuerte asociación positiva entre precio, área construida, número de baños y parqueaderos, lo que indica multicolinealidad entre variables estructurales. Esta condición justifica la aplicación del Análisis de Componentes Principales como técnica de reducción dimensional.

vivienda_scaled <- scale(vivienda_num)

#Análisis de Componentes Principales (ACP)

Técnica que:

Reduce dimensionalidad

Convierte variables correlacionadas en componentes no correlacionados

Maximiza varianza explicada

Supuestos:

Variables numéricas

#Correlación significativa

Escalamiento cuando están en diferentes unidades

pca <- prcomp(vivienda_scaled, center=TRUE, scale.=TRUE)
summary(pca)
## Importance of components:
##                           PC1    PC2    PC3    PC4     PC5     PC6     PC7
## Standard deviation     1.9707 1.3734 1.0061 0.9701 0.68406 0.58318 0.49619
## Proportion of Variance 0.4315 0.2096 0.1125 0.1046 0.05199 0.03779 0.02736
## Cumulative Proportion  0.4315 0.6411 0.7536 0.8581 0.91014 0.94793 0.97529
##                            PC8     PC9
## Standard deviation     0.42658 0.20104
## Proportion of Variance 0.02022 0.00449
## Cumulative Proportion  0.99551 1.00000

#Scree Plot

fviz_eig(pca,
         addlabels=TRUE,
         barfill="steelblue",
         barcolor="black")
## Warning in geom_bar(stat = "identity", fill = barfill, color = barcolor, :
## Ignoring empty aesthetic: `width`.

El scree plot muestra que los dos primeros componentes explican aproximadamente el 64% de la varianza total, mientras que los cuatro primeros alcanzan cerca del 86%. El punto de inflexión sugiere que los primeros dos o tres componentes capturan la mayor parte de la estructura de los datos.

fviz_pca_biplot(pca,
                repel=TRUE,
                col.var="red",
                col.ind="gray40")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## ℹ The deprecated feature was likely used in the ggpubr package.
##   Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

#MÉTODO DEL CODO

fviz_nbclust(vivienda_scaled, kmeans, method="wss")

El método del codo sugiere que tres clusters constituyen una segmentación adecuada del mercado, ya que a partir de este punto la reducción en la suma de cuadrados intra-cluster disminuye de forma marginal.

set.seed(123)
kmeans_result <- kmeans(vivienda_scaled, centers=3)

fviz_cluster(kmeans_result,
             data=vivienda_scaled,
             ellipse.type="convex",
             palette="jco")

distancia <- dist(vivienda_scaled)
hc <- hclust(distancia, method="ward.D2")

plot(hc, main="Dendrograma Segmentación Jerárquica")

El análisis multivariado permitió identificar una estructura clara en el mercado inmobiliario, donde el primer componente principal está asociado al valor estructural del inmueble, mientras que los componentes siguientes capturan variabilidad espacial y socioeconómica. La aplicación de clustering confirmó la existencia de tres segmentos bien diferenciados, lo que sugiere que el mercado presenta patrones estructurales definidos.

# Crear tabla de contingencia
tabla <- table(vivienda$tipo, vivienda$zona)

# Ejecutar análisis
ca <- CA(tabla, graph=FALSE)

#Conclusiones Clave #El mercado inmobiliario presenta una estructura claramente segmentada

El Análisis de Componentes Principales (PCA) evidenció que el primer componente explica aproximadamente el 43% de la variabilidad total, estando fuertemente asociado con variables como precio, área construida, número de baños y parqueaderos.

Esto indica que el principal factor diferenciador del mercado es el valor estructural del inmueble, es decir, sus características físicas y nivel de equipamiento.

#La ubicación introduce una segunda dimensión estratégica

El segundo componente principal (≈21% de la varianza) mostró relación con variables geográficas (latitud y longitud), lo que confirma que la localización espacial influye significativamente en la segmentación del mercado.

Esto sugiere que el valor de la vivienda no depende únicamente de sus atributos físicos, sino también de su posicionamiento territorial.

#Existen tres segmentos claramente diferenciados

El análisis de clustering (k-means y jerárquico) permitió identificar tres grupos bien definidos:

🔹 Segmento 1: Viviendas de menor tamaño y menor valor.

🔹 Segmento 2: Viviendas intermedias.

🔹 Segmento 3: Viviendas de mayor tamaño, mayor precio y mejores características estructurales.

Esto confirma que el mercado no es homogéneo, sino que presenta patrones estructurales diferenciados.

Alta correlación entre variables estructurales

La matriz de correlación mostró asociación fuerte entre:

Precio

Área construida

Número de baños

Parqueaderos

Esto evidencia que el precio está principalmente impulsado por características físicas del inmueble.

#Recomendaciones Estratégicas para la Empresa Inmobiliaria

#Diseñar estrategias diferenciadas por segmento

Dado que existen tres grupos claramente definidos, la empresa debería:

Implementar estrategias comerciales específicas para cada segmento.

Diferenciar campañas de marketing según nivel socioeconómico y características del inmueble.

#Focalizar inversiones en el segmento premium

El componente principal dominante indica que las características estructurales influyen significativamente en el valor.

#Recomendación:

Priorizar proyectos con mayor área construida y mejores amenidades.

Potenciar atributos como parqueaderos y baños adicionales, ya que incrementan el valor percibido.

#Incorporar análisis geoespacial en la toma de decisiones

La ubicación mostró ser una dimensión relevante.

Se recomienda:

Analizar zonas con mayor valorización potencial.

Desarrollar proyectos estratégicamente ubicados en sectores con alta demanda.

#Optimizar fijación de precios basada en atributos clave

Dado que el precio se relaciona fuertemente con características estructurales, la empresa puede:

Establecer modelos de pricing basados en área y equipamiento.

Evitar subvaloración de propiedades con atributos superiores.

Utilizar segmentación para mejorar eficiencia comercial

La identificación de clusters permite:

Dirigir esfuerzos comerciales de forma más eficiente.

Reducir costos de marketing.

Personalizar la oferta según perfil del cliente objetivo.

#Conclusión

El análisis multivariado permitió identificar que el mercado inmobiliario está estructurado principalmente en función del valor físico del inmueble y su localización geográfica. La segmentación obtenida demuestra la existencia de tres grupos estratégicamente diferenciables, lo que proporciona una base sólida para la toma de decisiones comerciales, de inversión y de fijación de precios.