library(paqueteMODELOS)
library(naniar)
data(vivienda)
datos <- vivienda
#visualizar datos faltantes
print(faltantes <- colSums(is.na(datos)) %>%
as.data.frame())
## .
## id 3
## zona 3
## piso 2638
## estrato 3
## preciom 2
## areaconst 3
## parqueaderos 1605
## banios 3
## habitaciones 3
## tipo 3
## barrio 3
## longitud 3
## latitud 3
gg_miss_var(datos) # Muestra la proporción de datos faltantes por cada variable
#Las variables 'piso' y 'parqueadero' presentan gran cantidad de datos faltantes, por ende, se deciden eliminar estas variables. A su vez, se decide por eliminar las variables 'id' y 'barrio' que no son relevantes en el análisis.
datos <- subset(datos, select = -c(id, piso, parqueaderos, barrio))
# Posteriormente, se eliminan filas con valores faltantes
datos <- datos[complete.cases(datos), ]
# Se visualiza la efectividad de los procesos de eliminación de datos faltantes
print(colSums(is.na(datos)) %>%
as.data.frame())
## .
## zona 0
## estrato 0
## preciom 0
## areaconst 0
## banios 0
## habitaciones 0
## tipo 0
## longitud 0
## latitud 0
print(datos)
## # A tibble: 8,319 × 9
## zona estrato preciom areaconst banios habitaciones tipo longitud latitud
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl>
## 1 Zona Or… 3 250 70 3 6 Casa -76.5 3.43
## 2 Zona Or… 3 320 120 2 3 Casa -76.5 3.43
## 3 Zona Or… 3 350 220 2 4 Casa -76.5 3.44
## 4 Zona Sur 4 400 280 5 3 Casa -76.5 3.44
## 5 Zona No… 5 260 90 2 3 Apar… -76.5 3.46
## 6 Zona No… 5 240 87 3 3 Apar… -76.5 3.37
## 7 Zona No… 4 220 52 2 3 Apar… -76.5 3.43
## 8 Zona No… 5 310 137 3 4 Apar… -76.5 3.38
## 9 Zona No… 5 320 150 4 6 Casa -76.5 3.48
## 10 Zona No… 5 780 380 3 3 Casa -76.5 3.49
## # ℹ 8,309 more rows
Posterior de la eliminación de las columnas ‘id’, ‘piso’, ‘barrio’ y ‘parqueadero’, y las filas con datos faltantes, la base de datos limpia consta de 8319 filas y 9 columnas.Por otra parte, se codifican las columnas categóricas (‘zona’ y ‘tipo’) para transformarlas a categórias numéricas.
library(dplyr)
#Códificación de la variable 'zona'
datos <- datos %>% mutate(zona = replace(zona,
zona == "Zona Centro", 1))
datos <- datos %>% mutate(zona = replace(zona,
zona == "Zona Norte", 2))
datos <- datos %>% mutate(zona = replace(zona,
zona == "Zona Oeste", 3))
datos <- datos %>% mutate(zona = replace(zona,
zona == "Zona Oriente",
4))
datos <- datos %>% mutate(zona = replace(zona,
zona == "Zona Sur", 5))
datos$zona <- as.numeric(datos$zona)
# Codificación de la variable 'tipo'
datos <- datos %>% mutate(tipo = replace(tipo,
tipo == "Casa", 1))
datos <- datos %>% mutate(tipo = replace(tipo,
tipo == "Apartamento", 2))
datos$tipo <- as.numeric(datos$tipo)
# Visualzación de las primeras filas de la tabla
head(datos, 5)
## # A tibble: 5 × 9
## zona estrato preciom areaconst banios habitaciones tipo longitud latitud
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4 3 250 70 3 6 1 -76.5 3.43
## 2 4 3 320 120 2 3 1 -76.5 3.43
## 3 4 3 350 220 2 4 1 -76.5 3.44
## 4 5 4 400 280 5 3 1 -76.5 3.44
## 5 2 5 260 90 2 3 2 -76.5 3.46
Por otra parte, se genera una matriz de correlación para analizar la incidencia entre sí de las variables.
options(repos = c(CRAN = "https://cloud.r-project.org"))
install.packages("psych")
## package 'psych' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\diego\AppData\Local\Temp\RtmpSMjix8\downloaded_packages
install.packages("corrplot")
## package 'corrplot' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\diego\AppData\Local\Temp\RtmpSMjix8\downloaded_packages
library(psych)
library(corrplot)
correlacion <- cor(datos, use = "complete.obs")
corrplot(correlacion, method = "number", col = colorRampPalette(c("purple", "yellow"))(200))
A partir de la matriz de correlacción es apreciable que a medida que el estrato de la vivienda aumenta, también lo hace el precio. Se observa una relación positiva entre el precio de la vivienda y el área construida. Las viviendas con un área mayor tienden a incrementar su precio. Asimismo, las viviendas con mayor cantidad de baños tienden a ser más costosas.
#Se Selecciona el subconjunto de variables a escalar
vivienda_z <- datos[, 2:6] %>%
scale()
# Se presentan los primeros registros
head(vivienda_z)
## estrato preciom areaconst banios habitaciones
## [1,] -1.5872276 -0.5595498 -0.7339949 -0.07793773 1.6406840
## [2,] -1.5872276 -0.3465670 -0.3842568 -0.77811479 -0.4147626
## [3,] -1.5872276 -0.2552886 0.3152194 -0.77811479 0.2703863
## [4,] -0.6156201 -0.1031580 0.7349051 1.32241640 -0.4147626
## [5,] 0.3559875 -0.5291236 -0.5940997 -0.77811479 -0.4147626
## [6,] 0.3559875 -0.5899759 -0.6150839 -0.07793773 -0.4147626
# Se realiza el Análisis de Componentes Principales
prcomp(vivienda_z)
## Standard deviations (1, .., p=5):
## [1] 1.7126464 1.0901014 0.6673458 0.4916079 0.4375986
##
## Rotation (n x k) = (5 x 5):
## PC1 PC2 PC3 PC4 PC5
## estrato 0.3300032 -0.6744363 0.4208934 -0.4795545 0.1706159
## preciom 0.5068715 -0.2807656 -0.3015468 0.2213868 -0.7240921
## areaconst 0.4940473 0.1638135 -0.6525373 -0.2984641 0.4628138
## banios 0.5189619 0.1092831 0.3767649 0.6647648 0.3672488
## habitaciones 0.3475270 0.6538568 0.4051685 -0.4359154 -0.3122700
Se revisará el número de componentes principales
library(factoextra)
# Realizar ACP y visualizar el gráfico
res.pca <- prcomp(vivienda_z)
fviz_eig(res.pca, addlabels = TRUE)
Es preciso observar que el primer componente principal explica el 58.7% de la variabilidad total y los dos primeros componentes principales explican en conjunto el 82.5% de la variabilidad total.,La primera componente principal supera la mitad de la variabilidad total.
# Visualización del gráfico
fviz_pca_var(res.pca,
col.var = "contrib",
gradient.cols = c("#FF7F00", "#034D94"),
repel = TRUE,)
A partir del gráfico se aprecia que las variables que están sobre el primer cuadrante corresponden a características asociadas a la infraestructura de la vivienda, mientras que las variables en el cuarto cuadrante corresponden a variables de valorización del inmueble. Posteriormente, se crean dos representaciones gráficas para determinar qué componentes tienen un impacto en las direcciones de la primera y segunda componente.
# Contribuciones en las componentes
fviz_contrib(res.pca, choice = "var", axes = 1, top = 10)
fviz_contrib(res.pca, choice = "var", axes = 2, top = 10)
get_pca_var(res.pca)$contrib[,1:2]
## Dim.1 Dim.2
## estrato 10.89021 45.486434
## preciom 25.69187 7.882934
## areaconst 24.40828 2.683486
## banios 26.93215 1.194279
## habitaciones 12.07750 42.752867
Se aprecia que la cantidad de baños es la característica que influye en la primera componente, junto con el precio de vivienda y el área construida. Por otro lado, en la segunda componente, son el estrato y la cantidad de habitaciones las que presentan mayor influencia.
# Se toman las siguientes variables: estrato, preciom, areacons, banios y habitaciones
vivienda_2 <- datos[2:6]
vivienda_2_est <- scale(vivienda_2)
vivienda_2_est <- as.data.frame(vivienda_2_est)
head(vivienda_2_est,5)
## estrato preciom areaconst banios habitaciones
## 1 -1.5872276 -0.5595498 -0.7339949 -0.07793773 1.6406840
## 2 -1.5872276 -0.3465670 -0.3842568 -0.77811479 -0.4147626
## 3 -1.5872276 -0.2552886 0.3152194 -0.77811479 0.2703863
## 4 -0.6156201 -0.1031580 0.7349051 1.32241640 -0.4147626
## 5 0.3559875 -0.5291236 -0.5940997 -0.77811479 -0.4147626
set.seed(0)
# Agrupamiento
modelo_kmeans <- kmeans(vivienda_2_est, 3)
vivienda_2_est <- data.frame(vivienda_2_est,
modelo_kmeans$cluster)
aggregate(vivienda_2,
by = list(vivienda_2_est$modelo_kmeans.cluster),
FUN = median)
## Group.1 estrato preciom areaconst banios habitaciones
## 1 1 4 185 75 2 3
## 2 2 5 780 324 5 5
## 3 3 5 370 118 3 3
# Distribución de datos por cluster
table(vivienda_2_est$modelo_kmeans.cluster)
##
## 1 2 3
## 3035 1873 3411
fviz_cluster(list(data = vivienda_2_est[,1:5],
cluster = vivienda_2_est$modelo_kmeans.cluster),
palette = c("#FF7F00", "#034D94", "#9d008c"),
ellipse.type = "convex",repel = F,
show.clust.cent = FALSE, ggtheme = theme_minimal())
Se presenta un análisis con un modelo de agrupamiento no jerárquico y con base a los resultado de las medianas se puede decir que el primer cluster se distingue por relacionar viviendas con precios, áreas y estratos más bajos. Por el contrario, las viviendas vinculadas al segundo cluster son aquellas con los precios y áreas más altos. La característica resaltada en el cluster 3 es que abarca viviendas con un estrato 5. A pesar de que las propiedades no tienen un área extensa, el precio es el doble al de las viviendas del primer cluster.
# Se emplea un método jerárquico de agrupación.
# con el objetivo de seleccionar el número adecuado de clusters se emplea el coeficiente de Silhouette
#El valor indicado para k es el más cercano a 1
set.seed(0)
dist_eu <- dist(vivienda_2_est[,1:6],method = "euclidean")
modelo_jer <- hclust(dist_eu, method = "ward.D")
library(tidyverse)
library(cluster)
cluster_assigments_k2 <- cutree(modelo_jer, k = 2) # Cluster
sil_1_k2 <- silhouette(cluster_assigments_k2, dist(vivienda_2_est[,1:6]))
sil_1_avg_k2 <- mean(sil_1_k2[,3])
cat("Coeficiente de Silhouette promedio k=2 : ", sil_1_avg_k2)
## Coeficiente de Silhouette promedio k=2 : 0.3649906
cluster_assigments_k3 <- cutree(modelo_jer, k = 3) # Cluster
sil_1_k3 <- silhouette(cluster_assigments_k3, dist(vivienda_2_est[,1:6]))
sil_1_avg_k3 <- mean(sil_1_k3[,3])
cat("Coeficiente de Silhouette promedio k=3 : ", sil_1_avg_k3)
## Coeficiente de Silhouette promedio k=3 : 0.429883
cluster_assigments_k4 <- cutree(modelo_jer, k = 4) # Cluster
sil_1_k4 <- silhouette(cluster_assigments_k4, dist(vivienda_2_est[,1:6]))
sil_1_avg_k4 <- mean(sil_1_k4[,3])
cat("Coeficiente de Silhouette promedio k=4 : ", sil_1_avg_k4)
## Coeficiente de Silhouette promedio k=4 : 0.4453488
cluster_assigments_k5 <- cutree(modelo_jer, k = 5) # Cluster
sil_1_k5 <- silhouette(cluster_assigments_k5, dist(vivienda_2_est[,1:6]))
sil_1_avg_k5 <- mean(sil_1_k5[,3])
cat("Coeficiente de Silhouette promedio k=5 : ", sil_1_avg_k5)
## Coeficiente de Silhouette promedio k=5 : 0.3105849
cluster_assigments_k6 <- cutree(modelo_jer, k = 6) # Cluster
sil_1_k6 <- silhouette(cluster_assigments_k6, dist(vivienda_2_est[,1:6]))
sil_1_avg_k6 <- mean(sil_1_k6[,3])
cat("Coeficiente de Silhouette promedio k=6 : ", sil_1_avg_k6)
## Coeficiente de Silhouette promedio k=6 : 0.2480993
cluster_assigments_k7 <- cutree(modelo_jer, k = 7) # Cluster
sil_1_k7 <- silhouette(cluster_assigments_k7, dist(vivienda_2_est[,1:6]))
sil_1_avg_k7 <- mean(sil_1_k7[,3])
cat("Coeficiente de Silhouette promedio k=7 : ", sil_1_avg_k7)
## Coeficiente de Silhouette promedio k=7 : 0.2625557
cluster_jer <- cutree(modelo_jer, k = 4)
vivienda_2_est <- data.frame(vivienda_2_est,cluster_jer)
table(vivienda_2_est$cluster_jer)
##
## 1 2 3 4
## 2976 3394 942 1007
aggregate(vivienda_2,
by = list(vivienda_2_est$cluster_jer),
FUN = median)
## Group.1 estrato preciom areaconst banios habitaciones
## 1 1 4.0 180 75.00 2 3
## 2 2 5.0 366 118.00 3 3
## 3 3 4.5 500 316.39 5 6
## 4 4 6.0 1100 322.42 5 4
fviz_cluster(list(data = vivienda_2_est[,1:5],
cluster = vivienda_2_est$cluster_jer),
palette = c("#2E9FDF", "#E7B800", "#9d008c", "#0e9d00"),
ellipse.type = "convex",repel = F,
show.clust.cent = FALSE, ggtheme = theme_minimal())
Estos resultados indican una mejor agrupación cuando se eligen k con 4 conglomerados, ya que valores más cercanos a 1 indican un agrupamiento más coherente.
A partir de los valores de las medianas para cada grupo se observa que en el primer cluster el precio es relativamente bajo y las viviendas son más pequeñas. Para el segundo grupo el precio es un poco mayor y las viviendas tienen un tamaño de 118. El cluster 3 el precio incrementa a 500 y las viviendas tienen una extensión de 316.39. En el cuarto grupo el precio es el más alto y las viviendas son las más grandes. Generalmente, a mayor estrato aumenta el precio junto con el tamaño de la construcción y tienen las características más grandes.
Los números de clusters indicados por los métodos jerárquico y no jerárquico son diferentes, lo cual indica que propiedades carecen de información suficiente para determinar patrones o características adicionales para generar clusters con una estructura más específica, en lugar de una estructura general.
Estas agrupaciones podrían utilizarse para un análisis estadístico más exhaustivo en cada uno de los grupos,reconociendo las características compartidas, los patrones y diferencias entre grupos similares. También podría considerarse nuevas medidas y adicionar nuevos datos a la tabla para generar clusters con estructuras sólidas.
#se contruye una tabla cruzada para las variables categóricas tipo de vivienda, zona y barrio
library(FactoMineR)
tabla <- table(datos$zona, datos$estrato)
resultados_ac <- CA(tabla)
valores_prop <-resultados_ac$eig
library(factoextra)
fviz_screeplot(resultados_ac, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
Las dos primeras dimensiones juntas explican el 97.7% de la varianza total en los datos, indicando que las dos primeras dimensiones son suficientes para capturar la mayor parte de la información presentada por los datos.
Por medio del análisis del plano se puede concluir que las viviendas que están en la Zona oeste son estrato 6. Por otro lado, las viviendas que están ubicadas en las zonas norte y sur pertenecen a estratos 4 y 5, y las viviendas que están ubicadas en las zonas Oriente y Centro son mayoritariamente de estrato 3.
En primer lugar, la aplicación del Análisis de Componentes Principales se logra reducir la dimensión de los datos para identificar las variables más influyentes que explican la variabilidad en el mercado de vivienda. Esto permite comprender los elementos claves que se relacionan con el valor y la oferta, como el área de construcción, los precios y características específicas del mercado.
El Análisis de Conglomerados permite agrupar propiedades con características similares para facilitar la segmentación de mercado e identificar patrones de oferta y demanda, lo cual es crucial para tomar decisiones estratégicas.
Por otra parte, el Análisis de Correspondencia permite reconocer relaciones entre categorías cualitativas, como el tipo o características del entorno, con el fin de facilizar una comprensión de la distribución de las preferencias del mercado.
Los resultados obtenidos del Análisis de Conglomerados pueden utilizarse para adaptar estrategias de marketing para cada grupo de inmuebles, considerando la ubicación como un elemento importante para establecer precios y estrategias de venta. A su vez, es importante el monitoreo continuo y los análisis detallados para verificar que las estrategias sean relevantes y efectivas.