Modelos MutivariadosEl sector inmobiliario en Cali (Colombia), ha experimentado un notable crecimiento en los últimos años, impulsado por diversos factores como el aumento de la población, la inversión extranjera y el desarrollo de nuevos proyectos sociales y urbanísticos. Con el propósito de identificar algunos patrones, relaciones y segmentaciones relevantes entre las principales variables de la vivienda en la ciudad, se llevará a cabo un análisis holístico de modelos multivariados que permitan mejorar la toma de decisiones en cuanto a la compra, venta y valoración de propiedades.
Para el desarrollo de este informe, se hará uso de técnicas y herramientas estadísticas para organizar, resumir y presentar los datos recopilados de acuerdo con la guía del curso de modelos estadisticos para la toma de decisiones, la cual seguirá las siguientes etapas:
Análisis explotario de los datos.
Análisis de modelos multivariados.
Conclusiones y recomendaciones.
En este apartado, se realizará la carga de la base de datos original, se realizará una primera visualización de los datos obtenidos, además de los paquetes a utilizar para el desarrollo de la actividad.
Consolidado de paquete de librerias a utilizar en el proyecto:
library(paqueteMETODOS)
library(broom)
library(devtools)
library(dplyr)
library(ggplot2)
library(reshape2)
library(GGally)
library(naniar)
library(mice)
library(FactoMineR)
library(factoextra)
library(corrplot)
library(tidyr)
library(gridExtra)
library(cluster)
library(knitr)
library(rmarkdown)
library(kableExtra)
library(stargazer)
Antes de comenzar a procesar los datos, debemos conocer las características del conjunto de datos que tenemos. Para ello podemos mirar los siguientes puntos:
Número de registros y atributos.
Tipo de datos
Medida de centralidad o dispersión de los datos
Cálculo de la matriz de correlación de los datos
Cálculo de datos faltantes o perdidos
Cálculo de datos atipicos
Al realizar el proceso de importación, se observa que el conjunto inicial de datos cuenta con un total de 8322 registros (filas - observaciones) y 13 variables (columnas) con diferentes tipos de datos como: id, zona, piso, estrato, precio en millones de pesos COP, area construida, parqueadero, baños, habitaciones, tipo de vivienda, barrio, longitud y latitud. Los principales tipos de dato que nos encontramos son numérico y categórico.
#Descarga de la base de datos original
#devtools::install_github("dgonxalex80/paqueteMETODOS, force = TRUE")
data(vivienda)
# Se crea una copia seguridad.
viviwork = vivienda
dim(vivienda)
## [1] 8322 13
# Aplicar la función class a cada columna del data frame
column_classes = sapply(vivienda, class)
# Convertir el resultado en un data frame
df_column_classes = data.frame(Tipo = column_classes, stringsAsFactors = FALSE)
# Mostrar el data frame resultante
print(df_column_classes)
## Tipo
## id numeric
## zona character
## piso character
## estrato numeric
## preciom numeric
## areaconst numeric
## parqueaderos numeric
## banios numeric
## habitaciones numeric
## tipo character
## barrio character
## longitud numeric
## latitud numeric
Tal como se observa en la siguiente tabla, las variables piso (2638) y parqueadero (1605) son las variables con la mayor pérdida de datos (NA); equivalente al 32% y 19%, respectivamente. De igual forma, hay 3 filas en las que todos sus atributos son NA y posteriormente, se procederá a su posterior eliminación.
# Se visualiza la existencia de datos faltantes por medio de un data frame
faltantes = colSums(is.na(vivienda)) %>%
as.data.frame()
colnames(faltantes) = "Faltantes"
kable(faltantes, caption = "Faltantes por variable") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE)
| Faltantes | |
|---|---|
| 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 |
Al realizar el análisis de datos perdidos o faltantes en la base de datos, podemos concluir principalmente que:
#Posibles Anexos o dejarlos en la linea
md.pattern(vivienda, rotate.names = TRUE)
## 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
vis_miss(vivienda_faltantes)
gg_miss_var(vivienda, show_pct = TRUE)
El análisis de correlación de las variables muestra que, en teoria hay baja relación de las variables. Alcanza un valor máximo de 0.69 (moderado) entre variables como parqueadero y precio o, el area construida y el precio.
# Seleccionar solo las columnas numéricas
numeric_columns = sapply(vivienda, is.numeric)
vivienda_numeric = vivienda[, numeric_columns]
# Calcular la matriz de correlación
correlation_matrix = cor(vivienda_numeric, use = "complete.obs")
# Convertir la matriz de correlación en un formato largo
melted_correlation_matrix = melt(correlation_matrix)
# Crear un mapa de calor usando ggplot2
ggplot(data = melted_correlation_matrix, aes(x = Var1, y = Var2, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "red", high = "blue", mid = "white", midpoint = 0, limit = c(-1, 1), space = "Lab", name = "Correlación") +
geom_text(aes(label = round(value, 2)), color = "black", size = 2) + # Añadir números de correlación
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
coord_fixed()
En el cálculo de datos atípicos se puede observar que hay una gran cantidad de datos outliers para las variables de precio y area construida. Sin embargo, no se procede a su eliminación por motivos como: medir los modelos multivariables y coincide con la relación de las variables y el análisis del sector en la vivienda en Cali (hay zonas de alto costo y alto nivel de area construida).
# Seleccionar las variables de interés
vivienda_subset = vivienda[, c("piso", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones")]
# Convertir el conjunto de datos a formato largo
vivienda_melted = melt(vivienda_subset)
# Crear un boxplot para todas las variables seleccionadas
ggplot(vivienda_melted, aes(x = variable, y = value)) +
geom_boxplot(fill = "#9abaf9", color = "#001865") +
labs(title = "Datos Atípicos de variables numéricas",
x = "Variable",
y = "Valores") +
theme_minimal()
En esta etapa se define una secuencia de pasos que modifican los datos para reducir situaciones que puedan ser causa de fallo o deficiencia en el proceso del modelado previsto para esta actividad. En este caso se van a realizar las siguientes actividades:
2.1 Completar los datos faltantes utilizando la media para atributos numéricos. 2.2 Eliminación de registros totalmente vacios. 2.3 Eliminación de variables que no aportarían a la modelación (id, barrio, longitud, latitud). Además se pasará el piso a variable numérica. 2.4 Preparación de los subset para trabajar el analisis con variables cuantitativas (Analisis de Componentes Principales PCA y Analisis de Conglomerados) y categoricas (Analisis de Correspondencia Multiple)
De acuerdo al analisis realizado a esta misma base de datos en trabajos anteriores, para rellenar los datos faltantes de las variable piso y parqueadero, tendremos en cuenta su relación con los atriburos apartamento y casa.
Para piso, en apartamento con el valor cinco (5) y para casa con valor de (3). Por su parte, para la variable parqueadero, tanto para apartamento como para casa, se utilizará el promedio general correspondiente al valor de uno (1). Esto, teniendo en cuenta lo mencionado respecto a que actualmente las casas y apartamentos en la ciudad no poseen parqueadero o son de tipo comunitario, de acuerdo con el análisis de medidas de tendencia central.
# Rellenar los datos faltantes en la columna "piso"
vivienda$piso = ifelse(
is.na(vivienda$piso) & vivienda$tipo == "Apartamento", 5,
ifelse(is.na(vivienda$piso) & vivienda$tipo == "Casa", 3,
vivienda$piso)
)
# Rellenar los datos faltantes en la columna "parquea"
vivienda$parqueaderos = ifelse(is.na(vivienda$parqueaderos) & (vivienda$tipo == "apartamento" | viviwork$tipo == "casa"),
1,
vivienda$parqueaderos)
#Corroboramos nuevamente faltantes
faltantesNew = colSums(is.na(viviwork)) %>%
as.data.frame()
# Eliminar las filas con valores NA en viviwork
vivienda = vivienda[complete.cases(viviwork), ]
faltantesNew = colSums(is.na(vivienda)) %>% as.data.frame()
Se corroborá por medio de la tabla, que los datos faltantes hayan sido rellenados, para poder avanzar con el siguiente punto del proyecto.
# Crear y mostrar la tabla con kableExtra
kable(faltantesNew,
caption = "Datos faltantes",
col.names = c("Variable", "Faltantes"),
align = "c",
digits = 0,
format = "html",
table.attr = "class='table table-striped table-hover'",
row.names = TRUE) %>%
kable_styling(full_width = FALSE)
| Variable | Faltantes |
|---|---|
| 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 |
#Antes, se crea una copia de lo que se ha avanzando
vivienda_nw = vivienda
# Eliminar las columnas id, barrio, longitud y latitud
vivienda = subset(vivienda, select = -c(id, longitud, latitud, barrio))
#Cambiar piso a numerico y estrato a categórico
vivienda$piso = as.numeric(vivienda$piso)
vivienda$estrato = as.character(vivienda$estrato)
head(vivienda)
#subset para variables cuantitativas y cuantitativas
vivienda_numericas = vivienda[, c("piso", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones")]
vivienda_categoricas = vivienda[, c("zona", "tipo", "estrato")]
head(vivienda_numericas)
head(vivienda_categoricas)
El objetivo de esta técnica es reducir la dimensionalidad del conjunto de datos, con la mayor varianza posible, a fin de 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.
En principio, vamos a calcular la variabilidad de cada una de las columnas. Con ello, podemos observar que la mayor variabilidad la tienen el precio (106,026) y el área construida (19,125).
varianzas = apply(vivienda_numericas, 2, var)
df_varianzas = data.frame(Variable = names(varianzas), Varianza = varianzas)
print(df_varianzas, row.names = FALSE)
## Variable Varianza
## piso 7.146887e+00
## preciom 1.060265e+05
## areaconst 1.912528e+04
## parqueaderos 1.208368e+00
## banios 1.825867e+00
## habitaciones 1.771170e+00
A continuación, se muestra la información de la desviación estadar de cada una de las componentes principales y las rotaciones de sus combinaciones lineales en las variables continuas. La matriz de rotación ha calculado 6 componentes principales (vectores propios) a partir de las variables.
De igual forma, podemos observar que las primeras tres componentes principales nos dan una explicabilidad del 86% y las primeras cuatro ya componen un 90% de variabilidad en nuestro conjunto de datos.
Los graficos de codo y de varianza acumulada, sugieren la elección entre 2 y 3 componentes principales.
Del gráfico biplot podemos observar que las variables de preciom, area, baños y parqueaderos están fuertemente correlacionados entre sí y con PC1 (apuntan en direcciones similares). La variable habitaciones tiene una fuerte relación con PC2 y piso tiene una correlación negativa con PC1 y PC2 (apunta en dirección opuesta).
#procedemos a hacer estandarización de los datos
acp = prcomp(vivienda_numericas,
center = TRUE, scale = TRUE)
#Resumen
print(acp)
## Standard deviations (1, .., p=6):
## [1] 1.8335756 1.0340089 0.8553449 0.5882495 0.5520768 0.4317233
##
## Rotation (n x k) = (6 x 6):
## PC1 PC2 PC3 PC4 PC5
## piso 0.1303842 -0.83216185 -0.517488231 0.02596413 -0.1358974
## preciom -0.4559601 -0.32247810 0.264482021 -0.35698936 0.1622554
## areaconst -0.4798166 0.04280053 -0.009048408 -0.48839255 -0.6010120
## parqueaderos -0.4315969 -0.23714602 0.378193665 0.74696838 -0.2128396
## banios -0.4785793 -0.03420384 -0.205573515 -0.04099560 0.7232466
## habitaciones -0.3599478 0.37983485 -0.690566723 0.27150467 -0.1600102
## PC6
## piso 0.05975193
## preciom -0.68146114
## areaconst 0.41002386
## parqueaderos 0.10579715
## banios 0.45029456
## habitaciones -0.38725009
summary(acp)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6
## Standard deviation 1.8336 1.0340 0.8553 0.58825 0.5521 0.43172
## Proportion of Variance 0.5603 0.1782 0.1219 0.05767 0.0508 0.03106
## Cumulative Proportion 0.5603 0.7385 0.8605 0.91814 0.9689 1.00000
plot(acp, type = "l", main = "Gráfico de sedimentación")
abline(h = 1, col = "red", lty = 2)
legend("topright", legend = c("Autovalores", "Autovalor = 1"),
col = c("black", "red"), lty = c(1, 2))
var_explained = acp$sdev^2 / sum(acp$sdev^2)
cumvar_explained = cumsum(var_explained)
plot(cumvar_explained, type = "b", ylim = c(0, 1),
xlab = "Número de componentes", ylab = "Proporción de varianza explicada",
main = "Varianza explicada acumulada")
abline(h = 0.8, col = "red", lty = 2)
biplot(acp, scale = 0, cex = 0.6, col = c("#9FB6CD", "#EE6363"))
# Contribuciones de las variables
loadings = acp$rotation
contrib = loadings^2
for(i in 1:ncol(contrib)) {
contrib[,i] <- contrib[,i] / sum(contrib[,i]) * 100
}
print(round(contrib, 2))
## PC1 PC2 PC3 PC4 PC5 PC6
## piso 1.70 69.25 26.78 0.07 1.85 0.36
## preciom 20.79 10.40 7.00 12.74 2.63 46.44
## areaconst 23.02 0.18 0.01 23.85 36.12 16.81
## parqueaderos 18.63 5.62 14.30 55.80 4.53 1.12
## banios 22.90 0.12 4.23 0.17 52.31 20.28
## habitaciones 12.96 14.43 47.69 7.37 2.56 15.00
El eigenvalue ayuda a determinar la importancia de cada componente principal. En teoría, representa la cantidad de varianza que ese componente captura o explica en los datos originales
res.pca = PCA(vivienda_numericas, ncp = 3,graph = TRUE)
res.pca$eig
## eigenvalue percentage of variance cumulative percentage of variance
## comp 1 3.3619994 56.033324 56.03332
## comp 2 1.0691744 17.819573 73.85290
## comp 3 0.7316149 12.193581 86.04648
## comp 4 0.3460375 5.767291 91.81377
## comp 5 0.3047888 5.079814 96.89358
## comp 6 0.1863850 3.106417 100.00000
res.pca$var
## $coord
## Dim.1 Dim.2 Dim.3
## piso -0.2390693 0.86046275 0.44263091
## preciom 0.8360373 0.33344522 -0.22622334
## areaconst 0.8797799 -0.04425612 0.00773951
## parqueaderos 0.7913655 0.24521109 -0.32348601
## banios 0.8775113 0.03536707 0.17583625
## habitaciones 0.6599914 -0.39275261 0.59067271
##
## $cor
## Dim.1 Dim.2 Dim.3
## piso -0.2390693 0.86046275 0.44263091
## preciom 0.8360373 0.33344522 -0.22622334
## areaconst 0.8797799 -0.04425612 0.00773951
## parqueaderos 0.7913655 0.24521109 -0.32348601
## banios 0.8775113 0.03536707 0.17583625
## habitaciones 0.6599914 -0.39275261 0.59067271
##
## $cos2
## Dim.1 Dim.2 Dim.3
## piso 0.05715414 0.740396139 1.959221e-01
## preciom 0.69895845 0.111185715 5.117700e-02
## areaconst 0.77401271 0.001958604 5.990001e-05
## parqueaderos 0.62625929 0.060128479 1.046432e-01
## banios 0.77002616 0.001250830 3.091839e-02
## habitaciones 0.43558868 0.154254613 3.488942e-01
##
## $contrib
## Dim.1 Dim.2 Dim.3
## piso 1.700005 69.2493341 26.779406959
## preciom 20.789963 10.3992124 6.995073955
## areaconst 23.022393 0.1831885 0.008187369
## parqueaderos 18.627585 5.6238234 14.303044847
## banios 22.903816 0.1169902 4.226047005
## habitaciones 12.956239 14.4274513 47.688239865
En los siguientes gráficos podemos observar la varianza explicada, en donde la dimensión 1 tiene un 56% de variabilidad seguida de la siguiente dimensión con un 17,8%, lo que es mayormente mas importante en terminos de explicar variabilidad.
En el gráfico de calor de cos2, no se observan clusters claramente definidos, pero hay algunas agrupaciones sutiles, tambien hay una mayor concentración de puntos en el centro del gráfico y algunos outliers son visibles, especialmente en los extremos derecho y superior.
fviz_eig(res.pca, addlabels = TRUE)
fviz_pca_ind(res.pca,
col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800","#DC4E07"),
repel = FALSE)
Análisis de la contribución de las variables a la dimensión 1 y 2 en el PCA. Para la dimensión uno, se puede ver la contribución que tienen las variables area construida, baños, precio y parqueaderos. Por su parte, en la dimensión dos la variable piso es la que más inferencia tiene.
fviz_contrib(res.pca, choice = "var", axes = 1, top=10)
fviz_contrib(res.pca, choice = "var", axes = 2, top=10)
Este metodo sugiere agrupar las propiedades residenciales en segmentos homogéneos con características similares para entender las dinámicas de las ofertas específicas en diferentes variables del sector inmobiliario.
corrplot(cor(vivienda_numericas))
Uno de los primeros pasos, es conocer la cantidad de cluster y para ello, existen tres principales formas de saber el numero de factores, entre las más populares se encuentran:
elbow
silhouette
gap_stat (este método demora mucho la renderización, por la gran cantidad de datos. Se omitirá su presentación gráfica en el informe)
Con el primer metodo “wss”, se puede observar un codo a partir del 3 o 4 cluster, mientras que el segundo metodo “silhouette”, nos sugiere el uso de 2 cluster.
fviz_nbclust(vivienda_numericas, kmeans, method="wss")
fviz_nbclust(vivienda_numericas, kmeans, method="silhouette")
En las siguientes gráficas, se observa la representación visual para dos, tres y cuatro cluster. Posterior a ello, analizaremos el coeficiente para conocer su distribución y rendimiento.
k2 = kmeans (vivienda_numericas, centers=2, nstar=25)
fviz_cluster(k2, data=vivienda_numericas)
k3 = kmeans (vivienda_numericas, centers=3, nstar=25)
fviz_cluster(k3, data=vivienda_numericas)
k4 = kmeans (vivienda_numericas, centers=4, nstar=25)
fviz_cluster(k4, data=vivienda_numericas)
Al realizar el análisis del coeficiente de silhouette para 2, 3 y 4 cluster, podemos observar un mejor rendimiento en anchura promedio total del silhouette para dos (2) cluster: 0.67. Lo anterior, recordando que un valor cercano a 1 indica que los datos están bien agrupados, un valor cercano a cero los datos están cerca del limite de los cluster y -1 los datos están mal agrupados. A una mayor cantidad de cluster, disminuye ese coeficiente.
De igual forma, el gráfico indica que el Cluster 1 (rojo) está bastante bien definido y sus puntos están bien agrupados, con una anchura media del silhouette alta.mientras que el cluster 2 (verde) es menos cohesivo, lo que sugiere que algunos puntos podrían estar mal agrupados o que este cluster podría beneficiarse de una revisión o un ajuste en el número de clusters. Sin embargo, al hacer el aumento de cluster, empeora el resultado por lo cual seguiremos con esta elección.
La línea punteada roja muestra la anchura media del silhouette global, y aunque para los cluster 3 y 4 indica que cada cluster lo pasa; se evidencia una perdida en el coeficiente.
#calcular el coeficiente de silhouette
set.seed(123)
silhouette_valuesk2 = silhouette(k2$cluster, dist(vivienda_numericas))
silhouette_valuesk3 = silhouette(k3$cluster, dist(vivienda_numericas))
silhouette_valuesk4 = silhouette(k4$cluster, dist(vivienda_numericas))
fviz_silhouette(silhouette_valuesk2)
## cluster size ave.sil.width
## 1 1 3999 0.72
## 2 2 809 0.40
fviz_silhouette(silhouette_valuesk3)
## cluster size ave.sil.width
## 1 1 3218 0.66
## 2 2 1220 0.38
## 3 3 370 0.45
fviz_silhouette(silhouette_valuesk4)
## cluster size ave.sil.width
## 1 1 321 0.40
## 2 2 2413 0.62
## 3 3 1392 0.34
## 4 4 682 0.33
vivienda_numericas$clus = as.factor(k2$cluster)
head(vivienda_numericas)
## # A tibble: 6 × 7
## piso preciom areaconst parqueaderos banios habitaciones clus
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 2 400 280 3 5 3 1
## 2 1 260 90 1 2 3 1
## 3 1 240 87 1 3 3 1
## 4 1 220 52 2 2 3 1
## 5 1 310 137 2 3 4 1
## 6 2 320 150 2 4 6 1
Hay una mejor sectorización de la contribución de los atributos, sin embargo el siguiente gráfico muestra que con dos cluster es suficiente para interpretar el resultado.
vivienda_numericas$clus = factor(vivienda_numericas$clus)
data_long = gather(vivienda_numericas, caracteristica, valor, piso:habitaciones, factor_key=TRUE)
ggplot(data_long, aes(x = caracteristica, y = valor, group=clus, colour = clus)) +
stat_summary(fun = mean, geom="pointrange", size = 1) +
stat_summary(geom="line") +
labs(title = "Perfil de clusters por características de vivienda",
x = "Características",
y = "Valor promedio",
colour = "Cluster") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Ahora, se propone hacer una caracterización sobre los resultado en los que incide cada cluster (para este caso, dos (2)). Se realiza un analisis descriptivo de los promedios en las variables del piso, precio, del area construida, parqueaderos, baños y habitaciones. En esta caracterización se puede observar los valores promedios por cluster, para el 1ro es de 336 millones y el 2do de 1053 millones (recodando como valores mínimos 58 millones y máximos 1999 millones). De igual forma se presenta un análisis similar en el área construida donde los valores oscilar en la base de datos principal entre 210 y 800 mtrs, agrupados en promedio de 135 y 367 metros para los cluster 1 y 2, respectivamente. Este valor puede representar una tendencia mas conjunta.
vivienda_numericas$cluster = as.factor(k2$cluster)
# Calcular el promedio de las variables seleccionadas por cluster
resumen_clusters = aggregate(cbind(preciom, areaconst, parqueaderos, banios, habitaciones) ~ cluster,
data = vivienda_numericas,
FUN = mean)
resumen_tabla <- resumen_clusters %>%
kable(caption = "Resumen por Cluster")
print(resumen_tabla)
##
##
## Table: Resumen por Cluster
##
## |cluster | preciom| areaconst| parqueaderos| banios| habitaciones|
## |:-------|---------:|---------:|------------:|--------:|------------:|
## |1 | 336.5229| 135.6975| 1.522131| 2.873218| 3.413854|
## |2 | 1053.6551| 367.8579| 3.263288| 4.929543| 4.309024|
En este modelo, buscamos examinar la relación entre las variables categóricas (tipo de vivienda, zona y estrato), para identificar patrones de comportamiento de la oferta en mercado inmobiliario.
Hay que mencionar que se exluyen algunas variables como el barrio, latitud y longitud pues en principio no aportar valor al análisis y además, incluir el barrio con sus más de 300 categorías dificulta su interpretación. De igual forma, se incluye en el subset el estrato pues representa una variable de tipo ordinal.
Con lo anterior, primero se observará la frecuencia que tiene cada variable, resaltando la Zona Sur, las viviendas de tipo apartamento y el Estrato 5 como las de mayor incidencia y participación.
f1 = ggplot(vivienda_categoricas, aes(x=zona)) + geom_bar(fill="#EEDC82") + theme(axis.text.x = element_text(angle = 45, hjust = 1))
f2 = ggplot(vivienda_categoricas, aes(x=tipo)) + geom_bar(fill="#FF7256")
f3 = ggplot(vivienda_categoricas, aes(x=estrato)) + geom_bar(fill="#3A5FCD")
grid.arrange(f1, f2, f3, ncol=2, nrow=2)
El siguiente gráfico indica unas relaciones muy fuertes entre los apartamentos hacia la zona sur y las casas en la zona norte de la Ciudad, a su vez asociados a estratos medio alto y alto (4 – 5). La zona oeste la comprenden estratos altos, y hacia el centro y oriente los medios.
res.acm = MCA(vivienda_categoricas, graph = FALSE)
fviz_mca_var(res.acm, repel=TRUE, col.var = "#104E8B")
Esta función esta asociada con la varianza, donde se puede determinar el valor individual de cada una de las dimensiones, el valor porcentual y el valor acumulado.
eigenval = get_eigenvalue(res.acm)
head(eigenval)
## eigenvalue variance.percent cumulative.variance.percent
## Dim.1 0.5416488 20.31183 20.31183
## Dim.2 0.4594459 17.22922 37.54105
## Dim.3 0.3986773 14.95040 52.49145
## Dim.4 0.3333715 12.50143 64.99288
## Dim.5 0.3188668 11.95750 76.95039
## Dim.6 0.2679131 10.04674 86.99713
De igual forma, para determinar el numero de componentes principales se puede ejecutar un ScreePlot ordenado de mayor a menor, de como se reduce la variabilidad de la varianza.
fviz_screeplot(res.acm, addlabels = TRUE)
A continuación podemos observar la contribución de las categorías variables a las dimensiones. La linea discontinua roja, indica el valor promedio esperado si las contribuciones fueran uniformes.
Se puede concluir que para la primera dimensión, las variables estrato tres y zonas oriente, centro y oeste son las que mayor contribución tiene y, para la dimensión dos, la zona oeste seguido de estrato 6 y 4.
fviz_contrib(res.acm, choice="var", axes=1, top=10)
fviz_contrib(res.acm, choice="var", axes=2, top=10)
En general hay variables críticas y determinantes como lo son el precio y el área a construida, además de la influencia de datos faltantes en variables parqueadero y piso en el análisis multivariado. Sin embargo, estas representan la realidad de la oferta de la vivienda en la ciudad de Cali (la relación entre el precio y el tamaño de la vivienda mostró una tendencia clara, donde las viviendas más grandes tienden a tener precios más altos) reflejado en los modelos multivariados que se detallaron en el desarrollo del ejercicio.
EL análisis de componentes principales (PCA), que mide las variables numéricas, nos muestra la gran contribución que tienen asociadas el precio y el área construida, lo cual las hace muy útiles en el conjunto de dimensiones a conservar.
El análisis de conglomerados ratifica la visión proporcionada por el PCA. Hay una gran tendencia a clusterizar conjuntamente la variable precio y área. Las métricas funcionan mejor cuando existen dos cluster, indicando mejor agrupamiento de las variables. El ruido está efectuado principalmente por el precio.
El análisis de correspondencia está determinado en principio por tres variables, lo que puede resultar siendo un reto. Sin embargo, es suficiente para indicar relaciones que el investigador supone como las zonas de la ciudad, el estrato y el tipo de vivienda (conocer el sector inmobiliario), lo que indica la importancia de adaptar la oferta de viviendas a las preferencias locales.
En importante tener en cuenta para una oferta de vivienda el conjunto de variables comprendidas entre el precio, el área, los baños y el parqueadero. El área a construir aumenta considerablemente con el número de baños y muestra sensibilidad con el número de habitaciones, al igual que el precio de la vivienda si incluye parqueaderos.
Habría que validar la importancia de la variable piso en la oferta, pues marca como una preferencia fuerte y aparte. Aunque, hay que resaltar que hubo datos imputados en este campo.
Lo anterior con el fin de considerar estrategias de nichos personalizados, identificando preferencias y comportamientos del consumidor, si se busca vivienda familiar, unipersonal, con mascotas que van a depender mucho del área y el precio y, ayuda a definir adecuadamente el mercado al que se quiere apuntar. De esta manera, se pueden ofrecer viviendas que satisfagan un conjunto general de necesidades, tanto en términos de infraestructura como de ubicación.