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.

Retos:

El reto principal consisten 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:

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.

Análisis de Conglomerados: Agrupar las propiedades residenciales en segmentos homogéneos con características similares para entender las dinámicas de las ofertas específicas en diferentes partes de la ciudad y en diferentes estratos socioeconómicos.

Análisis de Correspondencia: Examinar la relación entre las variables categóricas (tipo de vivienda, zona y barrio), para identificar patrones de comportamiento de la oferta en mercado inmobiliario.

Visualización de resultados: Presentar gráficos, mapas y otros recursos visuales para comunicar los hallazgos de manera clara y efectiva a la dirección de la empresa.

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.

Base de datos y variables

#devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
library(paqueteMODELOS)
library(dplyr)
library(summarytools)
library(knitr)
library(corrplot)
library(cluster)
library(factoextra)
library(FactoMineR)
data("vivienda")
cat(capture.output(glimpse(vivienda)), sep = "\n")
## Rows: 8,322
## Columns: 13
## $ id           <dbl> 1147, 1169, 1350, 5992, 1212, 1724, 2326, 4386, 1209, 159…
## $ zona         <chr> "Zona Oriente", "Zona Oriente", "Zona Oriente", "Zona Sur…
## $ piso         <chr> NA, NA, NA, "02", "01", "01", "01", "01", "02", "02", "02…
## $ estrato      <dbl> 3, 3, 3, 4, 5, 5, 4, 5, 5, 5, 6, 4, 5, 6, 4, 5, 5, 4, 5, …
## $ preciom      <dbl> 250, 320, 350, 400, 260, 240, 220, 310, 320, 780, 750, 62…
## $ areaconst    <dbl> 70, 120, 220, 280, 90, 87, 52, 137, 150, 380, 445, 355, 2…
## $ parqueaderos <dbl> 1, 1, 2, 3, 1, 1, 2, 2, 2, 2, NA, 3, 2, 2, 1, 4, 2, 2, 2,…
## $ banios       <dbl> 3, 2, 2, 5, 2, 3, 2, 3, 4, 3, 7, 5, 6, 2, 4, 4, 4, 3, 2, …
## $ habitaciones <dbl> 6, 3, 4, 3, 3, 3, 3, 4, 6, 3, 6, 5, 6, 2, 5, 5, 4, 3, 3, …
## $ tipo         <chr> "Casa", "Casa", "Casa", "Casa", "Apartamento", "Apartamen…
## $ barrio       <chr> "20 de julio", "20 de julio", "20 de julio", "3 de julio"…
## $ longitud     <dbl> -76.51168, -76.51237, -76.51537, -76.54000, -76.51350, -7…
## $ latitud      <dbl> 3.43382, 3.43369, 3.43566, 3.43500, 3.45891, 3.36971, 3.4…
#str(vivienda)

Revisando la clasificación inicial de las variables se evidencia la necesidad de realizar algunos ajustes:

  1. Reclasificar la variable piso como discreta.

  2. Reclasificar la variable estrato como categórica.

vivienda$piso <- as.integer(vivienda$piso)
vivienda$estrato <- as.character(vivienda$estrato)
cat(capture.output(glimpse(vivienda)), sep = "\n")
## Rows: 8,322
## Columns: 13
## $ id           <dbl> 1147, 1169, 1350, 5992, 1212, 1724, 2326, 4386, 1209, 159…
## $ zona         <chr> "Zona Oriente", "Zona Oriente", "Zona Oriente", "Zona Sur…
## $ piso         <int> NA, NA, NA, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, …
## $ estrato      <chr> "3", "3", "3", "4", "5", "5", "4", "5", "5", "5", "6", "4…
## $ preciom      <dbl> 250, 320, 350, 400, 260, 240, 220, 310, 320, 780, 750, 62…
## $ areaconst    <dbl> 70, 120, 220, 280, 90, 87, 52, 137, 150, 380, 445, 355, 2…
## $ parqueaderos <dbl> 1, 1, 2, 3, 1, 1, 2, 2, 2, 2, NA, 3, 2, 2, 1, 4, 2, 2, 2,…
## $ banios       <dbl> 3, 2, 2, 5, 2, 3, 2, 3, 4, 3, 7, 5, 6, 2, 4, 4, 4, 3, 2, …
## $ habitaciones <dbl> 6, 3, 4, 3, 3, 3, 3, 4, 6, 3, 6, 5, 6, 2, 5, 5, 4, 3, 3, …
## $ tipo         <chr> "Casa", "Casa", "Casa", "Casa", "Apartamento", "Apartamen…
## $ barrio       <chr> "20 de julio", "20 de julio", "20 de julio", "3 de julio"…
## $ longitud     <dbl> -76.51168, -76.51237, -76.51537, -76.54000, -76.51350, -7…
## $ latitud      <dbl> 3.43382, 3.43369, 3.43566, 3.43500, 3.45891, 3.36971, 3.4…

Análisis Exploratorio

#dfSummary(vivienda[, c("zona", "piso", "estrato", "preciom", "areaconst", "parqueaderos", #"banios", "habitaciones", "tipo", "barrio")]) %>%
#  print(method = "render")

vivienda %>%
  select(zona, piso, estrato, preciom, areaconst, parqueaderos, banios, habitaciones, tipo, barrio) %>%
  dfSummary() %>%
  print(method = "render")

Data Frame Summary

vivienda

Dimensions: 8322 x 10
Duplicates: 215
No Variable Stats / Values Freqs (% of Valid) Graph Valid Missing
1 zona [character]
1. Zona Centro
2. Zona Norte
3. Zona Oeste
4. Zona Oriente
5. Zona Sur
124(1.5%)
1920(23.1%)
1198(14.4%)
351(4.2%)
4726(56.8%)
8319 (100.0%) 3 (0.0%)
2 piso [integer]
Mean (sd) : 3.8 (2.6)
min ≤ med ≤ max:
1 ≤ 3 ≤ 12
IQR (CV) : 3 (0.7)
12 distinct values 5684 (68.3%) 2638 (31.7%)
3 estrato [character]
1. 3
2. 4
3. 5
4. 6
1453(17.5%)
2129(25.6%)
2750(33.1%)
1987(23.9%)
8319 (100.0%) 3 (0.0%)
4 preciom [numeric]
Mean (sd) : 433.9 (328.6)
min ≤ med ≤ max:
58 ≤ 330 ≤ 1999
IQR (CV) : 320 (0.8)
539 distinct values 8320 (100.0%) 2 (0.0%)
5 areaconst [numeric]
Mean (sd) : 174.9 (143)
min ≤ med ≤ max:
30 ≤ 123 ≤ 1745
IQR (CV) : 149 (0.8)
652 distinct values 8319 (100.0%) 3 (0.0%)
6 parqueaderos [numeric]
Mean (sd) : 1.8 (1.1)
min ≤ med ≤ max:
1 ≤ 2 ≤ 10
IQR (CV) : 1 (0.6)
1:3155(47.0%)
2:2475(36.8%)
3:520(7.7%)
4:384(5.7%)
5:68(1.0%)
6:68(1.0%)
7:18(0.3%)
8:17(0.3%)
9:4(0.1%)
10:8(0.1%)
6717 (80.7%) 1605 (19.3%)
7 banios [numeric]
Mean (sd) : 3.1 (1.4)
min ≤ med ≤ max:
0 ≤ 3 ≤ 10
IQR (CV) : 2 (0.5)
11 distinct values 8319 (100.0%) 3 (0.0%)
8 habitaciones [numeric]
Mean (sd) : 3.6 (1.5)
min ≤ med ≤ max:
0 ≤ 3 ≤ 10
IQR (CV) : 1 (0.4)
11 distinct values 8319 (100.0%) 3 (0.0%)
9 tipo [character]
1. Apartamento
2. Casa
5100(61.3%)
3219(38.7%)
8319 (100.0%) 3 (0.0%)
10 barrio [character]
1. valle del lili
2. ciudad jardín
3. pance
4. la flora
5. santa teresita
6. el caney
7. el ingenio
8. la hacienda
9. acopi
10. los cristales
[ 426 others ]
1008(12.1%)
516(6.2%)
409(4.9%)
366(4.4%)
262(3.1%)
208(2.5%)
202(2.4%)
164(2.0%)
158(1.9%)
154(1.9%)
4872(58.6%)
8319 (100.0%) 3 (0.0%)

Generated by summarytools 1.1.4 (R version 4.4.3)
2025-08-09

# Contar cuántos NA hay por fila
na_por_fila <- apply(is.na(vivienda), 1, sum)

# Crear tabla resumen: cuántas filas tienen cierta cantidad de NA
tabla_na <- as.data.frame(table(na_por_fila))
colnames(tabla_na) <- c("NA_por_fila", "Frecuencia")

# Mostrar como tabla en el informe
kable(tabla_na, caption = "Distribucion de datos faltantes por registro")
Distribucion de datos faltantes por registro
NA_por_fila Frecuencia
0 4808
1 2785
2 726
12 1
13 2

Preparación de los datos

Teniendo en cuenta lo observado en la exploración de los datos, se toma la decisión de realizar los siguientes ajustes:

  1. Eliminar los 3 registros en los que se observa que en dos de ellos hay 13 variables sin datos y en el otro registro hay 12 variables sin datos.

  2. Se considera que el valor de 0 baños es inconsistente para una vivienda, por lo que se imputará el valor mínimo de 1 en esos registros.

  3. Imputar los datos faltantes de las variables categóricas y/o discretas con la moda.

  4. Imputar los datos faltantes de las variables continuas con la mediana.

#Eliminación de los 3 registros con mayor cantidad de datos faltantes
v_sna <- vivienda[na_por_fila < 12, ]
#nrow(v_sna)

#Imputación de los registros con 0 banios
v_sna$banios[v_sna$banios == 0] <- 1
#sort(unique(v_sna$banios))

Tras la ejecución de los pasos 1 y 2 se verifica cuales variables aún tienen datos faltantes

#Imputación de otros datos faltantes
#Inicialmente se verifica cuales variables aún tienen datos faltantes
names(v_sna)[colSums(is.na(v_sna)) > 0]
## [1] "piso"         "parqueaderos"

Se realiza la imputación en las variables piso y parqueaderos a partir de la moda y se verifica que ya no existan columnas con datos faltantes.

#Imputación de datos faltantes en piso y parqueaderos con la moda
# Función para calcular la moda
moda <- function(x) {
  ux <- na.omit(unique(x))
  ux[which.max(tabulate(match(x, ux)))]
}

# Imputar NA con la moda en todas las columnas que tengan datos faltantes
for (col in names(v_sna)[colSums(is.na(v_sna)) > 0]) {
  v_sna[[col]][is.na(v_sna[[col]])] <- moda(v_sna[[col]])
}
names(v_sna)[colSums(is.na(v_sna)) > 0]
## character(0)
#Depuración de variables de estudio
v=v_sna[, (names(v_sna) %in% c("zona", "piso", "estrato", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones", "tipo", "barrio"))]

Análisis Bivariado - Multivariado

Tablas de contingencia

tabla=table(v$zona, v$estrato)
kable(tabla, caption = "Conteo de registros por zona y estrato")
Conteo de registros por zona y estrato
3 4 5 6
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
tabla=table(v$zona, v$piso)
kable(tabla, caption = "Conteo de registros por zona y piso")
Conteo de registros por zona y piso
1 2 3 4 5 6 7 8 9 10 11 12
Zona Centro 33 71 8 5 5 0 0 0 0 0 2 0
Zona Norte 177 1074 189 129 117 33 33 39 32 27 33 37
Zona Oeste 86 514 134 99 84 80 57 43 41 28 20 12
Zona Oriente 74 206 54 8 8 0 0 0 0 1 0 0
Zona Sur 490 2220 712 366 353 132 114 129 73 74 29 34
tabla=table(v$zona, v$tipo)
kable(tabla, caption = "Conteo de registros por zona y tipo")
Conteo de registros por zona y tipo
Apartamento Casa
Zona Centro 24 100
Zona Norte 1198 722
Zona Oeste 1029 169
Zona Oriente 62 289
Zona Sur 2787 1939
tabla=table(v$estrato, v$tipo)
kable(tabla, caption = "Conteo de registros por estrato y tipo")
Conteo de registros por estrato y tipo
Apartamento Casa
3 639 814
4 1404 725
5 1766 984
6 1291 696
tabla=table(v$estrato, v$parqueaderos)
kable(tabla, caption = "Conteo de registros por estrato y parqueaderos")
Conteo de registros por estrato y parqueaderos
1 2 3 4 5 6 7 8 9 10
3 1326 93 19 10 1 3 0 0 0 1
4 1726 317 50 23 4 4 2 0 1 2
5 1434 1030 136 100 27 13 5 3 1 1
6 271 1035 315 251 36 48 11 14 2 4
tabla=table(v$estrato, v$banios)
kable(tabla, caption = "Conteo de registros por estrato y banios")
Conteo de registros por estrato y banios
1 2 3 4 5 6 7 8 9 10
3 374 623 208 135 68 27 4 8 3 3
4 102 1187 444 232 100 40 9 11 2 2
5 48 941 897 492 249 61 39 15 5 3
6 17 195 444 597 473 186 55 14 5 1

Matriz de Correlaciones

#Matriz de correlaciones
v_num=v[, (names(v) %in% c("piso", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones"))]
Mcor <-cor(v_num)
round(Mcor,3)
##                piso preciom areaconst parqueaderos banios habitaciones
## piso          1.000  -0.027    -0.179       -0.043 -0.085       -0.187
## preciom      -0.027   1.000     0.687        0.667  0.675        0.264
## areaconst    -0.179   0.687     1.000        0.531  0.656        0.517
## parqueaderos -0.043   0.667     0.531        1.000  0.538        0.230
## banios       -0.085   0.675     0.656        0.538  1.000        0.587
## habitaciones -0.187   0.264     0.517        0.230  0.587        1.000

Gráfico de Correlaciones

#Gráfico de correlaciones
num_vars <- v[sapply(v, is.numeric)]
cor_matrix <- cor(num_vars, use = "complete.obs")

corrplot(cor_matrix, method = "color", type = "upper", tl.col = "black")

En el análisis multivariado y bivariado se observa:

Análisis de Componentes Principales

Estandarización de variables numéricas

#Estandarización de variables numéricas
v_numz= scale(v_num)
head(v_numz)
##            piso    preciom  areaconst parqueaderos      banios habitaciones
## [1,] -0.5231243 -0.5595498 -0.7339949   -0.6343338 -0.08229776    1.6406840
## [2,] -0.5231243 -0.3465670 -0.3842568   -0.6343338 -0.78738018   -0.4147626
## [3,] -0.5231243 -0.2552886  0.3152194    0.3063120 -0.78738018    0.2703863
## [4,] -0.5231243 -0.1031580  0.7349051    1.2469577  1.32786709   -0.4147626
## [5,] -0.9554580 -0.5291236 -0.5940997   -0.6343338 -0.78738018   -0.4147626
## [6,] -0.9554580 -0.5899759 -0.6150839   -0.6343338 -0.08229776   -0.4147626

Construcción de los componentes principales

pca <- prcomp(v_numz, scale. = TRUE)
summary(pca)  # Varianza explicada
## Importance of components:
##                           PC1    PC2    PC3     PC4     PC5     PC6
## Standard deviation     1.7896 1.0425 0.8936 0.63146 0.56623 0.43895
## Proportion of Variance 0.5338 0.1811 0.1331 0.06646 0.05344 0.03211
## Cumulative Proportion  0.5338 0.7149 0.8480 0.91445 0.96789 1.00000

Elección del número de componentes

fviz_eig(pca, addlabels = TRUE)

En este gráfico se observa que con las tres primeras componentes se explica el 84,8% de la variabilidad de los datos. A partir de la cuarta componente principal el aporte a la variabilidad explicada es menos significativo. Por lo que se eligen las primeras 3 componentes para reducir la dimensionalidad del conjunto de datos.

Plano de los componentes principales

fviz_pca_var(pca,
col.var = "contrib", # Color by contributions to the PC
gradient.cols = c("#FF7F00",  "#034D94"),
repel = TRUE     # Avoid text overlapping
)

En este gráfico se reflejan las relaciones encontradas en el análisis de correlaciones y se identifica el aporte de las variables a los 2 primeros componentes.

Primeras 3 componentes

# Primeras 3 componentes
loadings <- pca$rotation[, 1:3]

for(i in 1:3){
  cat(paste0("PC", i, " = ",
             paste0(round(loadings[, i], 2), names(loadings[, i]), collapse = " + ")),
      "\n")
}
## PC1 = 0.1piso + -0.47preciom + -0.48areaconst + -0.42parqueaderos + -0.49banios + -0.35habitaciones 
## PC2 = -0.8piso + -0.29preciom + 0.06areaconst + -0.3parqueaderos + 0banios + 0.42habitaciones 
## PC3 = 0.57piso + -0.25preciom + 0areaconst + -0.38parqueaderos + 0.22banios + 0.64habitaciones

Análisis de Conglomerados

Teniendo en cuenta que el conjunto de datos tiene datos atípicos, se realizará el análisis calculando la distancia Manhattan.

Identificación del número óptimo de grupos

# Se parte del conjunto de datos v_numz, el cual ya fue estandarizado para el análisis de componentes principales

#Cálculo de distancia Manhattan
dist_man <- dist(v_numz, method = "manhattan")

# Método del Codo con distancia Manhattan
set.seed(123)  # número fijo
fviz_nbclust(v_numz, FUNcluster = function(x, k) {
  pam(dist(x, method = "manhattan"), k, diss = TRUE)
}, k.max = 10, method = "wss") +
  labs(title = "Metodo del Codo - Distancia Manhattan")

set.seed(123)  # número fijo
# Método de la Silueta con distancia Manhattan
fviz_nbclust(v_numz, FUNcluster = function(x, k) {
  pam(dist(x, method = "manhattan"), k, diss = TRUE)
}, k.max = 10, method = "silhouette") +
  labs(title = "Metodo de la Silueta - Distancia Manhattan")

Teniendo en cuenta que el número de grupos no coincide para los métodos del codo y la silueta. Se decide utilizar el método de la silueta con el fin de garantizar grupos bien definidos. Por tanto trabajaremos con k=2.

#Gráfico de grupos resultantes
k_optimo <- 2

# Clustering jerárquico (método Ward, por ejemplo)
hc_man <- hclust(dist_man, method = "ward.D2")

# Cortar el dendrograma en k grupos
grupos <- cutree(hc_man, k = k_optimo)

# Visualizar los grupos en el espacio reducido
fviz_cluster(list(data = v_numz, cluster = grupos),
             geom = "point",
             ellipse.type = "norm", # elipses opcionales
             palette = "jco",       # paleta de colores
             main = paste("Clustering con distancia Manhattan - k =", k_optimo))

A partir del gráfico se observa la concentración de puntos en cada uno de los grupos. El cluster 1 está más disperso hacia la izquierda, mientras que el cluster 2 se concentra más hacia la derecha y hay una zona de traslape que indica que no todos los puntos estan claramente separados.

Para poder interpretar los grupos se consolidarán los datos promedios por grupo en una tabla. Inicialmente se muestran los promedios por cluster y posteriormente la cantidad de datos que agrupa cada uno.

Valores promedio por Cluster

# Crear un data frame combinando datos y grupos
datos_cluster <- v_numz %>%
  as.data.frame() %>%
  mutate(Cluster = factor(grupos))

# Calcular promedios por cluster
resumen <- datos_cluster %>%
  group_by(Cluster) %>%
  summarise(across(everything(), mean), .groups = "drop")

# Mostrar resultados
print(resumen)
## # A tibble: 2 × 7
##   Cluster   piso preciom areaconst parqueaderos banios habitaciones
##   <fct>    <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1 1       -0.294   0.827     0.861        0.676  0.997        0.801
## 2 2        0.167  -0.468    -0.487       -0.383 -0.565       -0.454
# Tamaño de cada cluster
table(grupos)
## grupos
##    1    2 
## 3008 5311

Se observa que en el grupo 1 con 3008 observaciones, se agrupan en general viviendas grandes, más caras, con mayor número de parqueaderos, baños y habitaciones. Las cuales se encuentran predominantemente en pisos bajos.

En el grupo 2 con 5311 observaciones, se agrupan viviendas más pequeñas, más baratas, con menos parqueaderos, baños y habitaciones. Las cuales particularmente se encuentran en pisos más altos.

En general mayor número de parqueaderos y baños está asociado con mayor estrato y a su vez con las zonas norte, sur y oeste, por tanto estas viviendas estarían representadas en el cluster 1, mientras que en el cluster 2 se representan estratos medios predominantemente en zonas centro y oriente. Posiblemente las viviendas que presentan traslape en los grupos pueden corresponder a las de estrato 4 que presentan características variadas frente a la cantidad de baños y parqueaderos.

Análisis de Correspondencias

En este caso considerando el ajuste inicial realizado en los tipos de variables y la gran cantidad de barrios, más de 426. Se realizará el análisis de correspondencias entre las variables categóricas tipo de vivienda, zona y estrato.

Tablas de Contingencia

# Combinar tipo y estrato en una sola variable
v_sna$tipo_estrato <- paste(v_sna$tipo, v_sna$estrato, sep = "_")

#Tablas de contingencia incluyendo, tipo, estrato y zona
tabla1 <- table(v_sna$tipo, v_sna$zona)
tabla1
##              
##               Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
##   Apartamento          24       1198       1029           62     2787
##   Casa                100        722        169          289     1939
tabla2 <- table(v_sna$tipo, v_sna$estrato)
tabla2
##              
##                  3    4    5    6
##   Apartamento  639 1404 1766 1291
##   Casa         814  725  984  696
tabla3 <- table(v_sna$estrato, v_sna$zona)
tabla3
##    
##     Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
##   3         105        572         54          340      382
##   4          14        407         84            8     1616
##   5           4        769        290            2     1685
##   6           1        172        770            1     1043

Pruebas de independencia

#Pruebas de independencia entre las variables
test1 <- chisq.test(tabla1)
test1
## 
##  Pearson's Chi-squared test
## 
## data:  tabla1
## X-squared = 690.93, df = 4, p-value < 2.2e-16
test2 <- chisq.test(tabla2)
test2
## 
##  Pearson's Chi-squared test
## 
## data:  tabla2
## X-squared = 224.33, df = 3, p-value < 2.2e-16
test3 <- chisq.test(tabla3)
test3
## 
##  Pearson's Chi-squared test
## 
## data:  tabla3
## X-squared = 3830.4, df = 12, p-value < 2.2e-16

Ho: Las variables son independientes.

Al obtener un valor p<0.05 para todas las combinaciones de variables se rechaza Ho concluyendo que hay asociación entre las variables y tiene sentido realizar el análisis de correspondencias.

Análisis de Correspondencias Múltiple

# Seleccionar solo las variables categóricas
vars <- v_sna[, c("tipo", "estrato", "zona")]

# MCA
res.mca <- MCA(vars, graph = FALSE)

# Gráfico
fviz_mca_var(res.mca,
             repel = TRUE,
             col.var = "green")

En este gráfico se logran ver los siguientes 4 grupos diferenciados por las siguientes relaciones:

  1. Predominancia del estrato 6 en la zona Oeste.

  2. Los estratos 4 y 5 se encuentran principalmente en las zonas Norte y Sur con presencia de casas y apartamentos.

  3. Las zonas Centro y Oriente presentan similitudes.

  4. Las viviendas de estrato 3 no se ubican en un grupo específico. Se alejan del grupo 1 y se encuentran en un punto medio entre los grupos 2 y 3.

Conclusiones y Recomendaciones

Teniendo en cuenta los resultados del análisis multivariado y las relaciones existentes entre las variables, se sugieren las siguientes recomendaciones:

  1. Diseñar la estrategia de mercadeo segmentada según los siguientes 2 grupos de viviendas:

    1. Viviendas ubicadas en las zonas Norte, Sur y Oeste. Estas concentran los estratos 4, 5 y 6, con viviendas grandes, mayor número de baños y parqueaderos, y precios más altos.

    2. Viviendas ubicadas en las zonas Centro y Oriente. En las cuales predomina el estrato 3 con menor tamaño y menor número de baños y parqueaderos.

  2. Considerar en la estrategia de mercadeo destacar en los estratos altos, caracteristicas como la amplitud y comodidad que proporcionan multiples parqueaderos y baños. Y en los estratos medios destacar los precios más asequibles y posibilidades de financiación para primera vivienda. Se recomienda caracterizar los potenciales clientes.

  3. Seleccionar en el proceso de comercialización de manera preferencial aquellos inmuebles en las zonas Norte, Sur y Oeste con mayor cantidad de parqueaderos y baños, garantizando así un mayor precio de venta.

  4. Construir un modelo que permita estimar el precio de las viviendas a partir de sus características y así garantizar ofertas de comercialización coherentes y justas.