Modelos EstadĆsticos para la toma de decisiones Evaluación de la oferta inmobiliaria urbana
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.
Cargue de Librerias
library(tidyverse) # Libreria para el uso y transformacion del dataset
library(paqueteMODELOS)
library(kableExtra) #para la visualizacion de tablas
library(reshape2) # Para melt(), dibujo de correlacion
library(gridExtra) # Union de graficas
library(factoextra)
library(FactoMineR)#Dimension
dataFrame <- as.data.frame(vivienda)
cat("NĆŗmero de filas:", nrow(dataFrame), "NĆŗmero de columnas:", ncol(dataFrame), "\n")## NĆŗmero de filas: 8322 NĆŗmero de columnas: 13
## $id
## [1] "numeric"
##
## $zona
## [1] "character"
##
## $piso
## [1] "character"
##
## $estrato
## [1] "numeric"
##
## $preciom
## [1] "numeric"
##
## $areaconst
## [1] "numeric"
##
## $parqueaderos
## [1] "numeric"
##
## $banios
## [1] "numeric"
##
## $habitaciones
## [1] "numeric"
##
## $tipo
## [1] "character"
##
## $barrio
## [1] "character"
##
## $longitud
## [1] "numeric"
##
## $latitud
## [1] "numeric"
# cambiando tipo de datos
dataFrame$piso <- as.numeric(dataFrame$piso)
dataFrame$estrato <- as.factor(dataFrame$estrato)
dataFrame$parqueaderos <- as.numeric((dataFrame$parqueaderos))
lapply(dataFrame, class)## $id
## [1] "numeric"
##
## $zona
## [1] "character"
##
## $piso
## [1] "numeric"
##
## $estrato
## [1] "factor"
##
## $preciom
## [1] "numeric"
##
## $areaconst
## [1] "numeric"
##
## $parqueaderos
## [1] "numeric"
##
## $banios
## [1] "numeric"
##
## $habitaciones
## [1] "numeric"
##
## $tipo
## [1] "character"
##
## $barrio
## [1] "character"
##
## $longitud
## [1] "numeric"
##
## $latitud
## [1] "numeric"
## id zona piso estrato preciom areaconst
## 3 3 2638 3 2 3
## parqueaderos banios habitaciones tipo barrio longitud
## 1605 3 3 3 3 3
## latitud
## 3
#Esta la tabla la muestro profe, dado que preferĆ no eliminar las columnas de piso y parqueadero,
# esto debido a que en mi teorĆa, los inmuebles que no aparecen con piso pueden pertenecer a locales
#comerciales que se encuentran sótanos (por ejemplo en los centros comerciales) o posiblemente un
#apartamento en el sótano de una casa que suelen verse mucho en EEUU (basement)
subset_df <- dataFrame[is.na(dataFrame$piso), ]
subset_df# Aplicando tecnica de redondeo y medias para asignar a valores NA y elimiando los valores no considerados
df_piso <- round(mean(dataFrame$piso, na.rm = T),2)
df_parqueadero <- round(mean(dataFrame$parqueaderos, na.rm = T), 2)
dataFrame$piso[is.na(dataFrame$piso)] <- df_piso
dataFrame$parqueaderos[is.na(dataFrame$parqueaderos)] <- df_parqueadero
num_nas <- colSums(is.na(dataFrame))
num_nas## id zona piso estrato preciom areaconst
## 3 3 0 3 2 3
## parqueaderos banios habitaciones tipo barrio longitud
## 0 3 3 3 3 3
## latitud
## 3
## id zona piso estrato preciom areaconst
## 0 0 0 0 0 0
## parqueaderos banios habitaciones tipo barrio longitud
## 0 0 0 0 0 0
## latitud
## 0
## Using zona, estrato, tipo, barrio as id variables
# Graficar un boxplot para la variable "preciom"
boxplot(dataFrame$preciom, main = "Boxplot para estrato")# Graficar un boxplot para la variable "areaconst"
boxplot(dataFrame$areaconst, main = "Boxplot para preciom")#Se eliminan Outliers y se imprime nuevamente los boxplot
cuantiles_preciom <- quantile(dataFrame$preciom, probs = c(0.25, 0.75), na.rm = TRUE)
cuantiles_areaconst <- quantile(dataFrame$areaconst, probs = c(0.25, 0.75), na.rm = TRUE)
iqr_preciom <- cuantiles_preciom[2] - cuantiles_preciom[1]
iqr_areaconst <- cuantiles_areaconst[2] - cuantiles_areaconst[1]
umbral_superior_preciom <- cuantiles_preciom[2] + 1.5 * iqr_preciom
umbral_inferior_preciom <- cuantiles_preciom[1] - 1.5 * iqr_preciom
umbral_superior_areaconst <- cuantiles_areaconst[2] + 1.5 * iqr_areaconst
umbral_inferior_areaconst <- cuantiles_areaconst[1] - 1.5 * iqr_areaconst
filas_outliers_preciom <- dataFrame$preciom > umbral_superior_preciom | dataFrame$preciom < umbral_inferior_preciom
filas_outliers_areaconst <- dataFrame$areaconst > umbral_superior_areaconst | dataFrame$areaconst < umbral_inferior_areaconst
dataFrame <- dataFrame[!filas_outliers_preciom & !filas_outliers_areaconst, ]
# Graficar un boxplot para la variable "preciom"
boxplot(dataFrame$preciom, main = "Boxplot para estrato")# Graficar un boxplot para la variable "areaconst"
boxplot(dataFrame$areaconst, main = "Boxplot para preciom")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. Se requiere aplicar diversas técnicas de anÔlisis de datos
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.
# separando las variables numericas de las categoricas y normalizando
df_2_num <- dataFrame[sapply(dataFrame, function(x) class(x))=='numeric']
df_2_num <- select(df_2_num, -longitud, -latitud, -id)
head(df_2_num)## piso preciom areaconst parqueaderos banios habitaciones
## 1 -0.004079537 -0.52833591 -0.8284738 -0.8744757 0.06778087 1.7981729
## 2 -0.004079537 -0.18893023 -0.2828522 -0.8744757 -0.72628353 -0.3659256
## 3 -0.004079537 -0.04347066 0.8083909 0.3981445 -0.72628353 0.3554406
## 4 -0.827322434 0.19896197 1.4631367 1.6707647 1.65590965 -0.3659256
## 5 -1.292431415 -0.47984939 -0.6102252 -0.8744757 -0.72628353 -0.3659256
## 6 -1.292431415 -0.57682244 -0.6429625 -0.8744757 0.06778087 -0.3659256
## Standard deviations (1, .., p=6):
## [1] 1.7506119 1.0316251 0.9180717 0.7179554 0.5711413 0.4319602
##
## Rotation (n x k) = (6 x 6):
## PC1 PC2 PC3 PC4 PC5
## piso 0.1211821 -0.80791409 0.53279453 0.1729430 0.12392594
## preciom -0.4639556 -0.33058380 -0.17545654 -0.4858193 0.03350917
## areaconst -0.5030510 0.07540466 0.06509377 -0.1581929 0.70346184
## parqueaderos -0.3607436 -0.29358837 -0.57262459 0.6697076 -0.06178913
## banios -0.4927156 -0.04214365 0.22537123 -0.1929019 -0.69573759
## habitaciones -0.3795986 0.37991195 0.54992425 0.4725737 0.02814682
## PC6
## piso -0.05876030
## preciom 0.63838180
## areaconst -0.46597541
## parqueaderos -0.05869207
## banios -0.42825349
## habitaciones 0.43015928
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.
# Estandarizacion de precio, Ɣrea y zona
precio_area <- dataFrame %>% select(preciom, areaconst)
c_precio_area <- as.data.frame(scale(precio_area))
c_precio_area$zona <- dataFrame$zona
# Calcular distancia euclidiana
dist_precio_area <- dist(c_precio_area, method = 'euclidean')# Cluster con mƩtodo complete
cl_precio_area <- hclust(dist_precio_area, method = 'complete')
# Determinar la pertenencia de cada observación
cl_assigments_precio_area <- cutree(cl_precio_area, k = 4)
# Asignar los clusters
cassign_precio_area <- c_precio_area %>%
mutate(cluster = as.factor(cl_assigments_precio_area))
# GrƔfico de puntos
ggplot(cassign_precio_area, aes(x = areaconst, y = preciom, color = cluster)) +
geom_point(size = 2, alpha = 0.5) +
geom_text(aes(label = cluster), vjust = -.8) +
theme_classic()# Dendograma
plot(cl_precio_area, cex = 0.6, main = "Dendograma Precio - Area", las=1,
ylab = "Distancia euclidiana", xlab = "Grupos")
rect.hclust(cl_precio_area, k = 2, border = 2:5)# Estandarizacion de precio, Ɣrea y zona
precio_banios <- dataFrame %>% select(preciom, banios)
c_precio_banios <- as.data.frame(scale(precio_banios))
c_precio_banios$zona <- dataFrame$zona
# Calcular distancia euclidiana
dist_precio_banios <- dist(c_precio_banios, method = 'euclidean')# Cluster con mƩtodo complete
cl_precio_banios <- hclust(dist_precio_banios, method = 'complete')
# Determinar la pertenencia de cada observación
cl_assigments_precio_banios <- cutree(cl_precio_banios, k = 4)
# Asignar los clusters
cassign_precio_banios <- c_precio_banios %>%
mutate(cluster = as.factor(cl_assigments_precio_banios))
# GrƔfico de puntos
ggplot(cassign_precio_banios, aes(x = banios, y = preciom, color = cluster)) +
geom_point(size = 2, alpha = 0.5) +
geom_text(aes(label = cluster), vjust = -.8) +
theme_classic()# Dendograma
plot(cl_precio_banios, cex = 0.6, main = "Dendograma precio - banios", las=1,
ylab = "Distancia euclidiana", xlab = "Grupos")
rect.hclust(cl_precio_area, k = 2, border = 2:5)# Estandarizacion de precio, Ɣrea y zona
precio_habitaciones <- dataFrame %>% select(preciom, habitaciones)
c_precio_habitaciones <- as.data.frame(scale(precio_habitaciones))
c_precio_habitaciones$zona <- dataFrame$zona
# Calcular distancia euclidiana
dist_precio_habitaciones <- dist(c_precio_habitaciones, method = 'euclidean')# Cluster con mƩtodo complete
cl_precio_habitaciones <- hclust(dist_precio_habitaciones, method = 'complete')
# Determinar la pertenencia de cada observación
cl_assigments_precio_habitaciones <- cutree(cl_precio_habitaciones, k = 4)
# Asignar los clusters
cassign_precio_habitaciones <- c_precio_habitaciones %>%
mutate(cluster = as.factor(cl_assigments_precio_habitaciones))
# GrƔfico de puntos
ggplot(cassign_precio_habitaciones, aes(x = habitaciones, y = preciom, color = cluster)) +
geom_point(size = 2, alpha = 0.5) +
geom_text(aes(label = cluster), vjust = -.8) +
theme_classic()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.
# Seleccionar todas las variables categóricas para el anÔlisis de correspondencia
categorias <- dataFrame %>% select(tipo, zona, estrato)
# Realizar el anÔlisis de correspondencia múltiple (ACM)
resultados <- MCA(categorias)# GrÔfico de contribución al primer y segundo eje del ACM tipo-zona-estrato
fviz_mca_var(resultados, col.var = "contrib",
title = "Contribución al Primer y Segundo Eje ")## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.5702573 21.384651 21.38465
## dim 2 0.4537296 17.014861 38.39951
## dim 3 0.3742155 14.033080 52.43259
## dim 4 0.3333357 12.500089 64.93268
## dim 5 0.3162102 11.857882 76.79056
## dim 6 0.2648973 9.933648 86.72421
## dim 7 0.2087617 7.828563 94.55277
## dim 8 0.1452594 5.447227 100.00000
fviz_screeplot(resultados, addlabels = TRUE, ylim = c(0, 25))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")# Se crea la tabla de contingencia para el analisis entre estrato y zona
est_zona <- table(dataFrame$zona, dataFrame$estrato)
colnames(est_zona) <- c("Estrato3", "Estrato4", "Estrato5", "Estrato6" )
est_zona##
## Estrato3 Estrato4 Estrato5 Estrato6
## Zona Centro 103 11 4 1
## Zona Norte 565 397 718 142
## Zona Oeste 52 80 257 564
## Zona Oriente 328 7 2 0
## Zona Sur 375 1585 1612 765
##
## Pearson's Chi-squared test
##
## data: est_zona
## X-squared = 3418.3, df = 12, p-value < 2.2e-16
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.315159713 69.775012 69.77501
## dim 2 0.126947048 28.105533 97.88055
## dim 3 0.009573151 2.119455 100.00000
fviz_screeplot(acm_est_zona, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")