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.
data=vivienda
names(vivienda)
## [1] "id" "zona" "piso" "estrato" "preciom"
## [6] "areaconst" "parqueaderos" "banios" "habitaciones" "tipo"
## [11] "barrio" "longitud" "latitud"
No se realizará el análisis sobre las variables id, barrio, longitud y latitud.
data1= data[, c("tipo","zona", "piso", "estrato", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones")]
colSums(is.na(data1))
## tipo zona piso estrato preciom areaconst
## 3 3 2638 3 2 3
## parqueaderos banios habitaciones
## 1605 3 3
#Eliminación de tres filas sin información de la data
data1 <- data1[!is.na(data1$tipo), ]
#Imputación de NA por cero (propiedades sin parqueadero)
data1$parqueaderos[is.na(data1$parqueaderos)] <- 0
#Imputación de NA por uno (propiedades de un piso)
data1$piso[is.na(data1$piso)] <- 1
#Transformar los piso de caracteres (01 a 09) a números (1 al 9)
data1$piso <- ifelse(data1$piso == "01", 1, data1$piso)
data1$piso <- ifelse(data1$piso == "02", 2, data1$piso)
data1$piso <- ifelse(data1$piso == "03", 3, data1$piso)
data1$piso <- ifelse(data1$piso == "04", 4, data1$piso)
data1$piso <- ifelse(data1$piso == "05", 5, data1$piso)
data1$piso <- ifelse(data1$piso == "06", 6, data1$piso)
data1$piso <- ifelse(data1$piso == "07", 7, data1$piso)
data1$piso <- ifelse(data1$piso == "08", 8, data1$piso)
data1$piso <- ifelse(data1$piso == "09", 9, data1$piso)
data1$piso <- as.numeric(data1$piso)
colSums(is.na(data1))
## tipo zona piso estrato preciom areaconst
## 0 0 0 0 0 0
## parqueaderos banios habitaciones
## 0 0 0
summary(data1)
## tipo zona piso estrato
## Length:8319 Length:8319 Min. : 1.000 Min. :3.000
## Class :character Class :character 1st Qu.: 1.000 1st Qu.:4.000
## Mode :character Mode :character Median : 2.000 Median :5.000
## Mean : 2.893 Mean :4.634
## 3rd Qu.: 4.000 3rd Qu.:5.000
## Max. :12.000 Max. :6.000
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 0.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 : 1.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.482 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
## habitaciones
## Min. : 0.000
## 1st Qu.: 3.000
## Median : 3.000
## Mean : 3.605
## 3rd Qu.: 4.000
## Max. :10.000
No existe una correlación alta (0.8) entre las variables, sin embargo se notan ciertos comportamientos de tendencias e las relaciones.
data2= data1[, c("piso", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones")]
#Matriz de correlaciones
corrplot::corrplot.mixed(cor(data2), lower="ellipse", upper="number", order="hclust")
dataZ = scale(data2)
summary(dataZ)
## piso preciom areaconst parqueaderos
## Min. :-0.7523 Min. :-1.1437 Min. :-1.0138 Min. :-1.1920
## 1st Qu.:-0.7523 1st Qu.:-0.6508 1st Qu.:-0.6640 1st Qu.:-0.3876
## Median :-0.3549 Median :-0.3161 Median :-0.3633 Median :-0.3876
## Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
## 3rd Qu.: 0.4398 3rd Qu.: 0.3228 3rd Qu.: 0.3782 3rd Qu.: 0.4169
## Max. : 3.6187 Max. : 4.7620 Max. :10.9822 Max. : 6.8521
## banios habitaciones
## Min. :-2.17847 Min. :-2.4702
## 1st Qu.:-0.77812 1st Qu.:-0.4148
## Median :-0.07794 Median :-0.4148
## Mean : 0.00000 Mean : 0.0000
## 3rd Qu.: 0.62224 3rd Qu.: 0.2704
## Max. : 4.82330 Max. : 4.3813
colSums(is.na(dataZ))
## piso preciom areaconst parqueaderos banios habitaciones
## 0 0 0 0 0 0
El primer componente principal explica el 52.5% de la variabilidad contenida en la base de datos y entre los dos primeros el 71.1% 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.
res.pca = prcomp(dataZ)
fviz_eig(res.pca, addlabels = TRUE)
pcainmo=PCA(dataZ, ncp = 2, graph = FALSE)
fviz_pca_var(pcainmo, col.var = "contrib", gradient.cols = c("blue", "orange"),repel = TRUE) + labs(colour="Contribución")
El primer componente principal está asociado principalmente con la variables Precio, Área y baños, mientras que el segundo componente se puede asociar a la variable Piso, por su parte la variables Habitaciones y Parqueaderos se representan en ambos componentes principales.
pcainmo$var$contrib
## Dim.1 Dim.2
## piso 0.8745164 60.09876452
## preciom 22.4652154 6.81152321
## areaconst 23.4743619 0.73870833
## parqueaderos 16.2054901 13.90902683
## banios 24.3347559 0.02054239
## habitaciones 12.6456603 18.42143472
Las características clave que influyen en la variación de precios de las propiedades son principalmente su área y la cantidad de baños. En menor medida se encuentran la cantidad de parqueaderos y habitaciones.
Detaresumen <- data1 %>%
group_by(estrato) %>%
summarise(piso = mean(piso),preciom = mean(preciom),areaconst = mean(areaconst),
parqueaderos = mean(parqueaderos),banios = mean(banios),habitaciones = mean(habitaciones))
data3= Detaresumen[, c("piso", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones")]
rownames(data3) = c("E3","E4","E5","E6")
## Warning: Setting row names on a tibble is deprecated.
data3Z =scale(data3)
dist_estrato = dist(data3Z, method = "euclidean")
dist_estrato
## E3 E4 E5
## E4 3.126768
## E5 3.284412 1.524669
## E6 5.107045 4.005564 2.642896
# Clúster jerárquico con el método complete
hc_estrato = hclust(dist_estrato, method = 'complete')
# Determinamos a dónde pertenece cada observación
cluster_assigments = cutree(hc_estrato, k = 4)
# asignamos los clusters
data3Z = as.data.frame(data3Z)
assigned_cluster <- data3Z %>% mutate(cluster = as.factor(cluster_assigments))
# gráfico de puntos
ggplot(assigned_cluster, aes(x = preciom, y = areaconst, color = cluster)) +
geom_point(size = 4) +
geom_text(aes(label = cluster), vjust = -.8) + # Agregar etiquetas del clúster
theme_classic()
plot(hc_estrato, cex = 0.6, main = "Dendograma de Estratos", las=1, ylab = "Distancia euclidiana", xlab = "Grupos")
Se calcula que los estratos que más se parecen (menor distancia
euclidiana) son E4 y E5 (d= 1.524669), conformando estos dos estratos un
primer clúster. Ya en el dendograma se valida ese supuesto donde se
observan 3 conglomerados (E4 y E5), (E3) y (E6).
dendograma <- hclust(dist_estrato, method = "average")
grp <- cutree(dendograma, k = 3)
grp
## E3 E4 E5 E6
## 1 2 2 3
barplot(sort(dendograma$height, decreasing = TRUE), horiz = TRUE,
main = "Agregaciones (distancias euclidianas)",
col = "lightblue", ylab = "Nodo", xlab = "Peso", xlim = c(0, 4))
cluster_assigments <- cutree(hc_estrato, k = 3)
sil <- silhouette(cluster_assigments, dist(data3Z))
sil_avg <- mean(sil[,3])
sil_avg
## [1] 0.2338722
El valor más alto del índice de Silhouette se dio al usar tres conglomerados K=3.
Con esto se podría sugerir que las propiedades que están en estrato 4 y 5 pueden tener más característica en común (Piso, Precio, Área, baños, Parqueaderos y Habitaciones) respecto a las propiedades en estrato 3 y 6.
colSums(is.na(data1))
## tipo zona piso estrato preciom areaconst
## 0 0 0 0 0 0
## parqueaderos banios habitaciones
## 0 0 0
tabla = table(data1$zona, data1$estrato)
chisq.test(tabla)
##
## Pearson's Chi-squared test
##
## data: tabla
## X-squared = 3830.4, df = 12, p-value < 2.2e-16
El resultado del análisis indica que se rechaza la hipótesis de independencia de las variables (p-value: 0.0000), un p-valor tan bajo te sugiere que estas dos variables están asociadas de alguna forma (es decir, una puede influir o estar relacionada con la otra).
resultados_ac = CA(tabla, graph = FALSE)
fviz_ca_biplot(resultados_ac, repel = TRUE)
El gráfico nos permite establecer relaciones como:
El estrato 6 se encuentra ubicado en la Zona Oeste
Los estratos 4 y 5 están ubicados principalmente en la Zona Sur y Norte
El estrato 3 está presente en las Zonas Oriente y Centro
valores_prop = resultados_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(resultados_ac, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
Se observa que la primera componente resumen el 70%, mientras que los primeros dos ejes (dim 1 y dim 2) explican un 97.65% de la variabilidad de los datos, lo que significa que son altamente representativos de la estructura general de los datos.
Las características clave que influyen en la variación de precios de las propiedades son principalmente su área y la cantidad de baños. En menor medida se encuentran la cantidad de parqueaderos y habitaciones.
Las propiedades que están en estrato 4 y 5 pueden tener más característica en común (Piso, Precio, Área, baños, Parqueaderos y Habitaciones) respecto a las propiedades en estrato 3 y 6.
El estrato 6 se encuentra ubicado en la Zona Oeste. Los estratos 4 y 5 están ubicados principalmente en la Zona Sur y Norte. El estrato 3 está presente en las Zonas Oriente y Centro.