Este informe presenta un análisis detallado del mercado inmobiliario urbano con el objetivo de identificar patrones en la oferta de viviendas. Se aplican técnicas estadísticas como Análisis de Componentes Principales (ACP), Clustering y Análisis de Correspondencia.
#install.packages("FactoMineR")
#install.packages("factoextra")
#install.packages("mice")
#install.packages("naniar")
#install.packages("VIM")
#install.packages("knitr")
# Cargar librerías
library(ca)
## Warning: package 'ca' was built under R version 4.4.3
library(factoextra)
## Warning: package 'factoextra' was built under R version 4.4.3
## Cargando paquete requerido: ggplot2
## Warning: package 'ggplot2' was built under R version 4.4.3
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(cluster)
library(cowplot)
library(devtools)
## Warning: package 'devtools' was built under R version 4.4.3
## Cargando paquete requerido: usethis
## Warning: package 'usethis' was built under R version 4.4.3
library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(FactoMineR)
## Warning: package 'FactoMineR' was built under R version 4.4.3
library(ggplot2)
library(gridExtra)
## Warning: package 'gridExtra' was built under R version 4.4.3
##
## Adjuntando el paquete: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
library(mice)
## Warning: package 'mice' was built under R version 4.4.3
##
## Adjuntando el paquete: 'mice'
## The following object is masked from 'package:stats':
##
## filter
## The following objects are masked from 'package:base':
##
## cbind, rbind
library(naniar)
## Warning: package 'naniar' was built under R version 4.4.3
library(paqueteMODELOS)
## Cargando paquete requerido: boot
## Cargando paquete requerido: broom
## Warning: package 'broom' was built under R version 4.4.3
## Cargando paquete requerido: GGally
## Warning: package 'GGally' was built under R version 4.4.3
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
## Cargando paquete requerido: knitr
## Warning: package 'knitr' was built under R version 4.4.3
## Cargando paquete requerido: summarytools
## Warning: package 'summarytools' was built under R version 4.4.3
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ lubridate 1.9.4 ✔ tibble 3.2.1
## ✔ purrr 1.0.4 ✔ tidyr 1.3.1
## ✔ readr 2.1.5
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ gridExtra::combine() masks dplyr::combine()
## ✖ mice::filter() masks dplyr::filter(), stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ✖ lubridate::stamp() masks cowplot::stamp()
## ✖ tibble::view() masks summarytools::view()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# Cargar la base vivienda
data("vivienda")
# Exploración inicial
dim(vivienda) # Dimensiones de la base de datos
## [1] 8322 13
str(vivienda) # Estructura de las variables
## 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")=
## .. cols(
## .. id = col_double(),
## .. zona = col_character(),
## .. piso = col_character(),
## .. estrato = col_double(),
## .. preciom = col_double(),
## .. areaconst = col_double(),
## .. parqueaderos = col_double(),
## .. banios = col_double(),
## .. habitaciones = col_double(),
## .. tipo = col_character(),
## .. barrio = col_character(),
## .. longitud = col_double(),
## .. latitud = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
summary(vivienda) # Resumen estadístico
## 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
cuántos valores faltantes hay por variable
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
gg_miss_var(vivienda) +
labs(title = "Valores faltantes por variable")
Esta gráfica muestra la cantidad de valores faltantes por variable en tu conjunto de datos.
Variables con mayor cantidad de valores perdidos:
piso: es la más afectada, con más de 2500 registros sin información.
parqueaderos: también presenta un número significativo de valores faltantes (ligeramente inferior a piso).
Resto de variables: Todas las demás (zona, tipo, longitud, latitud, id, habitaciones, estrato, barrio, banios, areaconst, preciom) tienen pocos o ningún valor perdido, lo cual es positivo para el análisis.
Las variables piso y parqueaderos podrían requerir imputación de valores o bien excluirse del análisis si no son críticas y la cantidad de datos perdidos afecta los modelos.
El resto de las variables presentan buena calidad en cuanto a completitud, lo que facilita su uso en análisis descriptivo o predictivo.
vis_miss(vivienda) +
labs(title = "Mapa de valores faltantes en la base 'vivienda'")
c
porcenta de satod faltantes
library(dplyr)
library(knitr)
tabla_perdidos <- data.frame(
Variable = names(vivienda),
Porcentaje_Perdido = apply(vivienda, 2, function(x) sum(is.na(x))/length(x)*100)
) %>%
arrange(desc(Porcentaje_Perdido)) %>%
mutate(Porcentaje_Perdido = sprintf("%.2f%%", Porcentaje_Perdido))
rownames(tabla_perdidos) <- NULL
kable(tabla_perdidos, align = c("l", "c"),
col.names = c("Variable", "% Perdido"))
Variable | % Perdido |
---|---|
piso | 31.70% |
parqueaderos | 19.29% |
id | 0.04% |
zona | 0.04% |
estrato | 0.04% |
areaconst | 0.04% |
banios | 0.04% |
habitaciones | 0.04% |
tipo | 0.04% |
barrio | 0.04% |
longitud | 0.04% |
latitud | 0.04% |
preciom | 0.02% |
La calidad de datos es muy buena en general, salvo en piso y parqueaderos.
Para esos dos casos críticos, puedes:
Usar imputación (mediana o moda si son numéricos, más frecuente si son categóricos).
Excluir la variable si no es clave para el modelo.
vivienda$zona <- as.factor(vivienda$zona)
vivienda$tipo <- as.factor(vivienda$tipo)
vivienda$barrio <- as.factor(vivienda$barrio)
#vivienda$piso <- ifelse(is.na(vivienda$piso), "Desconocido", vivienda$piso)
#vivienda$parqueaderos <- ifelse(is.na(vivienda$parqueaderos), "Desconocido", vivienda$parqueaderos)
vivienda2 <- vivienda[, !names(vivienda) %in% c("id", "parqueaderos")]
# Eliminar las filas con datos faltantes
vivienda3 <- vivienda2[complete.cases(vivienda2), ]
Se procede a estandarizar los datos de variables númericas que se consideren de gran relevancia, de modo que se asegura la no afectación de procedimiento de analisis de componentes principales.
library(dplyr)
viviendaCP <- vivienda3 %>%
select_if(is.numeric) %>%
scale()
head (viviendaCP)
## estrato preciom areaconst banios habitaciones longitud
## [1,] -0.6578315 -0.07388895 0.8208022 1.37212934 -0.3961809 -0.6424705
## [2,] 0.3408636 -0.51100887 -0.5699215 -0.77917165 -0.3961809 0.9038453
## [3,] 0.3408636 -0.57345457 -0.5918803 -0.06207132 -0.3961809 0.6996149
## [4,] -0.6578315 -0.63590027 -0.8480663 -0.77917165 -0.3961809 0.5397317
## [5,] 0.3408636 -0.35489461 -0.2259004 -0.06207132 0.3182519 -0.1202242
## [6,] 0.3408636 -0.32367176 -0.1307456 0.65502901 1.7471176 0.9090970
## latitud
## [1,] 0.4381262
## [2,] 0.9986195
## [3,] -1.0923885
## [4,] 0.2334793
## [5,] -0.7817848
## [6,] 1.4855055
Con lo anterior se procede a calcular la desviación estándar de los datos escalados.
prcomp(viviendaCP)
## Standard deviations (1, .., p=7):
## [1] 1.7797614 1.2090195 0.9419689 0.8202791 0.6269531 0.4874831 0.4240851
##
## Rotation (n x k) = (7 x 7):
## PC1 PC2 PC3 PC4 PC5
## estrato 0.3512593 0.46833678 -0.3068292809 0.29034071 -0.48135813
## preciom 0.4929430 0.07012266 -0.2336662548 0.24072929 0.29489564
## areaconst 0.4643260 -0.26159779 0.0005068512 0.07774488 0.60950568
## banios 0.4940936 -0.15772346 0.0639268619 0.04136808 -0.36191286
## habitaciones 0.3177697 -0.52270687 0.3225909371 -0.32691504 -0.39034650
## longitud -0.2440991 -0.48379852 0.0441810429 0.82626087 -0.13670716
## latitud -0.1154772 -0.41850914 -0.8609019084 -0.24579591 -0.08828128
## PC6 PC7
## estrato 0.47036000 0.16090810
## preciom -0.19145817 -0.71827556
## areaconst 0.32468574 0.48270638
## banios -0.68625610 0.35109616
## habitaciones 0.40378915 -0.31534986
## longitud 0.05033633 -0.02174968
## latitud -0.01255184 0.04467948
# fviz_eig(pca_result)
res.pca <- prcomp(viviendaCP)
fviz_eig(res.pca, addlabels = TRUE)
Con base en el gráfico precedente, se observa que el primer componente principal captura el 44,5 % de la varianza total del conjunto de datos, seguido por el segundo componente con un 21,3 %. El tercer y cuarto componentes aportan un 12,6 % y un 9,4 %, respectivamente. En consecuencia, se consideran estos cuatro componentes para el análisis, dado que en conjunto explican aproximadamente el 90 % de la variabilidad total, valor que se reconoce como umbral recomendado en estudios basados en análisis de componentes principales (ACP).
g1 <- fviz_contrib(res.pca, choice = "var", axes = 1, top = 10) +
ggtitle("Contribución de Variables - Dim 1")
g2 <- fviz_contrib(res.pca, choice = "var", axes = 2, top = 10) +
ggtitle("Contribución de Variables - Dim 2")
g3 <- fviz_contrib(res.pca, choice = "var", axes = 3, top = 10) +
ggtitle("Contribución de Variables - Dim 3")
g4 <- fviz_contrib(res.pca, choice = "var", axes = 4, top = 10) +
ggtitle("Contribución de Variables - Dim 4")
plot_grid(g1, g2, g3, g4, ncol = 2, labels = NULL)
ggsave("contribuciones.png", width = 10, height = 8)
Dimensiones 3 y 4 están prácticamente controladas por coordenadas geográficas, por lo que si tu objetivo es analizar características físicas y de valor de las viviendas, podrías considerar trabajar solo con Dim 1 y Dim 2 para análisis exploratorios.
Las variables baños, preciom, areaconst, estrato son las que más aportan a la variabilidad inicial (Dim 1).
numericas <- vivienda3 %>%
select(estrato, preciom, areaconst, banios, habitaciones) %>%
mutate(across(everything(), ~ as.numeric(as.character(.)))) %>%
na.omit()
variabilidad <- apply(numericas, 2, sd, na.rm = TRUE)
numericas <- numericas[, variabilidad > 0]
numericas_scaled <- scale(numericas)
pca_result <- PCA(numericas, scale.unit = TRUE, graph = FALSE)
fviz_pca_ind(pca_result, repel = TRUE)
La mayoría de los datos están concentrados en un rango entre -3 y 6 en Dim 1, y de -6 a 2 en Dim 2.
Hay grupos visibles en forma de nubes y algunos puntos más alejados que podrían ser outliers.
La separación parece más clara en Dim 1 que en Dim 2, lo que sugiere que Dim 1 está capturando la principal diferencia entre los registros.
fviz_pca_var(pca_result, col.var = "contrib")
Dim1 es básicamente un eje de tamaño/precio.
Dim2 es un eje que opone estrato a número de habitaciones.
Con el 83.4% de varianza explicada entre las dos dimensiones, este PCA es bastante representativo.
g1 <- fviz_pca_var(pca_result, axes = c(1, 2), col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE) +
ggtitle("PCA - Dim 1 vs Dim 2") +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(face = "bold", hjust = 0.5))
g2 <- fviz_pca_var(pca_result, axes = c(3, 4), col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE) +
ggtitle("PCA - Dim 3 vs Dim 4") +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(face = "bold", hjust = 0.5))
plot_grid(g1, g2, ncol = 2)
ggsave("pca_var_2.png", width = 12, height = 6)
Dim1 y Dim2 contienen la información más importante y reflejan los patrones dominantes (tamaño/precio vs estrato/habitaciones).
Dim3 y Dim4 son útiles si se quiere investigar variaciones residuales, pero su peso es bajo.
# Determinar número óptimo de clusters
vivienda_clustering <- vivienda %>%
select(estrato, preciom, areaconst, banios, habitaciones) %>%
na.omit()
# Escalar
numericas_scaled <- scale(vivienda_clustering)
# Determinar número óptimo de clusters
fviz_nbclust(numericas_scaled, kmeans, method = "wss")
# Ajustar K-means
set.seed(123)
kmeans_result <- kmeans(numericas_scaled, centers = 4, nstart = 25)
# Añadir cluster al dataset filtrado
vivienda_clustering$cluster <- as.factor(kmeans_result$cluster)
# Visualizar clusters
fviz_cluster(kmeans_result, data = numericas_scaled)
#fviz_nbclust(numericas_scaled, kmeans, method = "wss")
#set.seed(123)
#kmeans_result <- kmeans(numericas_scaled, centers = 4, nstart = 25)
#vivienda_clustering <- vivienda[complete.cases(vivienda[c("estrato", "preciom", "areaconst", "banios", "habitaciones")]), ]
#vivienda_clustering$cluster <- as.factor(kmeans_result$cluster)
#fviz_cluster(kmeans_result, data = numericas_scaled)
Los grupos están bien definidos, pero Clúster 2 y 3 se solapan parcialmente, lo que indica que tienen características similares en algunas variables.
tabla_corresp <- table(vivienda$zona, vivienda$tipo, vivienda$barrio)
tabla_agrupada <- apply(tabla_corresp, c(1, 2), sum)
print(tabla_agrupada)
##
## Apartamento Casa
## Zona Centro 24 100
## Zona Norte 1198 722
## Zona Oeste 1029 169
## Zona Oriente 62 289
## Zona Sur 2787 1939
chisq_test <- chisq.test(tabla_agrupada)
print(chisq_test)
##
## Pearson's Chi-squared test
##
## data: tabla_agrupada
## X-squared = 690.93, df = 4, p-value < 2.2e-16
ac_result <- CA(tabla_agrupada, graph = TRUE)
El Sur concentra la mayor cantidad de viviendas (tanto apartamentos como casas).
El Centro es el sector con menos propiedades registradas.
El Oeste tiene una alta proporción de apartamentos en comparación con casas.
El análisis de correspondencias se usa para analizar y representar visualmente la estructura de datos categóricos en tablas de contingencia, facilitando la comprensión de relaciones y asociaciones entre las categorías.
El análisis de correspondencias se usa principalmente para explorar y visualizar relaciones entre variables categóricas en tablas de contingencia. Es una técnica estadística que ayuda a identificar patrones, asociaciones o estructuras ocultas entre las categorías de dos o más variables cualitativas.
Se crea una tabla de contingencia con las variables categóricas zona y estrato del dataset vivienda
tabla <- table(vivienda$zona, vivienda$estrato)
tabla
##
## 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
Se realiza la prueba de independencia de chi-cuadrado sobre la tabla de contingencia
chisq.test(tabla)
##
## Pearson's Chi-squared test
##
## data: tabla
## X-squared = 3830.4, df = 12, p-value < 2.2e-16
Su finalidad es saber si las diferencias en las frecuencias observadas entre categorías son mayores a lo que se esperaría por azar, indicando una posible relación entre las variables.
Se observa lo siguiente:
X-squared = 3830.4, Este es el estadístico chi-cuadrado calculado a partir de los datos. Mientras más grande, mayor es la diferencia entre las frecuencias observadas y las esperadas bajo la hipótesis de independencia.
df = 12, Los grados de libertad, que dependen del tamaño de la tabla (número de filas y columnas). En este caso indica la complejidad del test.
p-value < 2.2e-16, Es el valor p, que indica la probabilidad de obtener un estadístico tan extremo como el observado, asumiendo que la hipótesis nula es cierta.
Entonces: La hipótesis nula (H0) es que las variables en la tabla (zona y estrato probablemente) son independientes, es decir, no están asociadas.
La hipótesis alternativa (H1) es que sí existe alguna asociación o dependencia entre las variables.
Se puede concluir que hay evidencia estadística muy fuerte para afirmar que existe una asociación significativa entre las variables categóricas de tu tabla. En otras palabras, zona y estrato no son independientes: la distribución del estrato depende de la zona o viceversa
resultados_ac <- CA(tabla, graph = FALSE)
graf_filas <- fviz_ca_row(resultados_ac,
repel = TRUE,
col.row = "blue",
title = "Correspondencia - Filas")
graf_columnas <- fviz_ca_col(resultados_ac,
repel = TRUE,
col.col = "red",
title = "Correspondencia - Columnas")
grid.arrange(graf_filas, graf_columnas, ncol = 2)
Grafica 1 (izquierda) Se puede identificar que las zonas Oeste, Oriente
y Centro están en la parte derecha superior, agrupadas y relativamente
cerca, indicando que tienen patrones similares en la distribución de
estratos.
Las zonas Norte y Sur están más separadas, en la parte inferior izquierda, mostrando que su perfil de estratos es diferente al grupo anterior.
Grafica 2 (derecha)
Los números representan categorías de estrato (por ejemplo, 3, 4, 5, 6).
Estratos 3 y 6 están en la parte derecha, mientras que 4 y 5 están en la parte izquierda inferior.
Esto sugiere que estratos 3 y 6 están relacionados con zonas que aparecen en esa misma área (por ejemplo, Centro, Oriente y Oeste).
Estratos 4 y 5 se relacionan más con zonas Norte y Sur.
Se evidencia que hay una asociación clara entre las zonas geográficas y los estratos socioeconómicos. Ademas, las zonas como Centro, Oriente y Oeste están relacionadas con estratos 3 y 6, las zonas Norte y Sur tienen mayor asociación con estratos 4 y 5.
La distancia entre puntos indica la fuerza de la asociación: más cercanos, más relacionados.
fviz_screeplot(resultados_ac, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
Con solo los dos primeros ejes ya se explica casi el 98% de la varianza total, lo cual es muy bueno y significa que puedes representar los datos con poca pérdida de información usando solo esos dos ejes para análisis y visualización.
El tercer eje prácticamente no aporta información relevante y probablemente pueda ser ignorado para fines interpretativos.
Este tipo de gráfica es útil para decidir cuántas dimensiones incluir en el análisis sin perder mucha información.
#Transformación las variables numérica en una variable categórica ordinal que agrupa los datos en rangos
q1 <- quantile(vivienda3$preciom, c(0.25), type = 6)
q2 <- quantile(vivienda3$preciom, c(0.50), type = 6)
q3 <- quantile(vivienda3$preciom, c(0.75), type = 6)
datacorresp <- vivienda3 %>% mutate(value = ifelse(preciom <= q1, "Bajo", ifelse(preciom <= q2,"Medio Bajo",ifelse(preciom <= q3,"Medio alto","Alto"))))
tabla2 <- table(datacorresp$zona, datacorresp$value)
chisq.test(tabla2)
##
## Pearson's Chi-squared test
##
## data: tabla2
## X-squared = 787.36, df = 12, p-value < 2.2e-16
resultados_ac2 <- CA(tabla2, graph = FALSE)
graf_filas <- fviz_ca_row(resultados_ac2,
repel = TRUE,
col.row = "blue",
title = "Correspondencia - Filas")
graf_columnas <- fviz_ca_col(resultados_ac2,
repel = TRUE,
col.col = "red",
title = "Correspondencia - Columnas")
grid.arrange(graf_filas, graf_columnas, ncol = 2)
El eje Dim1 explica el 90.2% de la variabilidad en los datos.
El eje Dim2 explica un 8% adicional.
Juntos, estos dos ejes resumen el 98.2% de la información, lo cual es muy alto, así que podemos confiar en esta representación bidimensional para entender la relación entre categorías.
#Observaciones:
“Zona Norte” y “Bajo” están cerca en el espacio, lo que indica que en la zona norte es más común que los precios sean bajos.
“Zona Oeste” está muy cerca de “Alto”, indicando que en esa zona los precios tienden a ser altos.
“Zona Sur” está alejada de los niveles bajos y medios, pero relativamente cerca de “Medio Bajo
Conclusiones Generales del Análisis El estudio identificó que las variables más determinantes en el comportamiento del mercado inmobiliario son precio, número de habitaciones, número de baños, área construida y zona. El Análisis de Componentes Principales (ACP) evidenció que estas características no se distribuyen de manera uniforme entre las zonas, existiendo agrupaciones naturales de propiedades que reflejan diferencias claras en oferta y demanda según la ubicación.
Mediante el Análisis de Clústeres se determinó que la segmentación óptima del mercado se logra en tres o cuatro grupos homogéneos con perfiles bien diferenciados:
Segmento Premium: propiedades amplias, con múltiples parqueaderos, ubicadas en zonas exclusivas.
Segmento Familiar: viviendas de tamaño equilibrado en barrios residenciales consolidados.
Segmento Compacto: apartamentos pequeños o estudios en zonas densamente urbanizadas.
Segmento Económico: propiedades de menor precio por metro cuadrado en áreas periféricas.
El Análisis de Correspondencia confirmó asociaciones relevantes entre zona, precio y estrato, variables que explican un alto porcentaje de la varianza y permiten comprender cómo la oferta responde a factores socioeconómicos y de desarrollo urbano.
Implicaciones Estratégicas Para inversionistas: focalizar capital en zonas donde la demanda esté alineada con el tipo de propiedad ofertada, aprovechando oportunidades de valorización en sectores emergentes.
Para desarrolladores: diseñar proyectos ajustados a las necesidades de cada segmento y zona, priorizando áreas con desajustes entre oferta y demanda.
Para agentes inmobiliarios: implementar estrategias de marketing geolocalizadas y personalizadas, potenciando la atracción de compradores mediante atributos clave para cada público objetivo.
En conjunto, la aplicación de ACP, clustering y análisis de correspondencia proporciona una base sólida para optimizar precios, orientar inversiones y desarrollar estrategias comerciales más efectivas en el mercado inmobiliario.