La empresa inmobiliaria líder busca comprender en profundidad el mercado de viviendas urbanas para tomar decisiones estratégicas más informadas. Con una base de datos extensa que contiene información detallada sobre diversas propiedades residenciales disponibles en el mercado, el objetivo es realizar un análisis integral y multidimensional de estos datos. Este análisis aplicará técnicas avanzadas como el Análisis de Componentes Principales para reducir la dimensionalidad del conjunto de datos y visualizar la estructura de las variables clave, el Análisis de Conglomerados para agrupar propiedades en segmentos homogéneos y entender las dinámicas de oferta en diferentes zonas y estratos socioeconómicos, y el Análisis de Correspondencia para examinar la relación entre variables categóricas y detectar patrones de comportamiento en el mercado.
El informe final presentará los resultados obtenidos, las conclusiones clave y las recomendaciones específicas para guiar las decisiones estratégicas de la empresa. La visualización de los hallazgos a través de gráficos y mapas facilitará la comunicación efectiva a la dirección, proporcionando ventajas competitivas al optimizar la inversión y maximizar los beneficios en un entorno inmobiliario urbano altamente competitivo y en constante cambio.
Para iniciar la exploración de datos, se procede a importar las librerías que serán utilizadas en el análisis.
library(paqueteMETODOS)
library(dplyr)
library(gplots)
library(ggplot2)
library(NbClust)
library(cluster)
library(factoextra)
library(FactoMineR)
library(mice)
library(tidyverse)
library(ggmice)
library(plotly)
library(scales)
library(DescTools)
library(openxlsx)
library(stringi)
Ahora se procede a importar los datos para su análisis.
data(vivienda)
La limpieza de datos es esencial para asegurar resultados coherentes y precisos. Para comenzar, se analizará la cantidad de observaciones y variables en la base de datos actual.
dim(vivienda)
## [1] 8322 13
La base de datos inicial consta de 8330 observaciones y 13 variables. A continuación, se presenta un resumen descriptivo de estas variables.
summary(vivienda)
## 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
El resumen descriptivo ofrece estadísticas clave como mínimo, máximo, primer y tercer cuartil, mediana y promedio para cada variable. Se observan valores nulos en varias variables, lo que afecta la calidad de la base de datos. Por lo tanto, se realizará una limpieza eliminando estas observaciones.
Para llevar a cabo un análisis detallado de los datos nulos o faltantes, se emplea la librería ggmice. Se utiliza el comando plot_pattern para visualizar de manera gráfica la distribución de los datos faltantes en la base de datos.
plot_pattern(vivienda, rotate = TRUE)
Se identificó que existen 2 registros o viviendas con información
completamente vacía, así como 1 registro con solo la variable “preciom”.
Para mejorar la calidad de la base de datos, se procede a eliminar estos
3 registros.
En primer lugar, se removerán las dos filas que no contienen ninguna información, es decir, están completamente vacías.
vivienda_limpia <- vivienda[rowSums(is.na(vivienda)) != ncol(vivienda),]
Posteriormente, se procede a eliminar la tercera fila que contiene únicamente la variable “preciom”.
vivienda_limpia <- vivienda[complete.cases(vivienda$id),]
Después de eliminar los registros con información faltante, se procede a realizar un nuevo análisis de la matriz de valores nulos para asegurar que no queden registros con datos incompletos:
plot_pattern(vivienda_limpia, rotate = TRUE)
Tras la eliminación de los registros con datos vacíos, se observa una
mejora significativa en la calidad de la base de datos. Sin embargo, aún
persisten valores nulos en las variables “parqueadero” y “piso”. Estas
dos columnas conservan un número considerable de casos vacíos, con 1603
y 2638 registros vacíos respectivamente. Aunque se ha reducido el ruido
en la base de datos, es importante tener en cuenta estos valores nulos
al realizar análisis posteriores.
Ahora revisaremos la base de datos para determinar la cantidad de datos vacíos por variable después de realizar los cambios aplicados en los pasos anteriores.
colSums(is.na(vivienda_limpia)) %>%
as.data.frame()
## .
## id 0
## zona 0
## piso 2635
## estrato 0
## preciom 0
## areaconst 0
## parqueaderos 1602
## banios 0
## habitaciones 0
## tipo 0
## barrio 0
## longitud 0
## latitud 0
Tras la limpieza de datos, se observa que las variables ‘piso’ y ‘parqueadero’ contienen 2635 y 1602 registros nulos, respectivamente.
Tras analizar nuestro conjunto de datos, hemos identificado que las variables ‘piso’ y ‘parqueadero’ son las únicas afectadas por valores nulos. Para abordar esta situación y garantizar la integridad de nuestros análisis, proponemos considerar las siguientes alternativas para la imputación de estos datos faltantes:
Antes de optar por alguna de estas opciones, es necesario comprender el contexto y plantearnos por qué estos datos podrían estar vacíos. ¿Cuál podría haber sido la razón?
Algunas posibles razones podrían incluir:
Información no proporcionada por el cliente: En algunos casos, los clientes pueden optar por no proporcionar detalles sobre el piso o el número de espacios de estacionamiento disponibles en la propiedad.
Errores de ingreso de datos: Durante la entrada de datos, es posible que se hayan omitido los detalles del piso o del parqueadero debido a errores humanos o problemas técnicos.
Características de la propiedad: En ciertos tipos de propiedades, como terrenos o locales comerciales, la información sobre el piso o el parqueadero puede no ser relevante o aplicable.
Información incompleta de la fuente de datos: Dependiendo de la fuente de los datos, es posible que la información sobre el piso o el parqueadero no esté disponible o no se haya recopilado adecuadamente.
La presencia de datos nulos en la base sugiere que la información sobre piso o parqueadero puede no ser relevante para ciertas viviendas. Es probable que algunas casas no tengan parqueadero, y en el caso de apartamentos, pueden no haber asignaciones previas de parqueadero. Por lo tanto, se opta por imputar todos los valores nulos con 0.
Para el proceso de reemplazo de los valores nulos por 0 en la variable parqueadero se realiza de la siguiente manera.
vivienda_limpia$parqueaderos[is.na(vivienda_limpia$parqueaderos)] <- 0
Para la variable “piso”, dado que no puede tener un valor de 0 y es una variable cualitativa ordinal, se opta por reemplazar los datos faltantes por la moda. En este caso, la moda sería el piso 2, ya que es el que tiene la mayor frecuencia.
moda_piso <- Mode(vivienda_limpia$piso, na.rm = TRUE)
vivienda_limpia$piso[is.na(vivienda_limpia$piso)] <- moda_piso
Ahora si finalmente observamos la base de datos:
colSums(is.na(vivienda_limpia)) %>%
as.data.frame()
## .
## 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
Se puede observar que ya no existen datos nulos o vacíos en la base de datos.
Asimismo, se eliminarán los atributos “latitud”, “longitud” y id” ya que no aportan valor sustancial al análisis ni al tratamiento de los datos.
# Eliminando las columnas 'id', 'latitud', 'longitud' y usando subset()
vivienda_limpia <- subset(vivienda_limpia, select = -c(id, latitud, longitud))
Por último, se intentará homogeneizar la variable “barrio”. Dado que hay una gran cantidad de barrios diferentes y puede ser difícil encontrar palabras mal tabuladas, se opta por estandarizar el texto para mejorar la calidad de los datos mediante la colocación de minúsculas a todas las palabras y quitar tildes o acentos en las palabras.
vivienda_limpia$barrio <- tolower(vivienda_limpia$barrio)
vivienda_limpia$barrio <- stri_trans_general(vivienda_limpia$barrio, "Latin-ASCII")
Ahora se observa el tipo de dato para cada variable:
str(vivienda_limpia)
## tibble [8,319 × 10] (S3: tbl_df/tbl/data.frame)
## $ zona : chr [1:8319] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8319] "02" "02" "02" "02" ...
## $ estrato : num [1:8319] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8319] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8319] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8319] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8319] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8319] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8319] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8319] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
Se tomarán las variables piso, preciom, areaconst, parqueaderos, banios y habitaciones como variables númericas mientras que el restante son categóricas.
# Se hace la conversión de los tipos de variable
vivienda_limpia$estrato <- as.character(vivienda_limpia$estrato)
vivienda_limpia$piso <- as.numeric(vivienda_limpia$piso)
Se comprueban ahora los tipos de datos en cada variable.
str(vivienda_limpia)
## tibble [8,319 × 10] (S3: tbl_df/tbl/data.frame)
## $ zona : chr [1:8319] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : num [1:8319] 2 2 2 2 1 1 1 1 2 2 ...
## $ estrato : chr [1:8319] "3" "3" "3" "4" ...
## $ preciom : num [1:8319] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8319] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8319] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8319] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8319] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8319] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8319] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
# Revisar la presencia de datos faltantes
md.pattern(vivienda_limpia)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
## zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo
## 8319 1 1 1 1 1 1 1 1 1
## 0 0 0 0 0 0 0 0 0
## barrio
## 8319 1 0
## 0 0
Se puede observar que no hay presencia de datos faltantes.
Con el fin de evitar que las variables que tiene una escala con valores más grandes afecten las estimaciones realizadas (sesgos) se realiza la estandarización de las variables antes de proceder a realizar el proceso de estimación de los componentes principales.
vivienda_limpiaz <- scale(vivienda_limpia[, c(2, 4:8)])
head(vivienda_limpiaz)
## piso preciom areaconst parqueaderos banios habitaciones
## [1,] -0.5231243 -0.5595498 -0.7339949 -0.3875522 -0.07793773 1.6406840
## [2,] -0.5231243 -0.3465670 -0.3842568 -0.3875522 -0.77811479 -0.4147626
## [3,] -0.5231243 -0.2552886 0.3152194 0.4168506 -0.77811479 0.2703863
## [4,] -0.5231243 -0.1031580 0.7349051 1.2212534 1.32241640 -0.4147626
## [5,] -0.9554580 -0.5291236 -0.5940997 -0.3875522 -0.77811479 -0.4147626
## [6,] -0.9554580 -0.5899759 -0.6150839 -0.3875522 -0.07793773 -0.4147626
# Análisis de Componentes Principales (ACP)
res.pca <- prcomp(vivienda_limpiaz)
res.pca
## Standard deviations (1, .., p=6):
## [1] 1.7743132 1.0568347 0.8900421 0.6571610 0.5631703 0.4401325
##
## Rotation (n x k) = (6 x 6):
## PC1 PC2 PC3 PC4 PC5
## piso 0.09587457 -0.77356195 0.611523842 0.07689090 -0.1097488
## preciom -0.47350316 -0.27116085 -0.246784404 0.36737661 0.2449494
## areaconst -0.48440557 0.08240134 -0.001735922 0.53613499 -0.5569970
## parqueaderos -0.40269395 -0.36411698 -0.368792208 -0.68565736 -0.3042894
## banios -0.49316001 0.01309733 0.211350352 -0.08244174 0.6926644
## habitaciones -0.35578765 0.43420158 0.620045459 -0.30782923 -0.2129161
## PC6
## piso -0.02217123
## preciom 0.66813039
## areaconst -0.40108834
## parqueaderos -0.08081254
## banios -0.47473363
## habitaciones 0.40041939
summary(res.pca)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6
## Standard deviation 1.7743 1.0568 0.8900 0.65716 0.56317 0.44013
## Proportion of Variance 0.5247 0.1862 0.1320 0.07198 0.05286 0.03229
## Cumulative Proportion 0.5247 0.7108 0.8429 0.91485 0.96771 1.00000
#Visualizar gráfico
fviz_eig(res.pca, addlabels = TRUE)
En este caso el primer componente principal explica el 52.5% de la variabilidad contenida en la base de datos y entre los dos primeros se explica casi el 72% de los datos (71.1),sin embargo un 30% de la variabilidad quedaría por fuera, por lo tanto se opta por elegir los 3 primeros CPS que en conjunto resumen un 84.29% de la variabilidad de la base.
# Definir los colores personalizados
colores_personalizados <- c("orange", "blue")
# Personalizar el gráfico
fviz_pca_var(res.pca,
col.var = "contrib", # Color by contributions to the PC
gradient.cols = colores_personalizados,
repel = TRUE # Avoid text overlapping
)
Al visualizar las variables en el plano de los componentes principales permite identificar el sentido y la caracterización de los componentes (característica capturada por los vectores propios de Σ). En este ejercicio el primer componente principal está asociado principalmente con la variables habitaciones, areaconst y precio, mientras que el segundo componente se puede asociar a la variable piso y parqueaderos.
Para explicar el sentido de los ejes, se escogen cuatro casos extremos conformados por los siguientes clientes.
datos<- rbind(vivienda_limpia[6000,], # ok
vivienda_limpia[8300,],
vivienda_limpia[2,],
vivienda_limpia[3000,])
datos <- as.data.frame(datos)
rownames(datos) = c("Cliente 6000", "Cliente 8300", "Cliente 2", "Cliente 3000")
datos
## zona piso estrato preciom areaconst parqueaderos banios
## Cliente 6000 Zona Sur 3 5 440 210 2 5
## Cliente 8300 Zona Sur 5 5 240 68 1 2
## Cliente 2 Zona Oriente 2 3 320 120 1 2
## Cliente 3000 Zona Oeste 2 6 550 233 1 2
## habitaciones tipo barrio
## Cliente 6000 5 Casa san joaquin
## Cliente 8300 3 Apartamento zona sur
## Cliente 2 3 Casa 20 de julio
## Cliente 3000 6 Casa el penon
casos1 <- rbind(res.pca$x[6000,1:2],res.pca$x[8300,1:2]) # CP1
rownames(casos1) = c("6000","8300")
casos1 <- as.data.frame(casos1)
casos2 <- rbind(res.pca$x[2,1:2], res.pca$x[3000,1:2]) # CP2
rownames(casos2) = c("2","3000")
casos2 <- as.data.frame(casos2)
# Convertir PC1 y PC2 a nombres de columna en los dataframes
colnames(casos1) <- c("PC1", "PC2")
colnames(casos2) <- c("PC1", "PC2")
# Plot PCA con etiquetas
fviz_pca_ind(res.pca, col.ind = "#DEDEDE", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")) +
geom_point(data = casos1, aes(x = PC1, y = PC2), color = "red", size = 3) +
geom_text(data = casos1, aes(x = PC1, y = PC2, label = rownames(casos1)), color = "red", vjust = -1, size = 3) +
geom_point(data = casos2, aes(x = PC1, y = PC2), color = "blue", size = 3) +
geom_text(data = casos2, aes(x = PC1, y = PC2, label = rownames(casos2)), color = "blue", vjust = -1, size = 3)
Se tomará de nuevo la base normalizada vivienda_limpiaz.
vivienda_limpiaz = as.data.frame(vivienda_limpiaz)
head(vivienda_limpiaz)
## piso preciom areaconst parqueaderos banios habitaciones
## 1 -0.5231243 -0.5595498 -0.7339949 -0.3875522 -0.07793773 1.6406840
## 2 -0.5231243 -0.3465670 -0.3842568 -0.3875522 -0.77811479 -0.4147626
## 3 -0.5231243 -0.2552886 0.3152194 0.4168506 -0.77811479 0.2703863
## 4 -0.5231243 -0.1031580 0.7349051 1.2212534 1.32241640 -0.4147626
## 5 -0.9554580 -0.5291236 -0.5940997 -0.3875522 -0.77811479 -0.4147626
## 6 -0.9554580 -0.5899759 -0.6150839 -0.3875522 -0.07793773 -0.4147626
Ahora se debe determinar el número de clusters a emplear para el análisis, para ello se recurre al metodo del codo y Silhouette.
#Estimar el numero de clusters mediante el metodo wss
fviz_nbclust(vivienda_limpiaz, kmeans, method = "wss")
#### Método de silhouette
#Estimar el numero de clusters mediante el metodo silhouette
fviz_nbclust(vivienda_limpiaz, kmeans, method = "silhouette")
Aunque el método de Silhouette sugiere usar un número de clusters = 2, se opta por usar un número de clusters es 4 basado en la aproximación por el método del codo igualmente y por el método de Silhouette.
# Calculamos los 3 clusters.
num_cluster <- 4
# Aplicar algoritmo K-means
m_kmeans <- kmeans(vivienda_limpiaz, centers = num_cluster, nstart = 25)
# Agregar el resultado del clustering al dataset original
vivienda_limpia$cluster <- as.factor(m_kmeans$cluster)
Se procede a construir una tabla de frecuencias:
table(vivienda_limpia$cluster)
##
## 1 2 3 4
## 1073 2239 4119 888
Ahora se grafican los clusters:
fviz_cluster(m_kmeans, data = vivienda_limpiaz)
fviz_cluster(m_kmeans, data = vivienda_limpiaz, ellipse.type = "norm")
# Paleta de colores personalizada
colores_personalizados <- c("#F67C6D", "#1A7332", "#1C5A99", "#7466C3")
# Gráfico de barras para mostrar la distribución de viviendas en cada clúster
ggplot(vivienda_limpia, aes(x = factor(cluster), fill = factor(cluster))) +
geom_bar() +
scale_fill_manual(values = colores_personalizados) +
labs(title = "Distribución de viviendas en cada clúster",
x = "Clúster",
y = "Cantidad de viviendas") +
theme_minimal() +
geom_text(stat='count', aes(label=..count..), vjust=-0.5)
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Se puede observar que la mayor concentración de viviendas se encuentran
en el cluster 3 con 4119 viviendas, seguido del cluster 2 con 2239,
luego el cluster 3 con 1073 y cluster 4 con 888 viviendas.
# Diagrama de dispersión para la relación entre 'preciom' y 'areaconst'
ggplotly(ggplot(vivienda_limpia, aes(x = preciom, y = areaconst, color = factor(cluster))) +
geom_point() +
labs(title = "Relación entre precio y área construida por clúster",
x = "Precio",
y = "Área construida",
color = "Clúster") +
theme_minimal() +
theme(legend.position = "bottom"))
El análisis realizado revela una clara segmentación en el mercado de viviendas, donde se identifican cuatro clústeres principales. El Clúster 1 agrupa viviendas más pequeñas y económicas, mientras que el Clúster 2 incluye propiedades de tamaño y precio intermedios. Por otro lado, el Clúster 3 representa viviendas más grandes y costosas, abarcando el rango superior tanto en precio como en área construida. Finalmente, el Clúster 4 parece representar un segmento de nicho o atípico, con características particulares. Estos hallazgos proporcionan una base sólida para la toma de decisiones estratégicas en términos de marketing y fijación de precios, al permitir una mejor comprensión de las diferentes subcategorías dentro del mercado de viviendas.
Se empiezan seleccionando solo las variables catégoricas para este análisis:
head(vivienda_limpia)
## # A tibble: 6 × 11
## zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo
## <chr> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Zona O… 2 3 250 70 1 3 6 Casa
## 2 Zona O… 2 3 320 120 1 2 3 Casa
## 3 Zona O… 2 3 350 220 2 2 4 Casa
## 4 Zona S… 2 4 400 280 3 5 3 Casa
## 5 Zona N… 1 5 260 90 1 2 3 Apar…
## 6 Zona N… 1 5 240 87 1 3 3 Apar…
## # ℹ 2 more variables: barrio <chr>, cluster <fct>
vivienda_cat <- table(vivienda_limpia$zona, vivienda_limpia$estrato)
Ahora se realiza la prueba chi.cuadrado de donde luego se construirán las coordenadas que serán representadas en un plano cartesiano para permitir ver la cercania o no entre las categorias de ambas variables.
chisq.test(vivienda_cat)
##
## Pearson's Chi-squared test
##
## data: vivienda_cat
## X-squared = 3830.4, df = 12, p-value < 2.2e-16
El resultado indica que se rechaza la hipótesis de independencia de las variables, indicando un tipo de relación entre ellas.
Finalmente se procede a realizar el análisis de correspondenciaque consiste en estimar las coordenadas para cada uno de los niveles de ambas variables y representarlas en un plano cartesiano:
vivienda_ac <- CA(vivienda_cat, graph = TRUE)
El gráfico nos permite establecer relaciones y validarlas como son: El
estrato 6 se encuentra ubicado en la Zona Oeste. Los estratos 4 y 5
están ubicados principalmente en la Zona Sur. El estrato 3 está presente
en las Zonas Oriente y Centro.
valores_prop <-vivienda_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
fviz_screeplot(vivienda_ac, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
El gráfico muestra que el primer eje explica el 70% de la varianza y el
segundo eje el 27.7%, lo que sugiere que la mayor parte de la
información relevante en los datos está capturada por estos dos ejes,
mientras que el tercer eje aporta muy poco, con solo el 2.4% de la
varianza explicada.
Se empiezan seleccionando de nuevo solo las variables catégoricas para este análisis:
vivienda_cat <- vivienda_limpia[, c("tipo", "zona", "estrato")]
Se realiza ahora el análisis de correspondencia multiple:
resultados_ac <- MCA(vivienda_cat)
El Análisis de Componentes Principales (PCA) muestra que las variables habitaciones, areaconst (área construida) y precio/m2 tienen una fuerte contribución a la primera dimensión (Dim1), que explica el 52.5% de la variabilidad de los datos. Esto indica que estas variables son las más influyentes en la caracterización de las propiedades en el mercado inmobiliario de Cali. Por otro lado, variables como piso y parqueaderos también son importantes, pero tienen una mayor contribución a la segunda dimensión (Dim2), que explica el 18.6% de la variabilidad, sugiriendo que influyen en aspectos diferentes de las propiedades
El scree plot indica que las primeras dos dimensiones explican un total del 71.1% de la variabilidad de los datos. Aunque este porcentaje es considerable, se opta por seleccionar tres componentes principales que, en conjunto, explican el 80% de la variabilidad total. Si bien las dimensiones adicionales (como Dim4 y otras) también aportan información, su contribución es significativamente menor. Al seleccionar tres componentes principales, se logra reducir la dimensionalidad de la base de datos, pasando de 6 variables numéricas a 3 componentes. Esto significa que el total de variables en la base de datos se reduce de 10 a 7, simplificando el análisis sin perder información crucial.
El gráfico de individuos muestra que la mayoría de los datos están concentrados cerca del origen de las dimensiones, lo que sugiere una alta similitud entre muchas propiedades. Sin embargo, hay individuos como los números 6000, 3000, y 8300 que se alejan de esta concentración, lo que podría indicar propiedades con características atípicas o únicas en comparación con el resto del mercado. Estas propiedades pueden representar nichos específicos en el mercado inmobiliario que podrían ser objeto de estrategias diferenciadas.
El gráfico del método del codo sugiere que el número óptimo de clusters se encuentra en torno a 4, ya que después de este punto, la reducción en la suma de cuadrados dentro de los clusters se estabiliza. Esto indica que segmentar el mercado en 4 grupos es una elección razonable, permitiendo capturar diferencias significativas entre los segmentos sin sobrecomplicar el modelo.
La distribución de clusters sugiere que las estrategias de marketing y ventas deben enfocarse principalmente en los clústeres 2 y 3 para capturar la mayor parte del mercado, mientras que los clústeres 1 y 4 podrían requerir estrategias más especializadas para atraer a compradores con necesidades o preferencias específicas.
El análisis revela que el mercado inmobiliario en Cali se segmenta en cuatro clústeres principales, donde las variables de precio, área construida, y número de habitaciones son determinantes. El clúster 4 muestra una diversidad significativa en propiedades, desde opciones más económicas hasta propiedades de lujo, mientras que los clústeres 1 y 2 agrupan propiedades más accesibles en términos de precio y tamaño. Esto sugiere la necesidad de estrategias de precios diferenciadas y enfoques de marketing personalizados para cada segmento, con un énfasis en identificar subsegmentos dentro de los clústeres más diversos para maximizar la efectividad de las estrategias comerciales.
El mapa de factores de Análisis de Correspondencias simple revela que las zonas de Cali están asociadas a diferentes estratos socioeconómicos de manera distintiva. La Zona Oriente y la Zona Centro están claramente vinculadas a estratos número 3, indicando que estas áreas concentran una mayor proporción de viviendas de nivel socioeconómico medio. Por otro lado, la Zona Oeste está más asociada con el estrato 6, lo que sugiere una predominancia de viviendas de alta gama en esta zona. Las Zonas Sur y Norte se agrupan cerca de los estratos 4 y 5, lo que indica una preponderancia de viviendas de nivel socioeconómico medio-alto. Esta segmentación resalta la importancia de adaptar las estrategias de desarrollo y comercialización inmobiliaria según la relación entre zona y estrato, optimizando la oferta para satisfacer las demandas específicas de cada segmento de la población.
El análisis de correspondencias múltiples revela una clara segmentación entre las zonas de Cali, los tipos de vivienda y los estratos socioeconómicos. La Zona Oriente y la Zona Centro están fuertemente asociadas con estratos medios (estrato 3) y el tipo de vivienda “casa”. En contraste, la Zona Oeste está vinculada con el estrato 6 y presenta una preferencia por apartamentos. Las Zonas Sur y Norte se agrupan en torno a los estratos 4 y 5 y parecen estar asociadas principalmente con viviendas tipo apartamento. Esta diferenciación sugiere que cada zona tiene un perfil demográfico y de vivienda distinto, lo que debe ser considerado al planificar estrategias de desarrollo inmobiliario y comercialización. Es esencial alinear la oferta de tipos de vivienda con las características demográficas y socioeconómicas de cada zona para maximizar la relevancia y efectividad de las campañas de marketing.
En clústeres como el 4, donde hay una menor cantidad de viviendas pero una posible diversidad de características, se sugiere explorar subsegmentos más pequeños dentro del clúster. Esta estrategia permite aprovechar nichos específicos del mercado que puedan estar interesados en propiedades con características únicas o diferenciadoras.
Dado el perfil demográfico diferenciado por zona y clúster, las campañas publicitarias deben ser altamente segmentadas. Utiliza los insights de la distribución por clústeres y zonas para dirigir mensajes específicos a cada segmento, resaltando las características de la propiedad que mejor se alineen con las preferencias de ese grupo demográfico.
Los clústeres 2 y 3 concentran la mayoría de las viviendas, lo que indica que representan los segmentos más comunes del mercado inmobiliario de Cali. Las campañas de marketing deben centrarse en estos clústeres, destacando características que son altamente valoradas en estas propiedades, como la relación calidad-precio y la conveniencia de la ubicación.
Las campañas publicitarias en la Zona Oriente y Zona Centro deben resaltar la combinación de calidad y valor, destacando la accesibilidad a servicios y el confort que se ajusta al estilo de vida de los estratos medio y medio-alto. En la Zona Oeste, el enfoque debe estar en la exclusividad y el prestigio, orientando el mensaje a un público de estrato alto.