El mercado inmobiliario urbano se caracteriza por su alta complejidad y dinamismo, donde múltiples factores económicos, sociales y geográficos influyen en la oferta y demanda de viviendas. En este contexto, las empresas inmobiliarias enfrentan el reto de tomar decisiones estratégicas basadas en información confiable y en análisis estadísticos que permitan comprender mejor las tendencias del mercado.
La actividad propuesta busca realizar un análisis integral de una base de datos con 8322 registros de propiedades residenciales, recopilados mediante técnicas de webscraping en plataformas digitales de oferta inmobiliaria. Dichos datos incluyen variables cuantitativas como precio, área construida, número de habitaciones, baños y parqueaderos, así como variables cualitativas relacionadas con el tipo de vivienda, zona y barrio.
El objetivo principal es identificar patrones, relaciones y segmentaciones que permitan a la empresa inmobiliaria optimizar sus decisiones de compra, venta y valoración de propiedades. Para ello, se aplicarán técnicas estadísticas avanzadas como el Análisis de Componentes Principales (ACP), el Análisis de Conglomerados y el Análisis de Correspondencia, complementados con recursos de visualización que faciliten la interpretación de los resultados.
Este estudio no solo busca describir el estado actual del mercado, sino también generar recomendaciones estratégicas que otorguen ventajas competitivas en un entorno altamente competitivo y en constante cambio. La combinación de métodos estadísticos y visualización de datos permitirá construir una visión holística del mercado inmobiliario urbano, apoyando la toma de decisiones fundamentadas y orientadas a maximizar beneficios.
# devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
# Cargar librerías necesarias
library(paqueteMODELOS)
library(dplyr)
# Cargar la base de datos
data("vivienda")
# Crear tabla resumen de variables
tabla_variables <- tibble(
Variable = names(vivienda),
Tipo = sapply(vivienda, function(x) class(x)[1]),
Descripción = c(
"Identificador único de la propiedad",
"Zona de la ciudad donde se ubica la vivienda",
"Número de piso (en caso de apartamentos)",
"Estrato socioeconómico",
"Precio de la vivienda (en millones)",
"Área construida (m²)",
"Número de parqueaderos",
"Número de baños",
"Número de habitaciones",
"Tipo de vivienda (Casa, Apartamento, etc.)",
"Barrio donde se ubica la vivienda",
"Coordenada geográfica (longitud)",
"Coordenada geográfica (latitud)"
)
)
# Mostrar tabla
knitr::kable(tabla_variables, caption = "Resumen de variables de la base de datos 'vivienda'")| Variable | Tipo | Descripción |
|---|---|---|
| id | numeric | Identificador único de la propiedad |
| zona | character | Zona de la ciudad donde se ubica la vivienda |
| piso | character | Número de piso (en caso de apartamentos) |
| estrato | numeric | Estrato socioeconómico |
| preciom | numeric | Precio de la vivienda (en millones) |
| areaconst | numeric | Área construida (m²) |
| parqueaderos | numeric | Número de parqueaderos |
| banios | numeric | Número de baños |
| habitaciones | numeric | Número de habitaciones |
| tipo | character | Tipo de vivienda (Casa, Apartamento, etc.) |
| barrio | character | Barrio donde se ubica la vivienda |
| longitud | numeric | Coordenada geográfica (longitud) |
| latitud | numeric | Coordenada geográfica (latitud) |
# Seleccionar solo variables numéricas
vars_num <- vivienda %>%
select_if(is.numeric)
# Crear tabla resumen con estadísticos básicos
tabla_resumen <- vars_num %>%
summarise_all(list(
Min = ~min(., na.rm = TRUE),
Max = ~max(., na.rm = TRUE),
Media = ~mean(., na.rm = TRUE),
Mediana = ~median(., na.rm = TRUE),
DesvStd = ~sd(., na.rm = TRUE)
)) %>%
tidyr::pivot_longer(cols = everything(),
names_to = c("Variable", ".value"),
names_sep = "_")
# Mostrar tabla en Markdown
knitr::kable(tabla_resumen, caption = "Resumen estadístico de variables numéricas")| Variable | Min | Max | Media | Mediana | DesvStd |
|---|---|---|---|---|---|
| id | 1.00000 | 8319.0000 | 4160.000000 | 4160.000 | 2401.6327779 |
| estrato | 3.00000 | 6.0000 | 4.633610 | 5.000 | 1.0292221 |
| preciom | 58.00000 | 1999.0000 | 433.891947 | 330.000 | 328.6472443 |
| areaconst | 30.00000 | 1745.0000 | 174.934938 | 123.000 | 142.9641260 |
| parqueaderos | 1.00000 | 10.0000 | 1.835194 | 2.000 | 1.1249088 |
| banios | 0.00000 | 10.0000 | 3.111311 | 3.000 | 1.4282102 |
| habitaciones | 0.00000 | 10.0000 | 3.605361 | 3.000 | 1.4595368 |
| longitud | -76.58915 | -76.4630 | -76.528606 | -76.530 | 0.0173983 |
| latitud | 3.33300 | 3.4977 | 3.417644 | 3.416 | 0.0426385 |
# Calcular valores faltantes por variable
tabla_na <- vivienda %>%
summarise_all(~sum(is.na(.))) %>%
tidyr::pivot_longer(cols = everything(),
names_to = "Variable",
values_to = "Valores_Faltantes") %>%
arrange(desc(Valores_Faltantes))
# Mostrar tabla en Markdown
knitr::kable(tabla_na, caption = "Valores faltantes por variable en la base de datos 'vivienda'")| Variable | Valores_Faltantes |
|---|---|
| piso | 2638 |
| parqueaderos | 1605 |
| id | 3 |
| zona | 3 |
| estrato | 3 |
| areaconst | 3 |
| banios | 3 |
| habitaciones | 3 |
| tipo | 3 |
| barrio | 3 |
| longitud | 3 |
| latitud | 3 |
| preciom | 2 |
ggplot(vivienda, aes(x = preciom)) +
geom_histogram(binwidth = 50, fill = "steelblue", color = "white") +
labs(title = "Distribución de precios de vivienda (millones)",
x = "Precio (millones)", y = "Frecuencia")ggplot(vivienda, aes(x = areaconst, y = preciom)) +
geom_point(alpha = 0.4, color = "darkred") +
labs(title = "Precio vs Área construida",
x = "Área construida (m²)", y = "Precio (millones)")ggplot(vivienda, aes(x = factor(estrato), y = preciom)) +
geom_boxplot(fill = "lightgreen") +
labs(title = "Distribución de precios por estrato",
x = "Estrato socioeconómico", y = "Precio (millones)")# Conteo de tipos de vivienda
tabla_tipos <- vivienda %>%
group_by(tipo) %>%
summarise(Conteo = n()) %>%
arrange(desc(Conteo))
# Mostrar tabla en Markdown
knitr::kable(tabla_tipos, caption = "Conteo de tipos de vivienda en la base de datos 'vivienda'")| tipo | Conteo |
|---|---|
| Apartamento | 5100 |
| Casa | 3219 |
| NA | 3 |
# Conteo de viviendas por zona
tabla_zonas <- vivienda %>%
group_by(zona) %>%
summarise(Conteo = n()) %>%
arrange(desc(Conteo))
# Mostrar tabla en Markdown
knitr::kable(tabla_zonas, caption = "Conteo de viviendas por zona en la base de datos 'vivienda'")| zona | Conteo |
|---|---|
| Zona Sur | 4726 |
| Zona Norte | 1920 |
| Zona Oeste | 1198 |
| Zona Oriente | 351 |
| Zona Centro | 124 |
| NA | 3 |
# 1. Eliminar variables que no aportan al análisis
vivienda_limpia <- vivienda %>%
select(-id, -longitud, -latitud)
# 2. Eliminar las filas con valores faltantes en 'zona'
vivienda_limpia <- vivienda_limpia %>%
filter(!is.na(zona))
# 3. Imputar valores faltantes en 'piso' y 'parqueaderos' con la categoría "no_contesta" que es igual a 0
vivienda_limpia <- vivienda_limpia %>%
mutate(
piso = ifelse(is.na(piso), "no_contesta", piso),
parqueaderos = ifelse(is.na(parqueaderos), 0, as.character(parqueaderos))
)En el proceso de depuración de la base de datos se realizaron varias transformaciones orientadas a mejorar la calidad de la información y garantizar la pertinencia de las variables para los análisis estadísticos posteriores. En primer lugar, se eliminaron las variables id, longitud y latitud, dado que no aportan información relevante para los objetivos del estudio: el identificador es únicamente un consecutivo sin valor analítico, mientras que las coordenadas geográficas no serán utilizadas en los modelos planteados.
Posteriormente, se identificaron tres registros con valores faltantes en la variable zona. Debido a que estos casos no presentan información en ningún otro campo que permita su recuperación, se decidió eliminarlos de la base, evitando así sesgos en los análisis posteriores.
Finalmente, se abordó el problema de los valores faltantes en las variables piso y parqueaderos, que presentaban una proporción considerable de datos ausentes. Para no perder información y mantener la integridad del conjunto de datos, se optó por una imputación categórica, asignando la etiqueta “no_contesta” a aquellos registros sin respuesta, sin embargo, en el caso de los parqueaderos, el no contesta tiene un valor de 0. Esta estrategia permite conservar los casos en el análisis, diferenciando explícitamente entre datos reportados y datos omitidos, lo cual es metodológicamente más adecuado que la eliminación masiva de registros.
Previo a la aplicación del análisis de componentes principales, se realizaron ajustes en la fase de preparación de datos que dejaron la base sin valores faltantes, garantizando así la consistencia de la información. Sin embargo, durante la exploración inicial se identificó la presencia de valores atípicos en variables como el precio de las viviendas. Estos valores extremos, lejos de ser errores, forman parte de la naturaleza del mercado inmobiliario, donde coexisten propiedades de bajo costo con inmuebles de lujo de alto valor.
Con el fin de evitar que las diferencias de escala entre las variables numéricas generen sesgos en las estimaciones, se procedió a la estandarización de las variables. Este proceso transforma los datos para que cada variable tenga media cero y desviación estándar igual a uno, permitiendo que todas contribuyan de manera equitativa al análisis. De esta forma, se asegura que variables con magnitudes mayores, como el precio o el área construida, no dominen la estructura de los componentes principales.
# One-hot encoding de todas las variables categóricas excepto 'barrio'
#vivienda_dummy <- dummy_cols(
# vivienda_limpia,
# select_columns = c("zona", "tipo"), # variables categóricas a transformar
# remove_selected_columns = TRUE, # elimina las originales
# remove_first_dummy = FALSE # conserva todas las categorías
#)
# La variable 'barrio' queda sin transformarvivienda_limpia$parqueaderos=as.numeric(vivienda_limpia$parqueaderos)
viviendaZ=scale(vivienda_limpia[,3:8])## Standard deviations (1, .., p=6):
## [1] 1.8480703 1.1222455 0.6779600 0.6592367 0.4909833 0.4357909
##
## Rotation (n x k) = (6 x 6):
## PC1 PC2 PC3 PC4 PC5 PC6
## estrato 0.3306904 -0.5816950 0.5551021 0.07749341 0.46143880 -0.1587620
## preciom 0.4781754 -0.1883533 -0.0359721 -0.36062553 -0.21967777 0.7458339
## areaconst 0.4417250 0.2388377 -0.2878930 -0.61783592 0.27859384 -0.4534506
## parqueaderos 0.4096354 -0.2607395 -0.6565763 0.57091588 0.04760414 -0.0700729
## banios 0.4668745 0.1921461 0.3633148 0.18500105 -0.67876421 -0.3437503
## habitaciones 0.2847775 0.6813261 0.2111757 0.34936005 0.44521273 0.2997240
El gráfico de sedimentación (scree plot) muestra el porcentaje de varianza explicada por cada componente principal. El CP1 explica 56,9% de la variabilidad y el CP2 explica 21,0%, acumulando aproximadamente 77,9% de la varianza total. A partir del CP3 el aporte marginal es reducido (≤ 7,7% cada uno) y la curva se aplana, lo que indica rendimientos decrecientes.
fviz_pca_var(res.pca,
col.var = "contrib", # Color by contributions to the PC
gradient.cols = c("#FF7F00", "#034D94"),
repel = TRUE # Avoid text overlapping
)El gráfico de variables del Análisis de Componentes Principales muestra cómo las características físicas y económicas de las viviendas se proyectan sobre los dos primeros componentes, que en conjunto explican alrededor del 78% de la variabilidad del conjunto de datos. El primer componente, con un peso dominante del 56,9%, agrupa variables como área construida, número de baños, habitaciones, parqueaderos y precio, las cuales apuntan en la misma dirección y presentan vectores largos. Esto indica que estas variables están fuertemente correlacionadas entre sí y representan un eje relacionado con el tamaño, nivel de equipamiento y valor económico del inmueble.
Por su parte, el segundo componente, que explica el 21% de la variabilidad, captura aspectos adicionales no del todo explicados por el tamaño o el precio. En este eje destacan principalmente las variables habitaciones y estrato, que se proyectan en direcciones opuestas, sugiriendo que aportan información diferenciada sobre la estructura interna del inmueble y el nivel socioeconómico del entorno.
El Análisis de Componentes Principales permitió identificar que la estructura del mercado inmobiliario urbano analizado está dominada por una dimensión asociada al tamaño, equipamiento y valor económico del inmueble. Esta primera dimensión, que explica el 56,9% de la variabilidad, reúne de manera consistente variables como área, número de baños, habitaciones, parqueaderos y precio, evidenciando que las características físicas y de confort son los elementos más determinantes en la diferenciación de la oferta residencial. Los altos niveles de correlación entre estas variables confirman la existencia de un patrón estructural claro en la valoración de las viviendas.
El segundo componente principal, con un aporte adicional del 21%, introduce una dimensión complementaria relacionada con la configuración interna del inmueble y el nivel socioeconómico del sector. La oposición entre las variables habitaciones y estrato revela matices adicionales que no están completamente explicados por el tamaño o el precio, lo cual es coherente con la segmentación social y urbanística presente en las ciudades latinoamericanas. En conjunto, los dos componentes explican cerca del 78% de la variabilidad total, permitiendo una representación eficiente y altamente interpretable del mercado, y constituyendo una base sólida para los análisis posteriores de segmentación y clasificación.
Una vez identificadas las principales dimensiones que explican la variabilidad de las características de las viviendas mediante el Análisis de Componentes Principales, es posible avanzar hacia una etapa de segmentación más profunda. El ACP permitió reducir la complejidad del conjunto de variables originales y sintetizar la información en un espacio de menor dimensión que conserva la mayor parte de la estructura relevante de los datos.
En este contexto, el siguiente paso consiste en aplicar un Análisis de Conglomerados con el fin de identificar grupos homogéneos de viviendas que compartan características comunes. Al utilizar los componentes principales como insumo para el clustering, se garantiza que los grupos resultantes se formen a partir de los patrones estructurales realmente presentes en los datos, evitando que variables altamente correlacionadas distorsionen las distancias entre observaciones.
library(paqueteMODELOS)
library(factoextra)
library(ggplot2)
library(dplyr)
library(cluster)
library(tidyverse)
data("vivienda")
# 1. Eliminar variables que no aportan al análisis
vivienda_limpia <- vivienda %>%
select(-id, -longitud, -latitud)
# 2. Eliminar las filas con valores faltantes en 'zona'
vivienda_limpia <- vivienda_limpia %>%
filter(!is.na(zona))
# 3. Imputar valores faltantes en 'piso' y 'parqueaderos' con la categoría "no_contesta" que es igual a 0
vivienda_limpia <- vivienda_limpia %>%
mutate(
piso = ifelse(is.na(piso), "no_contesta", piso),
parqueaderos = ifelse(is.na(parqueaderos), 0, as.character(parqueaderos))
)
vivienda_limpia$parqueaderos=as.numeric(vivienda_limpia$parqueaderos)
viviendaZ=scale(vivienda_limpia[,3:8])
res.pca <- prcomp(viviendaZ)
viviendaZ_df <- as.data.frame(viviendaZ)
# Elegimos cuántos componentes usar para clusterización
ncp <- 2 # puedes cambiar a 3 si lo deseas
scores_pca <- as.data.frame(res.pca$x[, 1:ncp])
colnames(scores_pca) <- paste0("CP", 1:ncp)
# Estandarizamos por si acaso (los scores ya suelen estar en escala comparable, pero es seguro)
scores_pca <- scale(scores_pca) |> as.data.frame()# ===============================================================
# 1) Distancias
# ===============================================================
# Distancia Euclidiana
dist_eucl <- dist(scores_pca, method = "euclidean")
# ===============================================================
# 2) Clúster jerárquico con diferentes métodos de enlace
# ===============================================================
# Usaremos la distancia Euclidiana sobre el espacio CP
dist_cp <- dist_eucl
# Método "complete"
hc_complete <- hclust(dist_cp, method = "complete")
# Decidir k
k <- 3
# Asignación de clústeres con el método elegido
cl_asig <- cutree(hc_complete, k = k)
# Data frame con etiquetas
scores_cl <- scores_pca %>%
mutate(cluster = factor(cl_asig))
# ===============================================================
# 3) Gráfico de puntos (CP1 vs CP2) coloreado por clúster
# ===============================================================
if (ncol(scores_pca) >= 2) {
ggplot(scores_cl, aes(x = CP1, y = CP2, color = cluster)) +
geom_point(alpha = .6, size = 2.5) +
geom_text(aes(label = cluster), vjust = -0.9, size = 3, show.legend = FALSE) +
theme_classic() +
labs(title = paste0("Clusters en el espacio de CP (k = ", k, ")"),
x = "CP1", y = "CP2", color = "Clúster")
}El Clúster 1 (color rojo) se ubica principalmente hacia valores altos de CP2 y una zona intermedia de CP1. Esta posición indica que contiene viviendas con mayor número de habitaciones, baños o características asociadas a la dimensión representada por CP2, lo que sugiere propiedades más amplias o con mejor equipamiento interno. El Clúster 2 (color verde) se concentra en la región central del plano, con valores moderados de CP1 y CP2. Esto lo convierte en un grupo “intermedio”, compuesto por viviendas con atributos equilibrados en tamaño, área construida y precio. El Clúster 3 (color azul) aparece desplazado hacia valores altos de CP1 y ligeramente bajos de CP2, lo que sugiere viviendas con mayores niveles de tamaño o valor económico, posiblemente asociadas a estratos más altos o propiedades de mayor área.
La separación visual entre los tres grupos evidencia que el método de conglomerados logró identificar segmentos bien diferenciados dentro del mercado inmobiliario. Además, aunque existen zonas de traslape —lo cual es esperado dada la alta heterogeneidad del mercado—, se observan fronteras relativamente claras que indican que los clústeres capturan diferencias reales en las características de las viviendas.
# ===============================================================
# 4) Dendrogramas y rectángulos de corte
# ===============================================================
par(mfrow = c(1,1))
plot(hc_complete, cex=.5, main="Dendrograma - Complete", ylab="Altura", xlab="")
rect.hclust(hc_complete, k = k, border = 2:5)En la gráfica se observa que las uniones entre observaciones cercanas ocurren en alturas bajas, lo que indica que existe un gran número de viviendas con características muy similares. A medida que asciende la altura del dendrograma, aparecen fusiones cada vez más distantes, lo cual refleja la presencia de grupos más heterogéneos que sólo pueden combinarse a niveles elevados de distancia. La presencia de saltos amplios en las alturas superiores sugiere puntos naturales de corte donde la estructura de los datos cambia drásticamente, facilitando la identificación del número adecuado de conglomerados.
En este caso, el corte dibujado sobre el dendrograma delimita tres grandes clústeres, lo cual es coherente con los saltos visibles en la altura de las fusiones. Los grupos formados presentan tamaños relativamente equilibrados y mantienen una separación horizontal apreciable, lo que indica que las viviendas asignadas a cada conglomerado presentan similitudes internas fuertes y diferencias claras respecto a los otros grupos.
# ===============================================================
# 6) Coeficiente de Silhouette (k elegido)
# ===============================================================
sil <- silhouette(cl_asig, dist_cp)
sil_avg <- mean(sil[, "sil_width"])
cat("Coeficiente de Silhouette promedio para k =", k, ": ", round(sil_avg, 3), "\n")## Coeficiente de Silhouette promedio para k = 3 : 0.418
El coeficiente de Silhouette promedio obtenido para k=3k=3k=3 fue 0,418, lo que sugiere una estructura de clústeres moderadamente bien definida. La partición en tres grupos ofrece un equilibrio entre separación y compactación interna, con cierta superposición esperable dado el carácter heterogéneo del mercado inmobiliario.
El ejercicio de segmentación identificó tres clústeres diferenciados y operativamente útiles para describir la oferta inmobiliaria. La elección de k=3 se sustentó en (1) los saltos de altura observados en el dendrograma (puntos naturales de corte), (2) la separación visual en el plano de los dos primeros componentes (grupos con fronteras razonablemente claras) y (3) un coeficiente de Silhouette promedio = 0,418, que indica una estructura de segmentación moderada pero consistente: existen grupos discernibles con cierta superposición en las zonas de frontera, algo esperable en mercados heterogéneos. En términos sustantivos, los clústeres se organizan principalmente alrededor de los ejes ya detectados en el ACP: tamaño/equipamiento–precio y estratificación. De forma general, se reconoce un segmento de mayor valor (inmuebles más grandes y costosos), un segmento intermedio (atributos equilibrados) y un segmento de acceso/asequible (menores áreas, precios y dotaciones), lo que confirma que la oferta se agrupa en submercados coherentes.
Para complementar los resultados obtenidos en los análisis previos, se realizará un análisis de correspondencia utilizando únicamente las variables categóricas de la base de datos. Aunque inicialmente se consideró incluir la variable barrio, su alto número de categorías y baja frecuencia en muchas de ellas dificultaba la interpretación y la estabilidad de los resultados. Por esta razón, se decidió trabajar únicamente con la variable zona, la cual agrupa territorialmente a los barrios y permite capturar de manera más sintética la dimensión geográfica del mercado inmobiliario.
Adicionalmente, la variable estrato, que originalmente estaba en formato numérico, fue transformada a una variable categórica para incorporarla en este análisis. De esta forma será posible explorar con mayor precisión cómo se relacionan el tipo de vivienda, la zona y el estrato socioeconómico, ampliando la comprensión cualitativa de la estructura y segmentación del mercado urbano.
library(paqueteMODELOS)
library(factoextra)
library(dplyr)
library(FactoMineR)
library(tidyr)
data("vivienda")
# Base mínima para AC/MCA (solo las 3 categóricas a analizar)
vivienda_cat <- vivienda %>%
select(tipo, zona, estrato) %>% # nos quedamos con las 3 variables
drop_na(tipo, zona, estrato) %>% # quitamos NAs en estas columnas
mutate(
tipo = as.factor(tipo),
zona = as.factor(zona),
estrato = as.factor(estrato) # estrato pasa a categórica
)
summary(vivienda_cat)## tipo zona estrato
## Apartamento:5100 Zona Centro : 124 3:1453
## Casa :3219 Zona Norte :1920 4:2129
## Zona Oeste :1198 5:2750
## Zona Oriente: 351 6:1987
## Zona Sur :4726
# Tabla de contingencia 3D (tipo × zona × estrato)
tab3 <- with(vivienda_cat, table(tipo, zona, estrato))
# Tabla “aplanada” (flat table) para lectura en reporte/HTML
ftab3 <- ftable(tab3)
ftab3## estrato 3 4 5 6
## tipo zona
## Apartamento Zona Centro 14 7 3 0
## Zona Norte 337 246 498 117
## Zona Oeste 29 58 231 711
## Zona Oriente 58 2 1 1
## Zona Sur 201 1091 1033 462
## Casa Zona Centro 91 7 1 1
## Zona Norte 235 161 271 55
## Zona Oeste 25 26 59 59
## Zona Oriente 282 6 1 0
## Zona Sur 181 525 652 581
# MCA con las 3 variables categóricas
mca_res <- MCA(vivienda_cat, graph = FALSE)
# Inercia por dimensión
mca_res$eig## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.5620882 21.078306 21.07831
## dim 2 0.4531232 16.992119 38.07043
## dim 3 0.3796450 14.236687 52.30711
## dim 4 0.3334444 12.504164 64.81128
## dim 5 0.3233137 12.124263 76.93554
## dim 6 0.2717762 10.191608 87.12715
## dim 7 0.2013563 7.550862 94.67801
## dim 8 0.1419197 5.321990 100.00000
El mapa factorial revela tres asociaciones territoriales y socioeconómicas principales. En el cuadrante derecho, Zona Oriente y Zona Centro se proyectan juntas y alejadas del origen, en proximidad con Estrato 3, lo que sugiere una co‑ocurrencia por encima de lo esperable bajo independencia. En el cuadrante superior izquierdo, Zona Oeste aparece muy próxima a Estrato 6, indicando un nicho de alto estrato relativamente diferenciado. Por su parte, el cuadrante inferior izquierdo reúne a Zona Sur con Estratos 4 y 5, y en esa misma dirección se ubica Apartamento, lo que sugiere una mayor afinidad relativa de esta tipología con esa zona y esos estratos que con el eje Centro/Oriente.
En cuanto a la tipología Casa y a Zona Norte, ambas se sitúan cerca del origen, por lo que discriminan poco en las dos primeras dimensiones y muestran un comportamiento más “promedio” respecto al conjunto. En términos de ejes, Dimensión 1 (21,1%) contrapone Centro/Oriente–Estrato 3 frente a Sur/Oeste (donde se alinea Apartamento), mientras que Dimensión 2 (17%) separa el bloque Oeste–Estrato 6 (arriba) del bloque Sur–Estratos 4–5 (abajo). Estas configuraciones apuntan a submercados territoriales con perfiles socioeconómicos diferenciados y a una segmentación tipológica más marcada para Apartamento que para Casa en este plano.
El análisis de correspondencia múltiple entre tipo, zona y estrato evidencia tres focos territoriales y socioeconómicos diferenciados: (i) Zona Oriente–Zona Centro asociados principalmente a estrato 3; (ii) Zona Oeste vinculada al estrato 6 (alto); y (iii) Zona Sur con mayor afinidad por estratos 4–5 y la tipología Apartamento, mientras que Casa y Zona Norte se ubican cerca del origen y, por tanto, discriminan poco en las dos primeras dimensiones.
El análisis integral del mercado inmobiliario permitió identificar patrones estructurales, segmentaciones y asociaciones territoriales que explican de manera consistente la variabilidad y organización de la oferta urbana. El ACP evidenció que las diferencias entre viviendas están dominadas por un eje de tamaño, equipamiento y precio, complementado por una segunda dimensión socioeconómica asociada al estrato. Con base en estas estructuras, el análisis de conglomerados identificó tres segmentos claramente diferenciados: un segmento premium caracterizado por inmuebles amplios y de alto valor; un segmento medio con atributos equilibrados; y un segmento asequible, conformado por propiedades de menor tamaño y precio. Finalmente, el análisis de correspondencia mostró que estas diferencias también se reflejan territorialmente: Zona Oriente–Centro se asocia a estrato 3, Zona Sur a estratos 4 y 5 y al producto Apartamento, mientras que Zona Oeste concentra oferta de estrato 6. Estos hallazgos confirman que la oferta inmobiliaria urbana no es homogénea, sino que se organiza en submercados coherentes tanto en términos físicos como socioeconómicos y territoriales.
A partir de estos resultados, se proponen varias recomendaciones estratégicas para la empresa inmobiliaria. En primer lugar, se sugiere orientar la captación de propiedades premium hacia la Zona Oeste, donde existe una clara concentración de vivienda de estrato alto, lo cual permite maximizar márgenes y fortalecer el portafolio de alto valor. En segundo lugar, el segmento medio, mayoritario y con alta rotación, representa una oportunidad para estrategias de volumen y estabilidad comercial, especialmente en la Zona Sur, donde los apartamentos de estratos 4 y 5 tienen una presencia significativa. En tercer lugar, la oferta asociada al estrato 3 en el corredor Centro–Oriente constituye un mercado sensible al precio, ideal para estrategias de posicionamiento basadas en accesibilidad, financiación flexible y optimización de inventario. De forma transversal, se recomienda integrar estos segmentos en un sistema de pricing diferenciado por zona y tipología, fortalecer los modelos predictivos de valoración con los componentes principales identificados, y utilizar los resultados del clustering y del MCA para diseñar campañas comerciales focalizadas según perfil socioeconómico y localización.