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.
El conjunto de datos está conformado por 8.322 registros y 13 variables. Los tipos de dato de cada variable (numérico y carácter) están de forma correcta, por lo cual, no es necesario hacer ajustes en este punto:
library(dplyr)
library(paqueteMODELOS)
data("vivienda")
attr(vivienda, "spec") <- NULL
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(*, "problems")=<externalptr>
En la revisión se identifica que las filas: 8320, 8321 y 8322 tienen el mayor número de datos faltantes, prácticamente no tienen información, por lo cual, se procede a eliminarlas y quedando con 8319 observaciones:
#Se revisa el mayor número de datos faltantes por fila
na_por_fila <- rowSums(is.na(vivienda))
# Filtrar filas con los 2 mayores NA
top2 <- sort(unique(na_por_fila), decreasing = TRUE)[1:2]
# Obtener índices de fila que cumplen la condición
filas <- which(na_por_fila %in% top2)
# Mostrar data frame con índice de fila y NA
result <- data.frame(
fila = filas,
Datos_faltantes = na_por_fila[filas]
)
print(result)
## fila Datos_faltantes
## 1 8320 13
## 2 8321 13
## 3 8322 12
#Se eliminan las 3 filas con más datos faltantes
vivienda1 <- vivienda[-c(8320, 8321, 8322), ]
Continuando con la revisión, se verifica el número de filas duplicadas en la base de datos, lo que arroja que no hay ninguna:
#Revisión de si hay filas duplicadas en la base de datos
duplicados <-duplicated(vivienda1)
sum(duplicados)
## [1] 0
Posteriormente a ello, se procede a revisar el número de datos faltantes por cada una de las columnas, en donde piso tiene 2635 datos faltantes, es decir, casi el 32%, por lo cual, se toma la decisión de eliminar está columna.De igual manera, se procede a eliminar “id” puesto que es un indicador y no brinda información significativa en el análisis, quedando con 11 variables.
# Datos faltantes por columnas
cat("=== Conteo de NA por columna ===")
## === Conteo de NA por columna ===
colSums(is.na(vivienda1))
## 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
vivienda2 <- vivienda1[, !(names(vivienda1) %in% c("piso", "id"))]
cat("=== Relación de variables ===")
## === Relación de variables ===
names(vivienda2)
## [1] "zona" "estrato" "preciom" "areaconst" "parqueaderos"
## [6] "banios" "habitaciones" "tipo" "barrio" "longitud"
## [11] "latitud"
En cuanto a la variable parqueaderos presenta 1602 datos faltantes, se observa que sus valores registrados van de 1 a 10, sin incluir el valor 0. Esto indica que en la base de datos no se representa explícitamente las viviendas que no cuentan con parqueadero.
table(vivienda$parqueaderos, useNA = "always")
##
## 1 2 3 4 5 6 7 8 9 10 <NA>
## 3155 2475 520 384 68 68 18 17 4 8 1605
Con el fin de analizar estos datos faltantes, se comparó su comportamiento por estrato socioeconómico, identificando que a medida que disminuía el estrato, aumentaba la proporción de valores de NA. Este patrón sugiriere que los datos faltantes no son aleatorios, sino una característica estructural, posiblemente asociada a viviendas sin parqueadero.
cat("=== Proporción de valores faltantes (NA) en la variable parqueaderos por cada estrato===")
## === Proporción de valores faltantes (NA) en la variable parqueaderos por cada estrato===
prop.table(table(vivienda2$estrato, is.na(vivienda2$parqueaderos)), 1)
##
## FALSE TRUE
## 3 0.47075017 0.52924983
## 4 0.77078441 0.22921559
## 5 0.91709091 0.08290909
## 6 0.94111726 0.05888274
Por otro lado, se evidencia que las viviendas con NA en
parqueaderos tienen un precio promedio mucho menor, lo que podría
sugerir que NA se asocia a 0 parqueaderos. Por lo cual, se procede a
reemplazar NA de parqueaderos con cero:
cat("=== Precio promedio de viviendas con y sin valores NA ===")
## === Precio promedio de viviendas con y sin valores NA ===
aggregate(preciom ~ is.na(parqueaderos), data = vivienda2, mean)
## is.na(parqueaderos) preciom
## 1 FALSE 468.8806
## 2 TRUE 287.2534
# Se reemplazan los NA en parquederos con cero
vivienda2$parqueaderos[is.na(vivienda2$parqueaderos)] <-0
sum(is.na(vivienda2$parqueaderos))
## [1] 0
De igual manera, se revisan los estadísticos descriptivos generales de las columnas numéricas, identificándose que los valores de parqueaderos, baños y habitaciones oscilan entre 0 y 10; el precio presenta un mínimo de 58 y un máximo de 1999; y el área construida varía entre 30 y 1745:
#
vivienda_num <- vivienda2[, c("preciom", "areaconst", "parqueaderos", "banios","habitaciones","longitud", "latitud" )]
summary(vivienda_num)
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 0.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 : 1.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.482 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
## habitaciones longitud latitud
## Min. : 0.000 Min. :-76.59 Min. :3.333
## 1st Qu.: 3.000 1st Qu.:-76.54 1st Qu.:3.381
## Median : 3.000 Median :-76.53 Median :3.416
## Mean : 3.605 Mean :-76.53 Mean :3.418
## 3rd Qu.: 4.000 3rd Qu.:-76.52 3rd Qu.:3.452
## Max. :10.000 Max. :-76.46 Max. :3.498
Continuando la revisión de la base de datos, se realizan los boxplot para ver si hay valores atípicos en las variables, estos gráficos se hacen de acuerdo a la escala de las variables, donde visualmente se observa que hay valores atípicos en precio, variable construida, parqueadero, baños, habitaciones y longitud:
library(dplyr)
par(mfrow = c(2, 2), # 2 filas, 2 columnas
mar = c(5, 5, 4, 2)) # Margenes: abajo, izquierda, arriba, derecha
# Boxplot 1
boxplot(vivienda2$preciom, vivienda2$areaconst,
main = "Boxplot Precio y Área",
las = 2,
col = c("lightgreen", "lightblue"),
names = c("Precio", "Área"))
# Boxplot 2
boxplot(vivienda2$parqueaderos, vivienda2$banios, vivienda2$habitaciones,
main = "Boxplot parqueaderos, baños y habitaciones",
las = 2,
col = c("lightgreen", "lightblue", "pink"),
names = c("Parqueaderos", "baños", "Habitaciones"))
# Boxplot 3
boxplot(vivienda2$latitud,
main = "Boxplot latitud",
las = 2,
col = "lightgreen",
names = "latitud")
# Boxplot 4
boxplot(vivienda2$longitud,
main = "Boxplot longitud",
las = 2,
col = "lightgreen",
names = "longitud")
# Restaurar el layout original (opcional)
par(mfrow = c(1,1))
Por lo tanto, se procede a cuantificar la cantidad de valores atípicos utilizando el método del Rango Intercuartílico (IQR). Los resultados indican que las variables con mayor número de outliers son habitaciones y parqueaderos. Sin embargo, estos valores no corresponden a errores de digitación, sino que reflejan características reales de las viviendas en el conjunto de datos. Por esta razón, se decide conservar los outliers, ya que representan información válida y relevante para el análisis:
Identificar_outliers <- function(x){
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
lim_inf <- Q1 - 1.5 * IQR
lim_sup <- Q3 + 1.5 * IQR
sum(x < lim_inf | x > lim_sup, na.rm = TRUE)
}
# Seleccionar variables numéricas
df_num <- vivienda2[, sapply(vivienda2, is.numeric)]
# Contar outliers por variable
cantidad_outliers <- sapply(df_num, Identificar_outliers)
# Convertir a data frame
resultado <- data.frame(
Variable = names(cantidad_outliers),
Cantidad_outliers = unname(cantidad_outliers)
)
resultado
## Variable Cantidad_outliers
## 1 estrato 0
## 2 preciom 552
## 3 areaconst 382
## 4 parqueaderos 567
## 5 banios 72
## 6 habitaciones 888
## 7 longitud 130
## 8 latitud 0
Luego de tener el dataset preparado se procede a realizar el Análisis de Componentes Principales, con el objetivo de reducir la dimensionalidad de los datos y encontrar un conjunto de nuevas variables que están correlacionadas entre si que serían una combinación lineal de las variables originales, conservando la mayor cantidad de información posible. Para lo cual, se realizó estandarización de las variables para evitar que las variables que tiene una escala con valores más grandes afecten las estimaciones realizadas:
#Se realiza estandarización de las variables
viviendaZ = scale(vivienda_num)
head(viviendaZ)
## preciom areaconst parqueaderos banios habitaciones longitud
## [1,] -0.5595498 -0.7339949 -0.3875522 -0.07793773 1.6406840 0.9728466
## [2,] -0.3465670 -0.3842568 -0.3875522 -0.77811479 -0.4147626 0.9331875
## [3,] -0.2552886 0.3152194 0.4168506 -0.77811479 0.2703863 0.7607566
## [4,] -0.1031580 0.7349051 1.2212534 1.32241640 -0.4147626 -0.6549016
## [5,] -0.5291236 -0.5940997 -0.3875522 -0.77811479 -0.4147626 0.8682385
## [6,] -0.5899759 -0.6150839 -0.3875522 -0.07793773 -0.4147626 0.6670691
## latitud
## [1,] 0.3793708
## [2,] 0.3763219
## [3,] 0.4225243
## [4,] 0.4070454
## [5,] 0.9678065
## [6,] -1.1242009
Se realiza el análisis de componentes principales (PCA) sobre las variables estandarizadas. En el cual, se puede visualizar que el primer componente las variables como precio, area construida y baños tienen los valores más altos positivos, por lo que este componente puede representar principalmente tamaño y precio de la vivienda. El segundo componente tiene valores más altos negativos las habitaciones, longitud y latitud indicando que el segundo componente captura principalmente la ubicación y distribución interna de la vivienda:
library(factoextra)
res.pca <-prcomp(viviendaZ)
res.pca
## Standard deviations (1, .., p=7):
## [1] 1.8067342 1.1252417 0.9188270 0.8295052 0.6566798 0.5604122 0.4380988
##
## Rotation (n x k) = (7 x 7):
## PC1 PC2 PC3 PC4 PC5
## preciom 0.4741774 0.09617394 0.287168897 0.17310778 0.34939650
## areaconst 0.4613911 -0.19959771 0.006433265 0.06377186 0.56169950
## parqueaderos 0.4068390 0.18423239 0.306267301 0.41870469 -0.65905516
## banios 0.4809583 -0.13472729 -0.139804434 -0.07173004 -0.10813788
## habitaciones 0.3213990 -0.48301986 -0.479202683 -0.34358756 -0.32630173
## longitud -0.2233140 -0.56691656 -0.175497597 0.76080997 0.04357837
## latitud -0.1107647 -0.58661379 0.737369026 -0.29769751 -0.08942232
## PC6 PC7
## preciom -0.2782719 -0.67376625
## areaconst 0.5251295 0.38974794
## parqueaderos 0.2996944 0.08518622
## banios -0.6995614 0.47408580
## habitaciones 0.2258623 -0.39776910
## longitud -0.1236654 -0.04373866
## latitud -0.0359722 0.04458941
En la elección del número de componentes principales se evaluó el aporte de cada uno. Se encontró que el primer componente principal (CP1) explica el 46.6% de la variabilidad de la base de datos, mientras que el segundo y el tercero explican el 18.1% y el 12.1%, respectivamente. Al considerar los tres primeros componentes (CP1, CP2 y CP3), se captura aproximadamente el 76.8% de la variabilidad total, lo que indica que gran parte de la información puede resumirse mediante una combinación lineal de estas tres variables principales. Por ello, se seleccionan tres componentes como suficientes para representar la estructura de los datos:
fviz_eig(res.pca, addlabels = TRUE)
Al visualizar las variables en el plano de los componentes principales se identifica que:
Las variables precio, baños, área construida y parqueaderos tienen flechas largas y apuntan hacia la derecha en Dim1, lo que indica que están fuertemente correlacionadas con el primer componente, y las tres primeras tiene color más oscuro mostrando su alta contribución al componente 1. Además, como están agrupadas a la derecha, sugiriendo que crecen juntas.
Las variables latitud y longitud apuntan en dirección opuesta y con menor tamaño, mostrando que aportan más al segundo componente y que su relación con las primeras variables es negativa o débil. Además, están tienen color más claro, indicando menor contribución general. Asimismo, apuntan hacia la izquierda e inferior, lo que indica que estas variables geográficas están correlacionadas entre sí, pero tienen correlación negativa o independiente con las variables de infraestructura.
En síntesis, el gráfico indica que las variables relacionadas con el tamaño y características de la vivienda contribuyen principalmente al primer componente, mientras que las variables geográficas (latitud y longitud) se agrupan en el segundo componente. Esto sugiere que el primer componente captura principalmente la variabilidad estructural y funcional de las viviendas, mientras que el segundo componente representa información geográfica.
fviz_pca_var(res.pca,
col.var = "contrib", # Color by contributions to the PC
gradient.cols = c("#FF7F00", "#034D94"),
repel = TRUE # Avoid text overlapping
)
Se usa el coseno cuadrado (cos2) para medir qué tan bien representada está una variable en cada componente principal. Las variables como precio, área construida y baños tienen altos valores de cos2 en el primer componente, lo que sugiere que este componente captura principalmente la variabilidad de estas variables. Las variables geográficas como latitud y longitud se representan mejor en los componentes dos y tres, indicando que estos componentes contienen información espacial. Asimismo, se identifica que de cada variable se encuentran los valores más altos ubicados en estos tres primeros componentes, lo que se asume que representan bien las variables:
var_cos2 <- get_pca_var(res.pca)$cos2
var_cos2
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## preciom 0.73395626 0.01171134 0.0696213281 0.020619180 0.0526434612
## areaconst 0.69490734 0.05044321 0.0000349406 0.002798314 0.1360552801
## parqueaderos 0.54029850 0.04297577 0.0791897128 0.120629593 0.1873056418
## banios 0.75509796 0.02298279 0.0165009671 0.003540303 0.0050426988
## habitaciones 0.33719224 0.29540757 0.1938679357 0.081229366 0.0459141010
## longitud 0.16278720 0.40693958 0.0260021856 0.398281933 0.0008189348
## latitud 0.04004894 0.43570864 0.4590260002 0.060980167 0.0034482532
## Dim.6 Dim.7
## preciom 0.0243194502 0.0871289856
## areaconst 0.0866059980 0.0291549176
## parqueaderos 0.0282080091 0.0013927812
## banios 0.1536974747 0.0431378050
## habitaciones 0.0160214846 0.0303673048
## longitud 0.0048029845 0.0003671767
## latitud 0.0004063956 0.0003815993
A continuación se calculó la contribución total de cada variable
a los primeros tres componentes principales, donde se ve que variables
como latitud (0.93), habitaciones (0.83), precio (0.82) y baños (0.79)
están muy bien representadas por los primeros tres componentes. Por otro
lado, las variables longitud (0.60) y parqueaderos (0.66) tienen una
representación algo menor en este espacio reducido, es decir, aportan
algo más de información que no queda capturada en estos tres
componentes:
var_cos2_total <- rowSums(var_cos2[, 1:3])
var_cos2_total
## preciom areaconst parqueaderos banios habitaciones longitud
## 0.8152889 0.7453855 0.6624640 0.7945817 0.8264677 0.5957290
## latitud
## 0.9347836
Se utilizó el método del codo basado en la suma de cuadrados intra-grupo (WSS) para elegir el número de grupos. En la gráfica se observa que al aumentar el número de grupos, la variación dentro de ellos disminuye considerablemente hasta llegar a 3. A partir de ese punto, la mejora es mucho menor. Por esta razón, se decidió trabajar con 3 clusters, ya que permiten una buena diferenciación de los datos sin complicar innecesariamente el análisis:
library(factoextra)
fviz_nbclust(viviendaZ, kmeans, method = "wss")
Se calculan los centroides de cada cluster y se identifca
que:
El cluster 1 tiene valores positivos altos en precio, área construida, parqueaderos, baños y habitaciones, lo que se puede interpretar que son viviendas más grandes, más costosas y con más comodidades que el promedio.
El cluster 2 Tiene valores negativos en precio y tamaño, pero valores altos en longitud y latitud, lo que sugiere viviendas más pequeñas y económicas, pero ubicadas en una zona específica (diferente al promedio).
El cluster 3 tiene valores ligeramente negativos en casi todas las variables, lo que indica que son viviendas un poco por debajo del promedio en tamaño, precio y características, pero más dispersas geográficamente.
set.seed(123) # reproducibilidad
kmeans_res <- kmeans(viviendaZ, centers = 3, nstart = 25)
# Centroides de cada cluster
kmeans_res$centers
## preciom areaconst parqueaderos banios habitaciones longitud
## 1 1.2358662 1.1812912 0.9472176 1.2363181 0.8555493 -0.4758825
## 2 -0.5374904 -0.3622694 -0.4904653 -0.5006034 -0.1056406 1.1850129
## 3 -0.3601452 -0.4114865 -0.2411784 -0.3767384 -0.3675931 -0.2954811
## latitud
## 1 -0.1375796
## 2 1.1246329
## 3 -0.4325755
En cuanto al tamaño de los conglomerados, el tercer grupo concentra la mayor cantidad de viviendas (4314), mientras que el primero y el segundo agrupan 2090 y 1915 viviendas, respectivamente. Esto indica que la mayoría de las viviendas del conjunto de datos comparten características similares a las del cluster 3, mientras que los otros dos grupos representan segmentos más específicos del mercado:
# Tamaño de cada cluster
kmeans_res$size
## [1] 2090 1915 4314
fviz_cluster(kmeans_res, data = viviendaZ)
La representación gráfica de los conglomerados muestra que el cluster rojo está claramente diferenciado (hacia la derecha), lo que indica un perfil de vivienda distinto. Los clusters verde y azul están más cercanos entre sí, pero siguen siendo diferenciables.La separación visual respalda que 3 clusters es una buena elección, ya que se observan grupos relativamente definidos. En sinstesis, hay una separación clara entre los tres grupos. El cluster 1 se distingue notablemente del resto, mientras que los clusters 2 y 3 presentan mayor cercanía entre sí, aunque mantienen diferencias que justifican su clasificación independiente.
Ahora pasamos de un análisis de las variables númericas a estudiar la relación entre las variables categóricas para lo cual, se construye entonces una tabla cruzada con las variables involucradas en el análisis :
Zona : Centro, Norte, Oeste, Oriente, Sur Estrato : 3,4,5,6
En la tabla se puede ver que la Zona Oeste presenta una alta concentración en estrato 6, mientras que la Zona Centro y la Zona Oriente se concentran principalmente en estrato 3. Por su parte, la Zona Sur y la Zona Norte presentan mayor presencia en estratos 4 y 5. Estos patrones sugieren la existencia de una asociación entre la zona y el estrato:
library(FactoMineR)
tabla <- table(vivienda2$zona, vivienda2$estrato)
colnames(tabla) <- c("Estrato3", "Estrato4", "Estrato5", "Estrato6" )
tabla
##
## Estrato3 Estrato4 Estrato5 Estrato6
## Zona Centro 105 14 4 1
## Zona Norte 572 407 769 172
## Zona Oeste 54 84 290 770
## Zona Oriente 340 8 2 1
## Zona Sur 382 1616 1685 1043
Se procede a realizar la prueba Chi-cuadrado para saber si zona y estrato están relacionados:
Hipótesis nula (H0): zona y estrato son independientes (no hay relación)
El resultado indica que se rechaza la hipótesis de independencia de las variables, indicando grado tipo de relación entre ellas. Existe una asociación significativa entre la zona y el estrato, algunos estratos se concentran más en ciertas zonas, la distribución de los estratos varía según la zona de la ciudad:
chisq.test(tabla)
##
## Pearson's Chi-squared test
##
## data: tabla
## X-squared = 3830.4, df = 12, p-value < 2.2e-16
Continuando con el análisis se procede a realizar el análisis de correspondencia que consiste en estimar las coordenadas para cada uno de los niveles de ambas variables y representarlas en un plano cartesiano, arrojando que la Zona Oeste está fuertemente relacionada con el estrato 6, la zona sur esta asociada a estratos medios (4 y 5), en la Zona Centro y Zona Oriente predomina el estrato 3:
library(FactoMineR)
library(factoextra)
library(gridExtra)
resultados_ac <- CA(tabla)
Por otro lado, en la siguiente tabla se puede vsiualizar que la primera dimensión explicó aproximadamente el 70% de la variabilidad entre las zonas y los estratos, mientras que la segunda dimensión aportó un 28% adicional. En conjunto, estas dos dimensiones capturan cerca del 98% de la información, lo que indica que la representación gráfica basada en ellas refleja muy bien la relación entre ambas variables. Las dimensiones posteriores contribuyen muy poco a la explicación de la variabilidad.:
valores_prop <-resultados_ac$eig ; valores_prop
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.32215213 69.965515 69.96551
## dim 2 0.12745096 27.680002 97.64552
## dim 3 0.01084108 2.354483 100.00000
El análisis de componentes principales (PCA) y clustering permitió identificar tres grupos de viviendas con características diferenciadas en cuanto a precio, tamaño, comodidades y ubicación, capturando el 76.8% de la variabilidad del mercado. Esto evidencia que el mercado urbano no es homogéneo y que existen oportunidades de segmentación estratégica.
El análisis de correspondencia mostró que la ubicación está asociada al estrato socioeconómico, con zonas específicas concentrando estratos altos o bajos.
El Cluster 1 corresponde a viviendas grandes y costosas, el Cluster 2 a viviendas pequeñas y económicas ubicadas en zonas específicas, y el Cluster 3 a viviendas promedio con dispersión geográfica. Esto permite enfocar la gestión de inventario y promoción según el segmento objetivo.
Se recomienda:
Diseñar campañas específicas para cada cluster y zona: Cluster 1 y estrato 6 → promoción de lujo y servicios premium. Cluster 2 y estratos 3-4 → campañas enfocadas en precio y ubicación estratégica. Cluster 3 y estratos 4-5 → resaltar la relación calidad-precio y beneficios de inversión a mediano plazo.
Priorizar inversiones en viviendas premium (Cluster 1) para maximizar retorno
Ajustar decisiones estratégicas con base en datos, monitoreando continuamente el mercado para optimizar la compra, venta y valoración de propiedades.