El presente informe busca comprender en profundidad el mercado de viviendas urbanas para una empresa inmobiliaria líder. Utilizando una base de datos con 8,322 registros , se aplicarán técnicas de reducción de dimensionalidad (ACP), segmentación y análisis de correspondencia para identificar patrones que optimicen la toma de decisiones estratégicas.
En esta etapa se realiza la carga y limpieza de la base de datos vivienda.
Identificación de variables que proporciona el dataset.
| Variable | Descripción |
|---|---|
| id | Identificador único del registro |
| zona | Ubicación geográfica por zona de la ciudad |
| piso | Nivel o piso donde se ubica el inmueble |
| estrato | Estrato socioeconómico (1 al 6) |
| preciom | Precio de la vivienda en millones de pesos (COP) |
| areaconst | Área total construida en metros cuadrados |
| parqueaderos | Número de cupos de parqueo o estacionamiento |
| banios | Número de baños disponibles |
| habitaciones | Número de habitaciones o alcobas |
| tipo | Tipo de inmueble (Casa o Apartamento) |
| barrio | Nombre del sector o barrio de ubicación |
| longitud | Longitud geográfica para mapeo |
| latitud | Latitud geográfica para mapeo |
Identificación de variables y número de NAs identificados en cada una.
| Faltantes | Porcentaje | |
|---|---|---|
| id | 3 | 0.04% |
| zona | 3 | 0.04% |
| piso | 2638 | 31.7% |
| estrato | 3 | 0.04% |
| preciom | 2 | 0.02% |
| areaconst | 3 | 0.04% |
| parqueaderos | 1605 | 19.29% |
| banios | 3 | 0.04% |
| habitaciones | 3 | 0.04% |
| tipo | 3 | 0.04% |
| barrio | 3 | 0.04% |
| longitud | 3 | 0.04% |
| latitud | 3 | 0.04% |
Gráficamente, la distribución de los valores faltantes pueden verse así:
Esa visualización de la función aggr y el resumen de conteos son reveladores. Confirman que el desafío principal de limpieza está en las variables piso (aprox. 31.7% de faltantes) y parqueaderos (aprox. 19.3%). Y dado el alto volúmen de información que se perdería, no basta con eliminar esas filas; se perderían casi un tercio de la data.
Para ello, se realizará lo siguiente para imputar los valores:
| Etapa | Registros | Porcentaje.Conservado |
|---|---|---|
| Base de Datos Original | 8322 | 100% |
| Tras Limpieza de NAs Críticos | 8319 | 99.96% |
| Variable | NAs.Finales |
|---|---|
| id | 0 |
| zona | 0 |
| piso | 0 |
| estrato | 0 |
| preciom | 0 |
| areaconst | 0 |
| parqueaderos | 0 |
| banios | 0 |
| habitaciones | 0 |
| tipo | 0 |
| barrio | 0 |
| longitud | 0 |
| latitud | 0 |
En este sentido, solo se han perdido 3 observaciones del total de la base original.
Con lo anterior, se logra:
A continuación, se procede a identificar relaciones clave antes de pasar a los modelos multivariados como el ACP o los Conglomerados.
I. Análisis de Relaciones Estratégicas Se relacionará el precio con el estrato y el tipo de vivienda, ya que estas variables suelen ser los principales motores del mercado inmobiliario urbano.
# Boxplot interactivo: Precio por Estrato y Tipo de Vivienda
ggplot(vivienda_clean, aes(x = as.factor(estrato), y = preciom, fill = tipo)) +
geom_boxplot(alpha = 0.7, outlier.shape = NA) +
theme_minimal() +
labs(title = "Distribución de Precios por Estrato y Tipo",
x = "Estrato Socioeconómico",
y = "Precio (Millones COP)",
fill = "Tipo de Vivienda") +
coord_cartesian(ylim = c(0, quantile(vivienda_clean$preciom, 0.98))) # Zoom para evitar outliersEsto nos muestra cómo, existe una progresión clara: a mayor estrato, mayor precio base y mayor variabilidad de este. Las casas suelen tener una mediana de precio superior a los apartamentos en los mismos estratos debido al metraje y la propiedad del suelo.
Interpretación de la Matriz:
Además, la Matriz de Relaciones muestra que las variables preciom y areaconst presentan distribuciones con un fuerte sesgo a la derecha y una relación que, aunque positiva (\(r = 0.687\)), muestra una mayor dispersión a medida que aumentan los valores. Esto es un indicio de que, sería recomendable aplicar un logaritmo natural (\(ln\)) como decisión técnica para mejorar la distribución de los datos:
En el mercado inmobiliario, la relación entre área y precio suele ser multiplicativa más que aditiva; el logaritmo transforma esta relación en lineal, facilitando el trabajo del ACP y las regresiones. También ayuda a que la varianza sea más constante, evitando que las propiedades de lujo (outliers de alto valor) dominen por completo la varianza del modelo. Adempas, en economía, el uso de logaritmos permite interpretar los coeficientes como cambios porcentuales (ej. “por cada 1% de aumento en el área, el precio aumenta un \(x\)%”).
# Transformación logarítmica para estabilizar varianza
vivienda_log <- vivienda_clean %>%
mutate(
log_precio = log(preciom),
log_area = log(areaconst)
)
# Gráfico de dispersión: Original vs Logarítmico
library(patchwork)
p1 <- ggplot(vivienda_clean, aes(x = areaconst, y = preciom)) +
geom_point(alpha = 0.3, color = "steelblue") +
geom_smooth(method = "lm", color = "red") +
labs(title = "Relación Original (Escala Lineal)", x = "Área", y = "Precio") +
theme_minimal()
p2 <- ggplot(vivienda_log, aes(x = log_area, y = log_precio)) +
geom_point(alpha = 0.3, color = "darkgreen") +
geom_smooth(method = "lm", color = "red") +
labs(title = "Relación Transformada (Escala Log)", x = "log(Área)", y = "log(Precio)") +
theme_minimal()
p1 + p2Tras realizar el análisis descriptivo inicial, se detectó un marcado sesgo positivo en las variables de precio y área construida. Para mitigar el efecto de los valores atípicos y corregir la heterocedasticidad observada en la nube de puntos, se optó por aplicar una transformación logarítmica. Esto permite normalizar las distribuciones y capturar relaciones de elasticidad, asegurando que el posterior Análisis de Componentes Principales (ACP) capture de manera más equilibrada la variabilidad de todo el mercado y no solo de las propiedades de mayor valor.
# Conteo de ofertas por zona y tipo
vivienda_clean %>%
count(zona, tipo) %>%
ggplot(aes(x = reorder(zona, n), y = n, fill = tipo)) +
geom_col(position = "dodge") +
coord_flip() +
theme_minimal() +
labs(title = "Densidad de Oferta por Zona",
x = "Zona de la Ciudad",
y = "Cantidad de Propiedades")
El análisis descriptivo actual revela una estructura de mercado muy
clara y justifica plenamente el paso hacia el Análisis de Componentes
Principales (ACP).
Variables Críticas de Precio: La matriz de relaciones confirma que el precio (preciom) tiene una correlación positiva sólida con el área construida (areaconst) (\(r = 0.687\)), los baños (\(r = 0.669\)) y los parqueaderos (\(r = 0.669\)). Esto sugiere que el valor de la propiedad no solo depende del tamaño, sino del nivel de comodidad y estatus.
Segmentación Geográfica: La densidad de oferta muestra que la Zona Sur es el núcleo del mercado, dominada por apartamentos, mientras que la Zona Oeste presenta una oferta casi exclusiva de apartamentos de alta densidad.
Comportamiento de los Datos Faltantes: El análisis de patrones confirma que la variable piso es la más afectada (\(NA > 30\%\)), seguida de parqueaderos. Sin embargo, se buscó una estrategia de imputación lógica para no perder la mayoría de los casos que están completos en el resto de variables.
Para el ACP, se utilizarán las versiones logarítmicas de precio y área para estabilizar la varianza y asegurar que las componentes no sean dominadas por propiedades extremas.
Objetivo: Reducir la dimensionalidad e identificar qué variables influyen más en la variación de precios.
# Preparación de datos para ACP
# Seleccionamos variables numéricas y aplicamos logaritmos donde acordamos
vivienda_pca_data <- vivienda_clean %>%
mutate(
log_preciom = log(preciom),
log_areaconst = log(areaconst)
) %>%
select(log_preciom, log_areaconst, estrato, banios, habitaciones, parqueaderos)
# Ejecución del ACP (Escalado automático incluido)
library(FactoMineR)
library(factoextra)
res_pca <- PCA(vivienda_pca_data, scale.unit = TRUE, graph = FALSE)
# 1.1. Visualización de la Varianza Explicada (Scree Plot)
fviz_eig(res_pca, addlabels = TRUE, ylim = c(0, 70),
barfill = "#3498db", barcolor = "#3498db") +
labs(title = "Varianza Explicada por Componente",
x = "Componentes Principales", y = "% de Varianza")De haberse realizado el ejercicio de PCA con las variables originales, el resultado hubiera dado que, la primera componente sumaba un 57,3% y la segunda componente un 20,5% (para un 77,8% entre ambas dimensiones). Con la transformación (logaritmos a preciom y areaconst), la Dimensión 1 (PC1) ahora explica el 60.5% de la varianza. Esto significa que se mejoró la capacidad del modelo para capturar la estructura del mercado.
fviz_pca_var(res_pca, col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE) +
labs(title = "Círculo de Correlación: Variables en el Espacio del ACP")PC1 (60.5% - “Eje de Valor y Dimensión”): los vectores de log_preciom, log_areaconst, banios y parqueaderos están ahora más alineados y son más largos. Esto indica que la transformación logró que el modelo identifique con mayor precisión que el tamaño físico y el valor económico son la misma fuerza impulsora del mercado.
PC2 (20.3% - “Eje de Estilo de Vida”): la variable habitaciones sigue siendo la protagonista de este eje, pero ahora vemos una separación más limpia respecto al estrato.
Hacia arriba: Propiedades con vocación familiar (muchas habitaciones).
Hacia abajo: Propiedades con vocación de ubicación/estatus (estrato alto), que no necesariamente tienen muchas habitaciones, sino mejores acabados o ubicaciones.
Contribución: Las variables en naranja/rojo (log_preciom, log_areaconst, habitaciones y estrato) son las que más información aportan para definir la personalidad de cada vivienda en la ciudad. Los parqueaderos, por su parte, no aportan tanto en la explicación del piso.
Ahora que se tienen las coordenadas perfectas, se pueden agrupar las 8,319 propiedades del dataset. Para ello, se utilizará el método K-means sobre los resultados del ACP.
# 1. Extraer las coordenadas de las componentes para el clustering
pca_coord <- as.data.frame(res_pca$ind$coord)
# 2. Determinar número de clusters (Método del Codo)
set.seed(123)
fviz_nbclust(pca_coord, kmeans, method = "wss") +
geom_vline(xintercept = 4, linetype = 2, color = "red") +
labs(title = "Método del Codo para Selección de K",
subtitle = "Buscamos el punto donde la ganancia de información se estabiliza")
La gráfica indica que, retener \(k =
4\) grupos es una decisión técnica sólida para este mercado
inmobiliario. Estadísticamente, esto significa que se ha alcanzado el
punto de equilibrio en el que añadir un quinto grupo no reduce
significativamente la varianza interna (el “error”), permitiendo una
segmentación lo suficientemente diversa para captar las diferencias de
la ciudad pero lo suficientemente simple para ser accionable.
Objetivo: Agrupar las propiedades en segmentos homogéneos.
Se ejecuta el algoritmo K-means sobre las coordenadas del ACP para segmentar las propiedades.
# Ejecución de K-means con k=4
set.seed(123)
km_res <- kmeans(pca_coord, centers = 4, nstart = 25)
# Asignar el cluster a la base de datos original
vivienda_clean$cluster <- as.factor(km_res$cluster)
# Visualización de los clusters en el plano de las componentes
fviz_cluster(km_res, data = pca_coord,
palette = "jco",
ellipse.type = "convex",
geom = "point",
stand = FALSE,
main = "Segmentación del Mercado Inmobiliario (K=4)")El gráfico de Segmentación del Mercado Inmobiliario (\(K=4\)) representa el resultado final del presente análisis de aprendizaje no supervisado. En este punto, se han transformado las 6 variables originales en un mapa bidimensional donde cada punto es una de las 8,319 propiedades del conjunto de datos.
¿Qué significa cada Cluster en el “Mundo Real”? Al observar la posición de los polígonos, se puede interpretar la naturaleza de cada segmento:
Ahora bien, como el reto pide examinar variables categóricas, se realiza también un Análisis de Correspondencia Múltiple para ver cómo se relacionan los clusters con la zona y el tipo de vivienda.
Esta técnica es fundamental porque permite cruzar los grupos numéricos que acabamos de crear con las variables categóricas (Zona y Tipo), respondiendo a la pregunta: ¿Dónde y qué tipo de propiedades componen cada segmento?.
Objetivo: Relacionar variables categóricas como zona, tipo y estrato.
# Renombrar los niveles del cluster para que sean descriptivos
vivienda_clean <- vivienda_clean %>%
mutate(cluster_label = factor(cluster,
levels = c("1", "2", "3", "4"),
labels = c("Lujo / Elite",
"Clase Media",
"Familiar Amplio",
"Interés Social")))
# Preparación de variables categóricas
vivienda_cat <- vivienda_clean %>%
select(zona, tipo, cluster_label) %>%
mutate(across(everything(), as.factor))
# Ejecución del ACM
res_mca <- MCA(vivienda_cat, graph = FALSE)
# Visualización corregida (Cambiando 'main' por 'title')
fviz_mca_biplot(res_mca,
repel = TRUE,
col.var = "indianred",
col.ind = "gray",
label = "var",
title = "Mapa de Correspondencia: Zonas, Tipos y Segmentos") +
theme_minimal()Basado en este gráfico, la interpretación de estos resultados indicaría:
Dinámica de los Ejes (Inercia)
Dimensión 1 (21.1%): este eje separa el mercado por tipología y densidad. Hacia la izquierda se agrupan los apartamentos y zonas de alta densidad, mientras que hacia la derecha se desplazan las casas y zonas con lotes más grandes.
Dimensión 2 (16.5%): este eje representa el estatus socioeconómico y la ubicación. Separa claramente el norte y el sur del centro y el oriente de la ciudad.
Análisis de las Asociaciones (Cercanía de Categorías)
El Clúster de Lujo y la Zona Oeste: Existe una asociación directa entre el segmento “Lujo / Elite” y la “Zona Oeste”. Esto indica que la oferta de más alto valor de la ciudad está geográficamente concentrada y se compone primordialmente de apartamentos de lujo.
El Clúster Familiar y la Zona Sur: El segmento “Familiar Amplio” aparece vinculado a la “Zona Sur” y al tipo “Casa”. Esto sugiere que el sur sigue siendo el refugio de las viviendas tradicionales de gran metraje y múltiples habitaciones.
Interés Social y Zona Norte: El análisis revela que el segmento de “Interés Social” tiene una fuerte correspondencia con la “Zona Norte”. Esto es un hallazgo estratégico, ya que indica hacia dónde se está expandiendo la oferta de bajo costo.
Zonas Oriente y Centro: Estas zonas aparecen en el cuadrante inferior derecho, alejadas del lujo y la clase media. Su cercanía al perfil “Familiar Amplio” puede indicar viviendas antiguas de gran tamaño pero menor estrato socioeconómico.
Por último, se hace una representación geográfica de los hallazgos para facilitar la interpretación con el contexto real.
library(leaflet)
# 1. Definir una paleta de colores profesional para los 4 segmentos
paleta <- colorFactor(
palette = c("#2c3e50", "#3498db", "#27ae60", "#e74c3c"),
domain = vivienda_clean$cluster_label
)
# 2. Preparar una muestra para el mapa (2000 registros es ideal para fluidez)
set.seed(123)
vivienda_mapa <- vivienda_clean %>% sample_n(2000)
# 3. Generación del mapa
leaflet(vivienda_mapa) %>%
addTiles() %>%
# Añadir marcadores con la información completa
addCircleMarkers(
~longitud, ~latitud,
color = ~paleta(cluster_label),
radius = 3,
fillOpacity = 0.7,
stroke = FALSE,
label = ~paste0(
"Segmento: ", cluster_label,
" | Precio: $", preciom, "M",
" | Tipo: ", tipo
)
) %>%
# Ajustar la leyenda con los nombres descriptivos
addLegend(
"bottomright",
pal = paleta,
values = ~cluster_label,
title = "Segmentos de Mercado",
opacity = 1
)La visualización geográfica confirma la segregación del mercado identificada en el ACM. Se observa una alta densidad de propiedades de Lujo / Elite en la Zona Oeste, mientras que el segmento Familiar Amplio domina el corredor Sur. Este mapa permite a la empresa identificar visualmente las fronteras de precios y zonas de expansión para nuevos proyectos inmobiliarios, optimizando la inversión según el perfil de cada barrio.
El presente análisis técnico de 8,322 registros de la base de datos de viviendas permite establecer una hoja de ruta clara para la toma de decisiones de inversión inmobiliaria.
A continuación, se sintetizan los hallazgos clave:
Este análisis fue desarrollado como parte de la Maestría en Ciencia de Datos en el curso de Modelos Estadísticos para la Toma Decisiones de la Universidad Javeriana Cali, 2026-I. Si tienes dudas sobre la metodología (ACP, Clustering o ACM) o quieres conectar para colaborar, no dudes en contactarme:
LinkedIn | GitHub | Correo Electrónico