Problema
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 consisten en realizar un análisis integral y multidimensional de la base de datos para obtener una comprensión del mercado inmobiliario urbano.
Analisis Base de datos
Se procede a explorar el dataset para establecer numero de observaciones, atributoS y tipos de variables:
summary(vivienda_faltantes)
## id zona piso estrato
## Min. : 1 Length:8330 Min. : 1.000 Min. :3.000
## 1st Qu.:2082 Class :character 1st Qu.: 2.000 1st Qu.:4.000
## Median :4164 Mode :character Median : 3.000 Median :5.000
## Mean :4164 Mean : 3.772 Mean :4.634
## 3rd Qu.:6246 3rd Qu.: 5.000 3rd Qu.:5.000
## Max. :8319 Max. :12.000 Max. :6.000
## NA's :3 NA's :2641 NA's :3
## preciom areaconst parquea banios
## Min. : 58.0 Min. : 30 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123 Median : 2.000 Median : 3.000
## Mean : 434.2 Mean : 175 Mean : 1.836 Mean : 3.112
## 3rd Qu.: 540.0 3rd Qu.: 229 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1606 NA's :3
## habitac tipo barrio longitud
## Min. : 0.000 Length:8330 Length:8330 Min. :-76576.00
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76506.00
## Median : 3.000 Mode :character Mode :character Median : -76.54
## Mean : 3.605 Mean :-21845.13
## 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.390
## Median : 3.450
## Mean : 970.370
## 3rd Qu.:3367.000
## Max. :3497.000
## NA's :3
La base de datos consta de 8330 observaciones y 13 variables. Se evidencia presencia de datos perdidos (NA). Cuenta con 3 variables categoricas (zona, tipo y barrio) y 10 númericas. Se evidencia adicionalmente presencia de datos atípicos principalmente en precio, área construida, piso, parqueadero, baños y habitaciones.
Se procede a realizar un diagnóstico de variables faltantes:
grafico <-md.pattern(vivienda_faltantes, rotate.names = TRUE)
title(main="Figura 1. Variables perdidas de la base de datos B&C")
La mayoria de datos perdidos se dan en las variables parqueadero y piso, por tal motivo no serán tenidas en cuenta dentro del análisis. Tampoco se analizarán las variables ID, latitud y longitud. Por otro lado, se eliminan 3 observaciones que no cuentan con ID ni
Se evidencia un gran numero de faltantes en las vairables piso y parqueaderos. Tambien se encuentran 3 casos sin ID y que no aportan información al resto de variables.
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.
El Analisis de componentes principales se realiza con variables numericas, por lo cual se transforman variables categoricas en numericas:
vivienda_faltantes <- vivienda_faltantes %>% mutate(zona = case_when (
zona == "Zona Centro" ~ 1,
zona == "Zona Norte" ~ 2,
zona == "Zona Oeste" ~ 3,
zona == "Zona Oriente" ~ 4,
zona == "Zona Sur" ~ 5, ))
vivienda_faltantes$zona <- as.numeric(vivienda_faltantes$zona)
vivienda_faltantes <- vivienda_faltantes %>% mutate(tipo = case_when ( tipo == "Casa" ~ 1,
tipo == "Apartamento" ~ 2))
vivienda_faltantes$tipo <- as.numeric(vivienda_faltantes$tipo)
head(vivienda_faltantes)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parquea banios habitac tipo
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 8312 3 4 6 1300 318 2 4 2 2
## 2 8311 3 1 6 480 300 1 4 4 1
## 3 8307 3 NA 5 1200 800 4 7 5 1
## 4 8296 5 2 3 220 150 1 2 4 1
## 5 8297 3 NA 5 330 112 2 4 3 1
## 6 8298 5 NA 5 1350 390 8 10 10 1
## # ℹ 3 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>
Se genera dataframe que contiene unicamente las siete variables seleccionadas.
dataset_filtrado <- vivienda_faltantes [c("zona", "estrato", "preciom", "areaconst", "banios", "habitac", "tipo")]
dataset_filtrado
## # A tibble: 8,330 × 7
## zona estrato preciom areaconst banios habitac tipo
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 3 6 1300 318 4 2 2
## 2 3 6 480 300 4 4 1
## 3 3 5 1200 800 7 5 1
## 4 5 3 220 150 2 4 1
## 5 3 5 330 112 4 3 1
## 6 5 5 1350 390 10 10 1
## 7 5 6 305 125 3 3 2
## 8 3 5 480 280 4 4 2
## 9 5 5 275 74 2 3 2
## 10 5 5 285 120 4 3 2
## # ℹ 8,320 more rows
Se realiza analisis de estadistica descriptiva del dataframe, se omiten datos nulos:
dataset_filtrado = na.omit(dataset_filtrado)
summary(dataset_filtrado)
## zona estrato preciom areaconst
## Min. :1.000 Min. :3.00 Min. : 58.0 Min. : 30.0
## 1st Qu.:3.000 1st Qu.:4.00 1st Qu.: 220.0 1st Qu.: 80.0
## Median :5.000 Median :5.00 Median : 330.0 Median : 124.0
## Mean :3.921 Mean :4.64 Mean : 435.8 Mean : 175.5
## 3rd Qu.:5.000 3rd Qu.:5.00 3rd Qu.: 550.0 3rd Qu.: 230.0
## Max. :5.000 Max. :6.00 Max. :1999.0 Max. :1745.0
## banios habitac tipo
## Min. : 0.000 Min. : 0.000 Min. :1.000
## 1st Qu.: 2.000 1st Qu.: 3.000 1st Qu.:1.000
## Median : 3.000 Median : 3.000 Median :2.000
## Mean : 3.119 Mean : 3.608 Mean :1.612
## 3rd Qu.: 4.000 3rd Qu.: 4.000 3rd Qu.:2.000
## Max. :10.000 Max. :10.000 Max. :2.000
Es importante tener en cuenta que el ACP, es sensible a datos atípicos. Se observan datos atípicos por encima del tercer cuartil para cuatro variables (precio, area construida, baños y habitaciones). Se decide realizar imputación de estas variables por mediana dado que la media, en este caso se ve afectada por la presencia de valores extremos.
Imputación de datos
columns <- c("zona", "estrato","preciom", "areaconst","banios", "habitac", "tipo")
imputed_data <- mice(dataset_filtrado[,names(dataset_filtrado) %in% columns],m = 1,
maxit = 1, method = "median",seed = 2018,print=F)
complete.data <- mice::complete(imputed_data)
sum(is.na(complete.data))
## [1] 0
Se verifica que no haya datos nulos en el dataset imputado:
md.pattern(complete.data)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
## zona estrato preciom areaconst banios habitac tipo
## 8227 1 1 1 1 1 1 1 0
## 0 0 0 0 0 0 0 0
grafico <-md.pattern(complete.data, rotate.names = TRUE)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
title(main="Figura 2. Variables perdidas luego de imputación de datos")
Correlación de variables
Verificamos el índice de correlación para las variables con el fin de comprender las relaciones entre ellas para determinar la fuerza y dirección de esas relaciones
matrizcor <- cor(complete.data)
corrplot (matrizcor, method = "number", number.cex = 0.5,
main="Figura 3. matriz de correlacion")
Las correlaciones positivas que mas destacan son:
areaconst y preciom: 0.69. banios y preciom: 0.67. banios y areaconst: 0.65.
Estandarización de variables
Con el fin de evitar sesgos dado por las variables que tiene una escala con valores más grandes afecten las estimaciones, se realiza la estandarización de las siete variables:
vivienda_std <- scale(complete.data)
head (vivienda_std, n = 5)
## zona estrato preciom areaconst banios habitac
## [1,] -0.6937075 1.3229679 2.6242492 1.0005237 0.6169735 -1.1014403
## [2,] -0.6937075 1.3229679 0.1342939 0.8741651 0.6169735 0.2689263
## [3,] -0.6937075 0.3499608 2.3205961 4.3841273 2.7167424 0.9541096
## [4,] 0.8135239 -1.5960533 -0.6552042 -0.1788236 -0.7828724 0.2689263
## [5,] -0.6937075 0.3499608 -0.3211858 -0.4455807 0.6169735 -0.4162570
## tipo
## [1,] 0.7967805
## [2,] -1.2548982
## [3,] -1.2548982
## [4,] -1.2548982
## [5,] -1.2548982
Con el fin de determinar pertinencia de ACP para el dataset se realiza medición de KMO y prueba de Barlett. Estas dos pruebas indican la idoneidad de los datos para la detección de estructuras.
KMO(complete.data)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = complete.data)
## Overall MSA = 0.73
## MSA for each item =
## zona estrato preciom areaconst banios habitac tipo
## 0.37 0.61 0.71 0.78 0.78 0.71 0.78
La Medida Kaiser-Meyer-Olkin de adecuación de muestreo es un estadístico que indica la proporción de varianza en las variables que pueden ser causadas por factores subyacentes. Los valores altos (cercanos a 1.0) generalmente indican que un análisis factorial puede ser útil con los datos. Si el valor es menor que 0,50, los resultados del análisis factorial probablemente no serán muy útiles, en este caso la variable zona no aporta mucho en el analisis por estructuras.
cortest(cor(complete.data))
## Warning in cortest(cor(complete.data)): n not specified, 100 used
## Tests of correlation matrices
## Call:cortest(R1 = cor(complete.data))
## Chi Square value 454.53 with df = 21 with probability < 4.5e-83
cortest.bartlett(cor(complete.data),n=850)
## $chisq
## [1] 2753.898
##
## $p.value
## [1] 0
##
## $df
## [1] 21
Prueba de esfericidad de Bartlett contrasta la hipótesis de que la matriz de correlaciones es una matriz de identidad, lo que indicaría que las variables no están relacionadas y, por lo tanto, no son adecuadas para la detección de estructuras. Los valores pequeños (menores que 0,05) del nivel de significancia del p valor, indican que un análisis factorial puede ser útil con los datos.En este caso el valor es de 2753 con un p valor estadisticamente significativo.
El indice de KMO se encuentra por encima de 0.65 y el resultado del test de Barllet es mayor a 0.60. Por lo cual se considera pertinencia para realizar analisis de componentes principales.
PCA
Se realiza analisis de componentes principales para las cuatro variables y se grafica resultado:
viviendaacp <- (prcomp(vivienda_std))
fviz_eig(viviendaacp, addlabels = TRUE, ylim = c(0, 80), main="Figura 4. Porcentaje de varianza por dimension")
El primer componente concentra la mayor varianza de los datos (46.1%), seguido del segundo componente (21.1%) y el tercer componente 14.4%. Entre los tres primeros componentes se concentra el 81.6% de la variabilidad de los datos.
Se verifica con los valores propios de cada uno de los componentes, se evidencia que el ideal de explicación de varianza de al menos 95%, se da con 5 dimensiones de las 7 dimensiones:
get_eigenvalue(viviendaacp)
## eigenvalue variance.percent cumulative.variance.percent
## Dim.1 3.2268988 46.098555 46.09855
## Dim.2 1.4782242 21.117488 67.21604
## Dim.3 1.0054218 14.363169 81.57921
## Dim.4 0.5145366 7.350522 88.92973
## Dim.5 0.3469235 4.956050 93.88578
## Dim.6 0.2416918 3.452740 97.33852
## Dim.7 0.1863034 2.661476 100.00000
En la siguiente tabla se observa la contribución de cada variable por cada uno de los 7 componentes:
get_pca_var(viviendaacp)$contrib[,1:7]
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5 Dim.6
## zona 0.1977851 0.9497739 96.672992991 0.1132256 1.9703492 1.757149e-02
## estrato 6.0768005 44.5596269 0.002841512 0.5636907 24.0023903 2.315369e+01
## preciom 20.1168675 12.5352908 1.556640240 3.7164306 7.7778129 4.759171e+00
## areaconst 23.4900027 0.3080794 0.747537549 11.5354320 29.0520941 8.721477e+00
## banios 24.1054622 0.2844353 0.016094512 14.3657173 3.2391929 4.438597e+01
## habitac 13.9904609 18.9392322 0.152284655 40.0641955 0.2301186 1.896143e+01
## tipo 12.0226210 22.4235615 0.851608542 29.6413084 33.7280420 6.935406e-04
## Dim.7
## zona 0.07830174
## estrato 1.64096493
## preciom 49.53778693
## areaconst 26.14537775
## banios 13.60312864
## habitac 7.66227493
## tipo 1.33216508
Para el primer componente, el numero de baños, area construida y precio aportan la mayor cantidad de varianza. Para el segundo componente estrato, tipo de vivienda, numero de habitaciones y el precio son las que realizan el mayor aporte. En el tercer componente, la zona es el principal aportante; mientras que para el cuarto componente el numero de habitaciones y tipo de vivienda son los que aportan mayor variabilidad. En la siguiente grafica se pueden visualizarse de mejor manera que el numero de habitaciones y el area construida se situan en el mismo cuadrante, mientras que numero de baños, precio y estrato se ubican en otro cuadrante y el tipo de vivienda se encuentra en otra dirección. La zona aparentemente no tiene mayor relación.
fviz_pca_var(viviendaacp, col.var = "contrib", gradient.cols = c("#FF7F00", "#034D94"),
repel = TRUE)
Con este gráfico es posible visualizar diferencias entre las muestras y el impacto de cada dato en cada uno de los componentes principales.
fviz_pca_biplot(viviendaacp,
repel=FALSE,
col.var='#2e9fdf',
col.ind='#ffff00')
Conclusiones ACP
Según lo mostrado en el gráfico se puede ver dos tipos de agrupamiento, en la parte superior derecha la asociación se da entre numero de habitaciones, numero de baños con el que se encuentra dotada la vivienda y el area construida. En el segmento inferior derecho, se ubican el precio de la vivienda y el estrato.
El componente principal explica el 46.1% de la varianza de los datos, el segundo componente principal 21.1% y el tercer componente 14.4, estos tres primeros componentes representan la mayor parte de la variabilidad de las 7 variables tomadas en el ACP.
En el primer componente principal las variables con mayor participación son numero de baños, area construida y precio; en el segundo componente la participación mas alta es dada por estrato, tipo de vivienda, numero de habitaciones y el precio. En el tercer componente, la zona es el principal aportante; mientras que para el cuarto componente el numero de habitaciones y tipo de vivienda son los que aportan mayor variabilidad.
Para realizar reduccion de dimensionalidad se utilizarían los primeros 4 componentes principales, que acumulan el 95% de la varianza del conjunto de datos.
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.
Normalizacion
Se normalizan las variables
vivienda_cluster <- scale (complete.data)
vivienda_cluster = as.data.frame(vivienda_cluster)
head (vivienda_cluster, n=5)
## zona estrato preciom areaconst banios habitac tipo
## 1 -0.6937075 1.3229679 2.6242492 1.0005237 0.6169735 -1.1014403 0.7967805
## 2 -0.6937075 1.3229679 0.1342939 0.8741651 0.6169735 0.2689263 -1.2548982
## 3 -0.6937075 0.3499608 2.3205961 4.3841273 2.7167424 0.9541096 -1.2548982
## 4 0.8135239 -1.5960533 -0.6552042 -0.1788236 -0.7828724 0.2689263 -1.2548982
## 5 -0.6937075 0.3499608 -0.3211858 -0.4455807 0.6169735 -0.4162570 -1.2548982
Se realiza medición de distancias euclidianas:
dis_euc<- dist(vivienda_cluster, method="euclidean")
head(dis_euc,5)
## [1] 3.507582 5.033033 5.566414 4.048754 7.442378
c1 <-hclust(dis_euc,method ="complete")
c1
##
## Call:
## hclust(d = dis_euc, method = "complete")
##
## Cluster method : complete
## Distance : euclidean
## Number of objects: 8227
Métodos no jerárquicos
Se procede a evaluar diferentes métodos de agrupación de los datos con el objetivo de identificar el número más óptimo de clústeres de acuerdo al conjunto de datos. Para ello comenzaremos con la construcción del siguiente gráfico
scv <- (nrow(vivienda_cluster) - 1) * sum(apply(vivienda_cluster, 2, var))
for (i in 2:7) scv[i] <- sum(kmeans(vivienda_cluster,
centers = i)$withinss)
plot(1:7, scv,
type = "b",
xlab = "Cantidad de Clusters",
ylab="Suma de cuadrados dentro de grupos")
La anterior gráfica evidencia la cantidad de clústeres que se pueden realizar con la data disponible. Sin embargo, la anterior gráfica no permite esclarecer la cantidad de clústeres necesarios para el análisis. Debido a ello, procedemos a evaluar el número de clúster mediante el método del codo el cual se puede representar mediante la siguiente figura
fviz_nbclust(vivienda_cluster, kmeans, method = "wss") +
geom_vline(xintercept = 4, linetype = 2) + labs (subtitle="Metodo del Codo")
Tambien se realiza un grafico con el metodo Silhouette para identificar cuantos clúster se pueden generar:
fviz_nbclust(vivienda_cluster, kmeans, method = "silhouette")
Se evidencia que el índice mas alto se genera a partir de dos
cluster.
Metodos jerarquicos
library(cluster)
# distancia euclidiana
dist_vivi_k2 <- dist(vivienda_cluster, method = 'euclidean')
# Cluster jerarquico con el método complete
hc_viv_k2 <- hclust(dist_vivi_k2, method = 'complete')
# Determinamos a dónde pertenece cada observación
cluster_assigments_k2 <- cutree(hc_viv_k2, k = 2)
# Calcular el coeficiente de Silhouette
sil_k2 <- silhouette(cluster_assigments_k2, dist(vivienda_cluster))
sil_avg_k2 <- mean(sil_k2[,3])
# Imprimir el coeficiente de Silhouette promedio
cat("Coeficiente de Silhouette promedio k=2 : ", sil_avg_k2)
## Coeficiente de Silhouette promedio k=2 : 0.6511063
Estos resultados indican una mejor agrupación cuando se eligen k=2 conglomerados (valores más cercanos a 1 indican un agrupamiento más coherente)
Se determina la pertenencia de cada observación a un cluster determinado:
cluster_assigments <- cutree(c1, k = 2)
cluster_assigments_k3 <- cutree(c1, k = 3)
cluster_assigments_k4 <- cutree(c1, k = 4)
cluster_assigments_k5 <- cutree(c1, k = 5)
Se asignan las observaciones a los cluster:
assigned_cluster <- vivienda_cluster %>% mutate(cluster = as.factor(cluster_assigments))
head(assigned_cluster,10)
## zona estrato preciom areaconst banios habitac
## 1 -0.6937075 1.3229679 2.6242492 1.0005237 0.61697355 -1.1014403
## 2 -0.6937075 1.3229679 0.1342939 0.8741651 0.61697355 0.2689263
## 3 -0.6937075 0.3499608 2.3205961 4.3841273 2.71674245 0.9541096
## 4 0.8135239 -1.5960533 -0.6552042 -0.1788236 -0.78287239 0.2689263
## 5 -0.6937075 0.3499608 -0.3211858 -0.4455807 0.61697355 -0.4162570
## 6 0.8135239 0.3499608 2.7760758 1.5059583 4.81651135 4.3800262
## 7 0.8135239 1.3229679 -0.3970990 -0.3543217 -0.08294942 -0.4162570
## 8 -0.6937075 0.3499608 0.1342939 0.7337666 0.61697355 0.2689263
## 9 0.8135239 0.3499608 -0.4881950 -0.7123378 -0.78287239 -0.4162570
## 10 0.8135239 0.3499608 -0.4578297 -0.3894213 0.61697355 -0.4162570
## tipo cluster
## 1 0.7967805 1
## 2 -1.2548982 1
## 3 -1.2548982 1
## 4 -1.2548982 1
## 5 -1.2548982 1
## 6 -1.2548982 1
## 7 0.7967805 1
## 8 0.7967805 1
## 9 0.7967805 1
## 10 0.7967805 1
Se procede a graficar los cluster acorde con las variables de interes:
# gráfico de puntos para las variables zona y estrato
ggplot(assigned_cluster, aes(x = zona, y = estrato, color = cluster)) +
geom_point(size = 4) +
geom_text(aes(label = cluster), vjust = -.8) + labs (title = "Distribucion por cluster de zona y estrato")
theme_classic()
# gráfico de puntos para las variables zona y precio
ggplot(assigned_cluster, aes(x = zona, y = preciom, color = cluster)) +
geom_point(size = 4) +
geom_text(aes(label = cluster), vjust = -.8) + labs (title = "Distribucion por cluster de zona y precio (Millones)") + # Agregar etiquetas del clúster
theme_classic()
# gráfico de puntos para las variables zona y area construida
ggplot(assigned_cluster, aes(x = zona, y = areaconst, color = cluster)) +
geom_point(size = 4) +
geom_text(aes(label = cluster), vjust = -.8) + labs (title = "Distribucion por cluster de zona y area construida (metros cuadrados)") + # Agregar etiquetas del clúster
theme_classic()
# gráfico de puntos para las variables precio y area construida
ggplot(assigned_cluster, aes(x = preciom, y = areaconst, color = cluster)) +
geom_point(size = 4) +
geom_text(aes(label = cluster), vjust = -.8) + labs (title = "Distribucion por cluster de zona y area construida (metros cuadrados)") + # Agregar etiquetas del clúster
theme_classic()
Se realiza el dendograma de viviendas para los dos cluster generados:
plot(c1, cex = 0.6, main = "Dendograma de Viviendas", las=1,
ylab = "Distancia euclidiana", xlab = "Viviendas")
rect.hclust(c1, k = 2, border = 2:5)
En el dendograma se encuentran la agrupacion de las observaciones de cada vivienda generadas a partir de dos grandes divisiones.
Se genera nuevo conjunto de datos incluyendo la clasificación por cluster:
set.seed(1)
modelkmeans <- kmeans(vivienda_cluster, 2)
vivienda_cluster2 <- data.frame(vivienda_cluster,modelkmeans$cluster)
aggregate(complete.data,
by = list(vivienda_cluster2$modelkmeans.cluster),
FUN = median)
## Group.1 zona estrato preciom areaconst banios habitac tipo
## 1 1 5 4 250 90 2 3 2
## 2 2 5 5 620 277 4 4 1
Se verifica numero de observaciones por cada uno de los cluster:
Numcluste = table(vivienda_cluster2$modelkmeans.cluster)%>%
as.data.frame()
colnames(Numcluste)=c("Cluster", "Frecuencia")
flextable(Numcluste)
Cluster | Frecuencia |
|---|---|
1 | 5,328 |
2 | 2,899 |
Se agrega una nueva columna al conjunto de datos con la pertenencia al cluster que corresponde cada observacion:
viviendakmeans = kmeans(vivienda_cluster2, centers = 2)
vivienda_cluster2$cluster = viviendakmeans$cluster
vivienda_cluster2$cluster = as.character(vivienda_cluster2$cluster)
head(vivienda_cluster2, n = 6)
## zona estrato preciom areaconst banios habitac tipo
## 1 -0.6937075 1.3229679 2.6242492 1.0005237 0.6169735 -1.1014403 0.7967805
## 2 -0.6937075 1.3229679 0.1342939 0.8741651 0.6169735 0.2689263 -1.2548982
## 3 -0.6937075 0.3499608 2.3205961 4.3841273 2.7167424 0.9541096 -1.2548982
## 4 0.8135239 -1.5960533 -0.6552042 -0.1788236 -0.7828724 0.2689263 -1.2548982
## 5 -0.6937075 0.3499608 -0.3211858 -0.4455807 0.6169735 -0.4162570 -1.2548982
## 6 0.8135239 0.3499608 2.7760758 1.5059583 4.8165113 4.3800262 -1.2548982
## modelkmeans.cluster cluster
## 1 2 2
## 2 2 2
## 3 2 2
## 4 1 1
## 5 1 1
## 6 2 2
Se grafica la pertenencia de cada observacion por los dos cluster generados:
fviz_cluster(list(data = vivienda_cluster2[1:8],
cluster = vivienda_cluster2$modelkmeans.cluster),
palette = c("#2E9FDF", "#E7B800" , "#FC4E07"),
ellipse.type = "convex",repel = F,
show.clust.cent = TRUE, ggtheme = theme_minimal())
Con el fin de analizar cada cluster por separado, se calculan medidas de tendencia central (media) para las variables contenidas en cada cluster generados:
median_clus <- aggregate(cbind(estrato, preciom, areaconst, habitac, banios, zona)
~ modelkmeans.cluster,
data = vivienda_cluster2, FUN = function(x) c(Media = round(mean(x), 2)))
colnames(median_clus)=c("Cluster", "Estrato", "Precio","Area construida", "Banios", "Zona", "habitaciones")
flextable(median_clus)
Cluster | Estrato | Precio | Area construida | Banios | Zona | habitaciones |
|---|---|---|---|---|---|---|
1 | -0.21 | -0.47 | -0.51 | -0.44 | -0.53 | -0.03 |
2 | 0.38 | 0.87 | 0.94 | 0.82 | 0.98 | 0.05 |
No obstante los datos en cada cluster se encuentran normalizado por lo cual se dificulta su interpretacion.
Conclusiones AC
El analisis por conglomerados muestra la presencia de dos grandes grupos que comparten determinadas características. El primero de ellos contiene 5328 observaciones y el segundo contiene 2899. El primer cluster se caracteriza por tener menos área construida por lo tanto cuentan con menor numero de baños y habitaciones, y esto hace que tenga un menor precio. El segundo cluster esta conformado por viviendas con mayor área construida, por lo tanto ofrece mayor numero de baños y habitaciones, caracteristicas que incluyen en el precio final de la viviendam siendo mas costosas que las del cluster 1.
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.
La variable barrio presenta un gran numero de subcategorias por lo cual no será tenido en cuenta en el análisis de correspondencia.
Se genera tabla de contigencia para las variables zona y estrato.
tabla <- table(dataset_filtrado$zona, dataset_filtrado$estrato)
rownames(tabla) <- c("Centro", "Norte", "Oeste", "Oriente", "Sur")
colnames(tabla) <- c("Estrato3", "Estrato4", "Estrato5", "Estrato6" )
addmargins(tabla)
##
## Estrato3 Estrato4 Estrato5 Estrato6 Sum
## Centro 105 14 4 1 124
## Norte 555 398 762 171 1886
## Oeste 54 85 287 767 1193
## Oriente 330 8 2 1 341
## Sur 374 1597 1673 1039 4683
## Sum 1418 2102 2728 1979 8227
Se aplica prueba de asociacion chi cuadrado para determinar la relacion entre las variables zona y estrato:
chisq.test(tabla)
##
## Pearson's Chi-squared test
##
## data: tabla
## X-squared = 3780, df = 12, p-value < 2.2e-16
Se evidencia que ambas variables zona y estrato se encuentran relacionadas acorde con p valor obtenido, por lo tanto se rechaza hipotesis nula que determina que son independientes la una de la otra. El nivel de significancia establecido es 0.05.
Se estiman las coordenadas para cada una de los niveles de las variables para ser representadas en un plano cartesiano
resultados_ac <- CA(tabla)
En la grafica se observa que las viviendas de estrato 3 estan ubicadas en la zona centro y oriente. Las viviendas que están ubicadas en las zonas Norte y Sur son principalmente de estratos 4 y 5. Las viviendas estrato 6 se ubican en la zona oeste de la ciudad.
Para medir el grado de representatividad del proceso, se calculan los valores de la varianza acumulada, utilizando para ellos los valores propios de la matriz de discrepancias:
valores_prop <-resultados_ac$eig ; valores_prop
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.32119386 69.907181 69.90718
## dim 2 0.12717852 27.680142 97.58732
## dim 3 0.01108523 2.412677 100.00000
fviz_screeplot(resultados_ac, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Componentes")
Los resultados indican que el primer componente contiene el 68.9% de la varianza de los datos y el segundo componente el 27.7%, es decir que entre ambos se aporta el 97.6% de los datos categoricos.
Se realiza tabla de contigencia para las variables tipo de vivienda y estrato.
tabla2 <- table(complete.data$tipo, complete.data$estrato)
rownames(tabla2) <- c("Casa", "Apartamento")
colnames(tabla2) <- c("Estrato3", "Estrato4", "Estrato5", "Estrato6" )
addmargins(tabla2)
##
## Estrato3 Estrato4 Estrato5 Estrato6 Sum
## Casa 799 721 982 693 3195
## Apartamento 619 1381 1746 1286 5032
## Sum 1418 2102 2728 1979 8227
chisq.test(tabla2)
##
## Pearson's Chi-squared test
##
## data: tabla2
## X-squared = 222.65, df = 3, p-value < 2.2e-16
Se evidencia que ambas variables tipo de vivienda y estrato se encuentran relacionadas, ya que el valor de p obtenido es menor al nivel de significancia, por lo tanto se rechaza hipotesis nula que determina que son independientes ambas variables.
Recomendaciones:
El precio de la vivienda se relaciona con el estrato, y éste con la zona geografica donde se ubica la vivienda. El área construida determina la dotación de la vivienda en cuanto a numero de habitaciones y baños. Entre mejor dotada se encuentre la vivienda mayor será el precio. La mayor demanda se da en tipos de vivienda apartamento estrato 4 y 5. Con esta información se puede segmentar la oferta de vivienda a los clientes acorde con sus necesidades.
Las viviendas de estrato 3 estan ubicadas en la zona centro y oriente. Las viviendas que están ubicadas en las zonas Norte y Sur son principalmente de estratos 4 y 5. Las viviendas estrato 6 se ubican en la zona oeste de la ciudad. Esto permite identificar a la empresa oportunidades de compra o venta de viviendas con alta demanda por parte de los clientes.
Se evidencia que los clientes se pueden segmentar en dos grandes cluster.El primer cluster se caracteriza porque los clientes prefieren viviendas pequeñas en área (menor numero de baños y habitaciones), a un precio accesible. El segundo cluster esta conformado por clientes con mayores ingresos que prefieren viviendas con mayor área construida, (por lo tanto ofrece mayor numero de baños y habitaciones).