Una empresa inmobiliaria líder en una gran ciudad está buscando comprender en profundidad el mercado de viviendas urbanas para tomar decisiones estratégicas más informadas. La empresa posee una base de datos extensa que contiene información detallada sobre diversas propiedades residenciales disponibles en el mercado.
Se requiere realizar un análisis holístico de estos datos para identificar patrones, relaciones y segmentaciones relevantes que permitan mejorar la toma de decisiones en cuanto a la compra, venta y valoración de propiedades.El reto principal consiste en realizar un análisis integral y multidimensional de la base de datos para obtener una comprensión del mercado inmobiliario urbano.
El insumo obtenido como fuente de información para el presente análisis cuenta con una base de datos de 8.322 registros, representados en 13 distintas columnas (variables), 8 de las cuales son de tipo cuantitativo, mientras las restantes tienen aspecto de calidad. Los datos que soportan los cálculos se pueden encontrar en la siguiente ubicación
De las variables que componen la base de datos, estas son sus principales características:
## 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>
## preciom id zona estrato areaconst banios habitaciones tipo barrio longitud
## 4808 1 1 1 1 1 1 1 1 1 1
## 1909 1 1 1 1 1 1 1 1 1 1
## 876 1 1 1 1 1 1 1 1 1 1
## 726 1 1 1 1 1 1 1 1 1 1
## 1 1 0 0 0 0 0 0 0 0 0
## 2 0 0 0 0 0 0 0 0 0 0
## 2 3 3 3 3 3 3 3 3 3
## latitud parqueaderos piso
## 4808 1 1 1 0
## 1909 1 1 0 1
## 876 1 0 1 1
## 726 1 0 0 2
## 1 0 0 0 12
## 2 0 0 0 13
## 3 1605 2638 4275
library(ggplot2)
# Gráfico de dispersión entre 'areaconst' y 'preciom' con color arcoíris
ggplot(vivienda, aes(x = areaconst, y = preciom, color = areaconst)) +
geom_point() +
scale_color_gradient(low = "blue", high = "red") +
ggtitle("Relación entre área construida y precio")
#install.packages("tidyverse")
library(tidyverse)
# Se calcula el porcentaje de valores NA para cada variable
porcentaje_na <- map_dfr(names(vivienda), ~ {
data.frame(variable = .x, porcentaje_na = round((sum(is.na(vivienda[[.x]])) / length(vivienda[[.x]])) * 100, 2))
})
# Ordenar variables por porcentaje de NAs de mayor a menor
porcentaje_na <- porcentaje_na %>%
arrange(desc(porcentaje_na))
# Diagrama
ggplot(porcentaje_na, aes(x = reorder(variable, porcentaje_na), y = porcentaje_na, fill = variable)) +
geom_bar(stat = "identity") +
labs(title = "Porcentaje de NA's en la base de datos vivienda",
x = "Variable",
y = "% NA's",
fill = "Variable") +
theme(legend.position = "bottom")
## variable porcentaje_na
## 1 piso 31.70
## 2 parqueaderos 19.29
## 3 id 0.04
## 4 zona 0.04
## 5 estrato 0.04
## 6 areaconst 0.04
## 7 banios 0.04
## 8 habitaciones 0.04
## 9 tipo 0.04
## 10 barrio 0.04
## 11 longitud 0.04
## 12 latitud 0.04
## 13 preciom 0.02
En análisis de datos faltantes nos muestra que existe un alto porcentaje de data que deba ser reemplazada o eliminada para las variables piso y parqueaderos. Por tal motivo, se requiere una depuración de la data en la base de trabajo. Información detallada de clasificación por variables se encuentra en pestaña de análisis
## [1] "id" "zona" "piso" "estrato" "preciom"
## [6] "areaconst" "parqueaderos" "banios" "habitaciones" "tipo"
## [11] "barrio" "longitud" "latitud"
# Eliminando las columnas 'id', 'piso', 'barrio' y 'parqueaderos' usando subset()
vivienda2 <- subset(vivienda, select = -c(id, piso, barrio, parqueaderos))
# Eliminando filas con valores faltantes
vivienda2 <- vivienda2[complete.cases(vivienda2), ]
# Conteo de valores faltantes
sum(is.na(vivienda2))
## [1] 0
Inicialmente se eliminan las variables determinadas en el análisis previo, las cuales, al tener un número significativo de datos faltantes, alteran el correcto análisis de la información. En ese sentido, se eliminan las variables, al igual que los registros con valores faltantes. Posterior a eso, se procede a modificar el tipo de variable zona y tipo, intentando buscar valores numéricos que permitan trabajar el análisis de componentes principales
# Convertir la variable 'zona' a factor con etiquetas numéricas
vivienda2$zona <- factor(vivienda2$zona,
levels = c("Zona Centro", "Zona Norte", "Zona Oeste", "Zona Oriente", "Zona Sur"),
labels = c(1, 2, 3, 4, 5))
# Convertir la variable 'tipo' a factor con etiquetas numéricas
vivienda2$tipo <- factor(vivienda2$tipo,
levels = c("Casa", "Apartamento"),
labels = c(1, 2))
head(vivienda2, 10)
Partiendo de la base procesada en la fase previa del presente documento, se dará paso a la construcción de algunos cálculos y gráficos estadísticos adicionales, que permitan inferir algunos resultados y conclusiones de los datos obtenidos en el análisis
#Histogramas
#Configurar el diseño del gráfico
par(mfrow = c(3, 2)) # 3 filas y 2 columnas para 6 histogramas
#Histogramas de frecuencia para la variable estrato
hist(vivienda2$estrato, main = "Estratos", xlab = "estrato", ylab = "Nivel socioeconómico",col = "blue")
#Histogramas de frecuencia para la variable preciom
hist(vivienda2$preciom, main = "Precios", xlab = "preciom", ylab = "Precio(mt2)",col = "red")
#Histogramas de frecuencia para la variable areaconst
hist(vivienda2$areaconst, main = "Área_construida", xlab = "areaconst", ylab = "Area construida (mt2)",col = "blue")
#Histogramas de frecuencia para la variable baños
hist(vivienda2$banios, main = "Baños", xlab = "banios", ylab = "Número de baños",col = "red")
#Histogramas de frecuencia para la variable habitaciones
hist(vivienda2$habitaciones, main = "Habitaciones", xlab = "habitaciones", ylab = "Número de habitaciones",col = "blue")
Reducir la dimensionalidad del conjunto de datos y visualizar la estructura de las variables en componentes principales para identificar características clave que influyen en la variación de precios y oferta del mercado.
Se realizará el análisis con las variables estrato, preciom, areconst, banios y habitaciones
#str(vivienda2)
#vivienda3 <- vivienda2[1:8319,1:7]
#apply(X = vivienda2, MARGIN = 2, FUN = var)
#pca <- prcomp(vivienda3, scale = TRUE)
#Se convierte la columna piso en numérica
#vivienda3$piso <- as.numeric(vivienda3$piso)
#Al no poder convertir la variable piso a numérica, se mantiene por fuera del análisis
vivienda3 <- vivienda2[1:8319,2:6]
apply(X = vivienda2, MARGIN = 2, FUN = var)
## zona estrato preciom areaconst banios habitaciones
## 1.762895e+00 1.059298e+00 1.080207e+05 2.043874e+04 2.039784e+00 2.130248e+00
## tipo longitud latitud
## 2.372472e-01 3.026997e-04 1.818039e-03
library(factoextra)
fviz_pca_ind(pca, geom.ind = "point",
col.ind = "blue",
axes = c(1, 2),
pointsize = 1.5)
En este caso el primer componente principal explica el 58.7% de la variabilidad contenida en la base de datos y entre los dos primeros mas del 82% de los datos, lo cual indicaría que con solo una variable (CP1) que se obtiene mediante una combinación lineal de las variables se puede resumir gran parte de la variabilidad que contiene la base de datos
Porcentaje de Varianza Explicada: En PCA, cada componente principal captura una proporción de la varianza total de los datos. Los valores que mencionas (58.7 y 23.8) podrían representar el porcentaje de varianza explicada por las dos primeras componentes principales. Así que, si estos valores se refieren al porcentaje de varianza explicada, la interpretación es la siguiente:
Primera Componente Principal (PC1): Explica el 58.7% de la varianza total en los datos. Esto significa que la primera componente principal captura una cantidad significativa de la variabilidad en los datos, lo cual es importante porque está proporcionando una gran cantidad de información sobre la estructura subyacente de los datos.
Segunda Componente Principal (PC2): Explica el 23.8% de la varianza total. Aunque es menor que el porcentaje explicado por la primera componente, sigue siendo significativa y contribuye de manera importante al modelo general.
Juntas, las dos primeras componentes principales (PC1 y PC2) explican el 82.5% de la varianza total (58.7% + 23.8%). Esto sugiere que estas dos componentes juntas representan una buena parte de la variabilidad en tus datos. En muchos casos, si estas dos primeras componentes explican un alto porcentaje de la varianza (por ejemplo, más del 70-80%), es una señal de que puedes reducir la dimensionalidad de los datos de manera efectiva utilizando solo estas dos componentes. Reducción de Dimensionalidad:
Dado que las dos primeras componentes principales explican una gran proporción de la varianza, podrías considerar usar solo estas dos componentes para visualización o para análisis subsiguientes. Esto facilita la interpretación y la visualización de los datos sin perder mucha información.
Evaluación de la Estructura de los Datos: Las componentes principales ayudan a identificar patrones en los datos. Si estas componentes principales están explicando una gran parte de la varianza, sugiere que los datos tienen una estructura que puede ser capturada eficazmente por un número relativamente pequeño de dimensiones (componentes). 3. Visualización y Aplicación: Visualización:
Se pueden trazar las dos primeras componentes principales en un gráfico de dispersión para observar cómo se distribuyen las observaciones en el espacio de las componentes principales. Esto puede ayudarte a identificar agrupamientos, tendencias o patrones en los datos.
Aplicación en Modelos Posteriores: Se pueden usar las componentes principales como nuevas características para modelos de aprendizaje automático, reduciendo la dimensionalidad del problema mientras preservas la mayor parte de la información relevante.
En resumen, los valores 58.7% y 23.8% indican que las dos primeras componentes principales de tu PCA explican la mayor parte de la variabilidad en tus datos. Juntas, estas componentes proporcionan una representación comprensible y útil de la estructura de tus datos, lo que te permite simplificar el análisis y enfocarte en las dimensiones más significativas.
Agrupar las propiedades residenciales en segmentos homogéneos con características similares para entender las dinámicas de las ofertas específicas en diferentes partes de la ciudad y en diferentes estratos socioeconómicos.
Para realizar el análisis se ejecutan las variables: estrato, preciom, areaconst, banios y habitaciones. Será importante normalizar los datos antes de realizar el análisis de conglomerados, ya que las variables pueden tener diferentes escalas y esto puede afectar los resultados del algoritmo K-Means.
## tibble [8,319 × 9] (S3: tbl_df/tbl/data.frame)
## $ zona : Factor w/ 5 levels "1","2","3","4",..: 4 4 4 5 2 2 2 2 2 2 ...
## $ 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 ...
## $ 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 : Factor w/ 2 levels "1","2": 1 1 1 1 2 2 2 2 1 1 ...
## $ longitud : num [1:8319] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8319] 3.43 3.43 3.44 3.44 3.46 ...
variables_cong <- vivienda2[, c('estrato', 'preciom', 'areaconst', 'banios', 'habitaciones')]
#Normalización de los datos
datos_normales <- scale(variables_cong)
Antes de aplicar el algoritmo K-Means, es necesario determinar el número óptimo de clústeres para agrupar las viviendas. En este caso se utilizó el método del codo (Elbow Method) para encontrar el número óptimo de clústeres que explica la mayor varianza en los datos.
El gráfico de la curva del codo representa la Suma de Cuadrados Internos (WCSS) en función del número de clústeres. La WCSS es una métrica que mide la dispersión interna de los puntos dentro de cada clúster. La idea es identificar el “codo”, es decir, el punto en el cual el aumento en el número de clústeres deja de reducir significativamente la WCSS.
## estrato preciom areaconst banios
## Min. :-1.5872 Min. :-1.1437 Min. :-1.0138 Min. :-2.17847
## 1st Qu.:-0.6156 1st Qu.:-0.6508 1st Qu.:-0.6640 1st Qu.:-0.77812
## Median : 0.3560 Median :-0.3161 Median :-0.3633 Median :-0.07794
## Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.00000
## 3rd Qu.: 0.3560 3rd Qu.: 0.3228 3rd Qu.: 0.3782 3rd Qu.: 0.62224
## Max. : 1.3276 Max. : 4.7620 Max. :10.9822 Max. : 4.82330
## habitaciones
## Min. :-2.4702
## 1st Qu.:-0.4148
## Median :-0.4148
## Mean : 0.0000
## 3rd Qu.: 0.2704
## Max. : 4.3813
#Optimización del número de clústeres
calcular_wcss <- function(data, k_max) {
wcss <- vector("numeric", length = k_max)
for (k in 1:k_max) {
model <- kmeans(data, centers = k, nstart = 10)
wcss[k] <- model$tot.withinss
}
return(wcss)
}
# Aplicamos la función para diferentes números de clústeres
k_max <- 4
wcss_valores <- calcular_wcss(datos_normales, k_max)
# Graficamos la curva del codo para identificar el número óptimo de clústeres
plot(1:k_max, wcss_valores, type = "b", pch = 19, frame = FALSE, xlab = "Número de clústeres", ylab = "Suma de cuadrados internos",col = "blue")
# Definimos el número óptimo de clústeres (para nuestro análisis 4)
num_clusters <- 4
# Aplicamos el algoritmo K-Means
modelo_kmeans <- kmeans(datos_normales, centers = num_clusters, nstart = 10)
# Agregamos los resultados del clustering al conjunto de datos original
vivienda3$cluster <- as.factor(modelo_kmeans$cluster)
# Visualizamos la distribución de las viviendas en cada clúster
table(vivienda3$cluster)
##
## 1 2 3 4
## 2759 3389 998 1173
# Gráfico de barras para mostrar la distribución de viviendas en cada clúster
ggplot(vivienda3, aes(x = factor(cluster))) +
geom_bar() +
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)
# Diagrama de dispersión para la relación entre 'preciom' y 'areaconst'
ggplot(vivienda3, aes(x = preciom, y = estrato, color = factor(cluster))) +
geom_point() +
labs(title = "Relación entre precio y área construida por clúster",
x = "Precio",
y = "Nivel socioeconómico",
color = "Clúster") +
theme_minimal() +
theme(legend.position = "bottom")
# Diagrama de dispersión para la relación entre 'preciom' y 'areaconst'
ggplot(vivienda3, 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 de conglomerados ha sido crucial para enfrentar el desafío que presenta la empresa inmobiliaria. Al examinar en detalle la base de datos de propiedades residenciales, hemos descubierto agrupamientos importantes y patrones que antes estaban ocultos. Estos agrupamientos ofrecen una visión más clara de las dinámicas del mercado de viviendas urbanas, lo que resulta esencial para tomar decisiones estratégicas bien fundamentadas. Mediante el Análisis de Conglomerados, hemos segmentado las propiedades en grupos que presentan similitudes en aspectos como estrato, precio y número de habitaciones.
Este enfoque resalta la importancia de entender cómo las características de las propiedades pueden influir en el mercado y cómo pueden impactar las estrategias de compra, venta y valoración. En resumen, este análisis ayuda a la empresa a hacer decisiones más informadas y proactivas en el competitivo mercado inmobiliario.
Examinar la relación entre las variables categóricas (tipo de vivienda, zona y barrio), para identificar patrones de comportamiento de la oferta en mercado inmobiliario.
Se construye una tabla cruzada con las variables involucradas en el análisis y se organiza tabla con las variables habitaciones y estrato
##
## 3 4 5 6
## 0 21 22 17 6
## 1 10 7 26 16
## 2 140 389 257 140
## 3 681 1101 1400 915
## 4 183 326 580 640
## 5 111 124 255 189
## 6 92 61 114 51
## 7 76 38 44 15
## 8 72 36 25 5
## 9 49 13 14 7
## 10 18 12 18 3
##
## Pearson's Chi-squared test
##
## data: tabla
## X-squared = 769.95, df = 30, p-value < 2.2e-16
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.063013752 68.084215 68.08422
## dim 2 0.025933406 28.020163 96.10438
## dim 3 0.003605502 3.895622 100.00000
# Se crea un gráfico de scree plot con colores personalizados
fviz_screeplot(correspondencia, addlabels = TRUE, ylim = c(0, 80), col = "blue") +
ggtitle("") +
ylab("Porcentaje de varianza explicado") +
xlab("Ejes")
La visualización gráfica que obtuvimos ofrece una visión clave sobre cómo se relacionan las variables de estrato y zona en el mercado inmobiliario. Nos permite detectar patrones importantes, lo que facilita una segmentación más detallada del mercado y una comprensión más profunda de las preferencias de los compradores en distintas áreas geográficas.
Este enfoque estadístico no solo confirma las tendencias que hemos observado visualmente, sino que también proporciona una base sólida para tomar decisiones estratégicas en el sector inmobiliario.
El Análisis de Componentes Principales (ACP) se utiliza para identificar las variables más importantes que afectan la variabilidad en los precios de las viviendas. Hemos encontrado que el primer componente principal (CP1) explica el 58.7% de esta variabilidad, mientras que los dos primeros componentes combinados explican el 82.5%. El gráfico de ACP revela que el CP1 está principalmente relacionado con variables como el estrato, el precio y el área construida.
En el Análisis de Conglomerados, se realiza un análisis de k-means para agrupar las viviendas según las variables relevantes. Se observa una correlación positiva entre el estrato socioeconómico, el precio de la propiedad y el número de conglomerados. El conglomerado 1 está dominado por apartamentos, el conglomerado 3 por casas, y el conglomerado 2 muestra una mezcla más equilibrada de ambos tipos de propiedades.
Para el Análisis de Correlación, calculamos la matriz de correlación para descubrir cómo se relacionan las variables entre sí. Encontramos una fuerte correlación positiva entre el número de habitaciones y baños, así como entre el estrato socioeconómico y el precio de la propiedad. También hay una correlación positiva moderada entre el número de habitaciones y el área construida, y entre el número de baños y el precio de la propiedad.
El Análisis de Correspondencia Múltiple (ACM) se usa para explorar las relaciones entre variables categóricas y numéricas. Descubrimos una asociación significativa entre las variables de zona y estrato. En particular, el estrato 6 suelen tener entre 4 y 5 habitaciones principalmente, mientras que el estrato 4 predominan los inmuebles con dos habitaciones.