Maria comenzó como agente de bienes raíces en Cali hace 10 años. Después de laborar dos años para una empresa nacional, se traslado a Bogotá y trabajó para otra agencia de bienes raíces. Sus amigos y familiares la convencieron de que con su experiencia y conocimientos del negocio debía abrir su propia agencia. Terminó por adquirir la licencia de intermediario y al poco tiempo fundó su propia compañía, C&A (Casas y Apartamentos) en Cali. Santiago y Lina, dos vendedores de la empresa anterior aceptaron trabajar en la nueva compaña. En la actualidad ocho agentes de bienes raíces colaboran con ella en C&A.
Actualmente las ventas de bienes raíces en Cali se han visto disminuidas de manera significativa en lo corrido del año. Durante este periodo muchas instituciones bancarias de ahorro y vivienda están prestando grandes sumas de dinero para la industria y la construcción comercial y residencial. Cuando el efecto producto de las tensiones políticas y sociales disminuya, se espera que la actividad económica de este sector se reactive.
Hace dos días, María recibió una carta solicitando asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad. Las solicitudes incluyen las siguientes condiciones:
| Características | Vivienda 1 | Vivienda 2 |
|---|---|---|
| Tipo | Casa | Apartamento |
| Área construida | 200 | 300 |
| Parqueaderos | 1 | 3 |
| Banos | 2 | 3 |
| Habitaciones | 4 | 5 |
| Estrato | 4 o 5 | 5 o 6 |
| Zona | Norte | Sur |
| Crédito preaprobado | 350 millones | 850 millones |
Realizar un análisis de regresión multiple para determinar los componentes del precio de las viviendas del mercado inmobiliario de Cali.
Para el análisis exploratorio de las variables que describen las características de los tipos de vivienda en Cali en función del precio, se realizaron diagramas de dispersión para las variables continuas como el precio y el área construida y para las variables continuas se construyeron diagramas de cajas del precio por cada una de las categorías analizadas como: el estrato, número de habitaciones, número de pisos, número de parqueaderos y número de baños.
El diagrama de dispersión entre el área construida y el precio mostró que hay una relación directa entre estas dos variables. El mayor valor del precio fue de 1650 millones de pesos para un área 1500 millones.
library(plotly)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = casas, x = ~Area_Construida,
y = ~Precio,
type = 'scatter',
mode = 'markers') %>%
layout(
xaxis = list(title = "Área Construida"),
yaxis = list(title = "Precio")
)
p1
Figura 1. Diagrama de dispersión de la relación del área construida vs el precio para las casas ubicadas en el norte de Cali.
Para la relación entre el estrato y el precio se encontró que en el estrato 3 se presentan los menores precios para las casas distribuidas en el norte de Cali con una mediana de 235 millones y el estrato 6 se presentan los mayores valores de precios con una mediana de 1250 millones, sin embargo las distribuciones de precios entre los estratos medios parecen sobreponerse con medianas para el estrato 4 de 272 millones y para el estrato 5 con 415 millones.
library(plotly)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = casas, x = ~Estrato , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio")
)
p1
Figura 2. Diagrama de cajas representando la relación del estrato vs el precio para las casas ubicadas en el norte de Cali.
No se observó una tendencia clara entre el precio y el número de habitaciones (Figura 3). Se encontró que el mayor precio se presentó para una casa que tiene solo tres habitaciones con un valor de 1650 millones, sin embargo esta misma categoría presentó la menor mediana de todas (Figura 3).
library(plotly)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = casas, x = ~No.Habitaciones , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Habitaciones"),
yaxis = list(title = "Precio")
)
p1
Figura 3. Diagrama de cajas de la relación del número de habitaciones vs el precio para las casas ubicadas en el norte de Cali.
En esta relación se pudo observar que hay una tendencia al aumento de precios con el aumento del número de pisos. Sin embargo, hay muchos datos que son atípicos y el mayor precio del conjunto se presenta para las casas que tiene un piso con un precio de 1650 millones (Figura 4).
library(plotly)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = casas, x = ~No.Pisos , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Pisos"),
yaxis = list(title = "Precio")
)
p1
Figura 4. Diagrama de cajas de la relación del número de pisos vs el precio para las casas ubicadas en el norte de Cali.
Basados en las medianas de los precios frente al número de parqueaderos, se puede observar una tendencia al aumento de los precios con el aumento del número de parqueaderos (Figura 5).
library(plotly)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = casas, x = ~No.Parqueaderos , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Parqueaderos"),
yaxis = list(title = "Precio")
)
p1
Figura 5. Diagrama de cajas de la relación del número de parqueaderos vs el precio para las casas ubicadas en el norte de Cali.
En cuanto a la relación entre el número de baños de las casas y el precio de estas, se puede observar una tendencia general del aumento de las medianas del precio con el aumento de número de baños, exceptuando cuando las casas tienen alrededor de 8 baños con una media mucho menor de 470 millones que cuando presenta siete baños con un precio de 785 millones (Figura 6).
library(plotly)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = casas, x = ~No.Banos , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Banos"),
yaxis = list(title = "Precio")
)
p1
Figura 6. Diagrama de cajas de la relación del número de Banos vs el precio para las casas ubicadas en el norte de Cali.
Se puede observar que los puntos dispersos indicaron una tendencia positiva entre ambas variables, sugiriendo que a medida que el precio de las propiedades aumentó, el área construida también tendió a incrementarse. Sin embargo, se observaron algunas dispersiones notables en las que los precios elevados correspondieron a áreas construidas relativamente pequeñas y viceversa. Estas observaciones sugirieron la presencia de posibles outliers o variaciones en el mercado que podrían estar influenciando esta relación (Figura 8).
library(plotly)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
apartamentos$Area_Construida<-as.numeric(apartamentos$Area_Construida)
# Crear gráficos individuales
p1 <- plot_ly(data = apartamentos, x = ~Area_Construida, y = ~Precio , type = 'scatter', mode = 'markers') %>%
layout(
xaxis = list(title = "Precio"),
yaxis = list(title = "Área Construida")
)
p1
Figura 7.Diagrama de dispersión de la relación del área construida vs el precio para las apartamentos ubicadas en el norte de Cali..
Se observó que, en general, el precio de las propiedades aumentó con el estrato. Los diagramas de cajas revelaron que la mediana del precio fue progresivamente mayor a medida que el estrato aumentó. Además, la dispersión de los precios dentro de cada estrato también mostró una tendencia creciente, especialmente en el estrato 6, donde se presentaron varios valores atípicos por encima del tercer cuartil, indicando que en este estrato hubo una mayor variabilidad en los precios.
Los datos sugirieron que los apartamentos en estratos más altos no solo tienden a ser más costosas, sino que también exhiben una mayor diversidad en los precios, lo que podría estar relacionado con diferencias en características como la ubicación, el tamaño o las comodidades ofrecidas (Figura 8).
library(plotly)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = apartamentos, x = ~Estrato , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio")
)
p1
Figura 8. Diagrama de cajas de la relación del estrato vs el precio para los apartamentos ubicadas en el norte de Cali.
En esta gráfica se observó una tendencia de las medianas del precio a aumentar con el número de habitaciones, sin embargo los apartamentos que aparecen en la categoría de cero habitaciones se sale de esta tendencia (Figura 9). Cada una de estas categorías presentaron una variación de precios amplia pero la categoría de 3 habitaciones es la que mayor variabilidad presentó (Figura 9).
library(plotly)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = apartamentos, x = ~No.Habitaciones , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Habitaciones"),
yaxis = list(title = "Precio")
)
p1
Figura 9 Diagrama de cajas de la relación del número de habitaciones vs el precio para los apartamentos ubicados en el norte de Cali.
Esta categoría se refiere al número de piso en el que se encuentra el apartamento. Para esta categoría parece no existir una relación clara entre el precio y el número del piso en el que se ubica el apartamento (Figura 10).
library(plotly)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = apartamentos, x = ~No.Pisos , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Pisos"),
yaxis = list(title = "Precio")
)
p1
Figura 10. Diagrama de cajas de la relación del número de pisos vs el precio para los apartamentos ubicados en el norte de Cali.
Se observó que el número de parqueaderos asignados al apartamento si influye en el precio de este con una tendencia al aumento (Figura 11).
library(plotly)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = apartamentos, x = ~No.Parqueaderos , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Parqueaderos"),
yaxis = list(title = "Precio")
)
p1
Figura 11. Diagrama de cajas de la relación del número de parqueaderos vs el precio para los apartamentos ubicados en el norte de Cali.
También se observó que hay una relación directa entre el precio de los apartamentos y el número de baños, sin embargo existe una categoría de cero para esta variable lo cuál no tiene mucho sentido práctico (Figura 12).
library(plotly)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
# Crear gráficos individuales
p1 <- plot_ly(data = apartamentos, x = ~No.Banos , y = ~Precio,
type = 'box') %>%
layout(
xaxis = list(title = "No. Banos"),
yaxis = list(title = "Precio")
)
p1
Figura 12 Diagrama de cajas de la relación del número de Banos vs el precio para las casas ubicadas en el norte de Cali.
El modelo de regresión lineal múltiple fue ajustado para predecir el precio de las casas utilizando como variables predictoras el área construida, el estrato, el número de habitaciones, el número de parqueaderos y el número de baños.
\(Precio = Area.Construida + Estrato + No.Habitaciones + No.Parqueaderos + No.Baños\)
library(caret)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
casas$No.Parqueaderos<-as.integer(casas$No.Parqueaderos)
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Estrato<-as.factor(casas$Estrato)
modelo <- lm(Precio ~ Area_Construida + Estrato + No.Habitaciones + No.Parqueaderos + No.Banos, data = casas)
# Mostrar el resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = Precio ~ Area_Construida + Estrato + No.Habitaciones +
## No.Parqueaderos + No.Banos, data = casas)
##
## Residuals:
## Min 1Q Median 3Q Max
## -470.76 -48.39 -13.96 37.49 546.23
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 60.94030 16.67335 3.655 0.000295 ***
## Area_Construida 0.40854 0.03877 10.537 < 2e-16 ***
## Estrato4 33.28387 17.73052 1.877 0.061291 .
## Estrato5 114.07611 22.12116 5.157 4.14e-07 ***
## Estrato6 634.00436 39.87847 15.898 < 2e-16 ***
## No.Habitaciones -3.38578 3.77851 -0.896 0.370813
## No.Parqueaderos 34.03396 6.82782 4.985 9.63e-07 ***
## No.Banos 31.67447 5.34640 5.924 7.28e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 103 on 363 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.7391, Adjusted R-squared: 0.7341
## F-statistic: 146.9 on 7 and 363 DF, p-value: < 2.2e-16
print(varImp(modelo))
## Overall
## Area_Construida 10.5366236
## Estrato4 1.8772076
## Estrato5 5.1568768
## Estrato6 15.8984125
## No.Habitaciones 0.8960635
## No.Parqueaderos 4.9846013
## No.Banos 5.9244526
Coeficientes: El área construida tiene un coeficiente estimado de 0.41 (p < 2e-16), indicando un aumento en el precio con el aumento del área. Los estratos 4, 5 y 6 muestran coeficientes positivos, siendo el estrato 6 el de mayor impacto en el precio (634.00, p < 2e-16).
El estrato 4 es marginalmente significativo (p = 0.061).
El número de parqueaderos (coeficiente 34.03, p < 0.001) y el número de baños (coeficiente 31.67, p < 0.001) son predictores significativos y positivos del precio.
El número de habitaciones no resultó significativo (p = 0.370), indicando que su efecto sobre el precio no es considerable en este modelo.
Bondad de ajuste: El valor de R-cuadrado ajustado es 0.7341, lo que indica que aproximadamente el 73.4% de la variabilidad en el precio puede ser explicada por el modelo. El valor F del modelo es 146.9 (p < 2.2e-16), lo que sugiere que el modelo en su conjunto es altamente significativo.
El modelo demuestra que el área construida, el estrato, el número de parqueaderos y el número de baños son predictores significativos del precio de las casas, mientras que el número de habitaciones no presenta un efecto significativo.
Residuales: Los residuales del modelo presentan una distribución simétrica, con valores mínimos y máximos de -470.76 y 546.23, respectivamente. El primer cuartil (1Q) es -48.39, la mediana es -13.96, y el tercer cuartil (3Q) es 37.49, lo que sugiere una leve asimetría hacia valores residuales positivos.
# Normalidad prueba de Shapiro
coeficientes <- summary(modelo)$coefficients
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.86649, p-value < 2.2e-16
Según la prueba de Breusch-Pagan esta indica la presencia de heterocedasticidad .
# Comprobar homocedasticidad (prueba de Breusch-Pagan)
library(lmtest)
bptest(modelo)
##
## studentized Breusch-Pagan test
##
## data: modelo
## BP = 85.212, df = 7, p-value = 1.186e-15
El valor del estadístico Durbin-Watson cercano a 2 indica una autocorrelación positiva leve. Sin embargo, el p-valor bajo sugiere que la autocorrelación de los errores es significativa, lo cual puede indicar que los errores no son independientes.
# Comprobar la independencia de los residuos (prueba de Durbin-Watson)
dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.7528, p-value = 0.005205
## alternative hypothesis: true autocorrelation is greater than 0
Residuals vs Fitted: Este gráfico muestra una ligera tendencia no lineal en los residuales, lo que sugiere que podría haber una relación no capturada por el modelo. También se observan algunos puntos con valores de residuales altos, lo que indica posibles valores atípicos.
Q-Q Plot: Los residuales estandarizados no siguen completamente la línea de normalidad, especialmente en los extremos, lo que indica que los residuales no son perfectamente normales.
Scale-Location: Este gráfico muestra una dispersión creciente de los residuales a medida que aumenta el valor ajustado, lo que sugiere heterocedasticidad (varianza no constante de los errores).
Residuals vs Leverage: Muestra algunos puntos con alta influencia (alto leverage y residuales estandarizados altos), lo que indica que algunos valores tienen un impacto significativo en el modelo.
par(mfrow=c(2,2))
plot(modelo)
Los resultados de la prueba de Multicolinealidad no muestras valores alto que indiquen que haya multicolinealidad entre las variables analizadas.
# 4.4. Comprobar la multicolinealidad (VIF)
library(car)
vif(modelo)
## GVIF Df GVIF^(1/(2*Df))
## Area_Construida 1.378636 1 1.174154
## Estrato 1.527540 3 1.073162
## No.Habitaciones 2.044903 1 1.430001
## No.Parqueaderos 1.201060 1 1.095929
## No.Banos 2.105593 1 1.451066
Las predicciones de precios basados en la variables del modelo para una casa de 200 m^2 con 1 parqueaderos, 2 baños y 4 habitaciones en el estrato 4 y en el estrato 5 está entre los 259 y los 340 millones de pesos cuyos costos están acorde con el presupuesto de los clientes.
# 4.4. Comprobar la multicolinealidad (VIF)
predict(modelo,list(Area_Construida = 200, No.Parqueaderos = 1, No.Banos = 2,
No.Habitaciones = 4, Estrato = "4")) # Estrato 4
## 1
## 259.7711
# 4.4. Comprobar la multicolinealidad (VIF)
predict(modelo,list(Area_Construida = 200, No.Parqueaderos = 1, No.Banos = 2,
No.Habitaciones = 4, Estrato = "5")) # Estrato 5
## 1
## 340.5634
Para explorar una mejora en el desempeño del modelo se proceso un análisis con una partición de un 70% de entrenamiento y un 30% de testeo junto a una validación cruzada de k-fold con un \(k=10\).
Para las Casas, esta aproximación mejoró el desempeño del modelo y pasó de un \(R^{2}=0.7391\) a un \(R^{2}=0.7551\).
library(caret)
casas<-read.csv2("casaEspacial_df.csv", header = TRUE, sep=",")
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Precio<-as.numeric(casas$Precio)
casas$No.Parqueaderos<-as.integer(casas$No.Parqueaderos)
casas$Area_Construida<-as.numeric(casas$Area_Construida)
casas$Estrato<-as.factor(casas$Estrato)
casas <- na.omit(casas)
# 5. Partición de los datos en entrenamiento (70%) y prueba (30%)
set.seed(123) # Para reproducibilidad
train_index <- sample(1:nrow(casas), 0.7 * nrow(casas))
casas_train <- casas[train_index, ]
casas_test <- casas[-train_index, ]
control <- trainControl(method = "cv", number = 10) # 10-fold cross-validation
formula_model <- Precio ~ Area_Construida + Estrato + No.Habitaciones + No.Parqueaderos + No.Banos
modelo_cv <- train(formula_model, data = casas_train, method = "lm", trControl = control)
summary(modelo_cv)
##
## Call:
## lm(formula = .outcome ~ ., data = dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -266.75 -49.33 -13.99 37.45 515.92
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 91.60011 18.04210 5.077 7.48e-07 ***
## Area_Construida 0.59682 0.04996 11.947 < 2e-16 ***
## Estrato4 32.67102 18.97088 1.722 0.086271 .
## Estrato5 95.94330 22.73538 4.220 3.42e-05 ***
## Estrato6 537.42803 40.24118 13.355 < 2e-16 ***
## No.Habitaciones -4.00237 3.91920 -1.021 0.308133
## No.Parqueaderos 16.63093 7.51987 2.212 0.027896 *
## No.Banos 19.16979 5.71880 3.352 0.000926 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 92.52 on 251 degrees of freedom
## Multiple R-squared: 0.7557, Adjusted R-squared: 0.7489
## F-statistic: 110.9 on 7 and 251 DF, p-value: < 2.2e-16
print(varImp(modelo_cv))
## lm variable importance
##
## Overall
## Estrato6 100.000
## Area_Construida 88.580
## Estrato5 25.935
## No.Banos 18.898
## No.Parqueaderos 9.651
## Estrato4 5.683
## No.Habitaciones 0.000
predicciones <- predict(modelo_cv, newdata = casas_test)
# Mostrar las primeras predicciones
head(predicciones)
## 3 6 8 12 15 17
## 324.5669 192.5583 217.6962 157.1708 404.8900 218.4684
# Comparar las predicciones con los valores reales
comparacion <- data.frame(Real = casas_test$Precio, Predicho = predicciones)
head(comparacion)
## Real Predicho
## 3 500 324.5669
## 6 180 192.5583
## 8 200 217.6962
## 12 85 157.1708
## 15 320 404.8900
## 17 215 218.4684
Con la información obtenida se presentó la distribución espacial (Figura 12) de las casas del norte que pueden ser obtenidas por los clientes en el estrato 4 y 5, con precios inferiores a las 350 (Casas E4 y Casas E5) y con las características deseadas (Area_Construida >= 200, No. Baños == 2, No. Parqueaderos==1, No.Habitaciones == 4), se encontraron 11 casas 7 en el estrato 4 y 4 en el estrato 5.
require(sf)
require(leaflet)
require(leaflet.extras)
require(dplyr)
#Carga de capas espaciales
Barrios<-sf::read_sf("Cali_WGS84.gpkg", layer='Barrios')
zonas<-sf::read_sf("Zonas.gpkg", layer='Zonas_Precio_Total')
crs <- sf::st_crs("+proj=longlat +datum=WGS84 +no_defs")
#Carga de datos iniciales
datosImputadosTotales<-read.csv2("datosImputadosTotales.csv", header = TRUE, sep=",")
#Filtración de lso registros de las casas del
Casas_Imputadas<-subset(datosImputadosTotales, Tipo.Vivienda == "Casa")
casasNorte<-subset(Casas_Imputadas, Zona == "Zona Norte")
datos_casas_sin.na<- subset(Casas_Imputadas, !is.na(Longitud) & !is.na(Latitud))
Viviendas_Espacial_Casas <- sf::st_as_sf(datos_casas_sin.na, coords = c("Longitud", "Latitud"))
Viviendas_Espacial_Casas <- sf::st_set_crs(Viviendas_Espacial_Casas, crs)
Casas_joined_sf <- sf::st_join(Viviendas_Espacial_Casas,Barrios , join = st_within)
zona_Norte<-dplyr::filter(zonas, Zonas_IDE == "Zona Norte")
casas_NorteEspacial<-sf::st_intersection(zona_Norte, Casas_joined_sf)
E4 <- casas_NorteEspacial %>%
filter( Estrato == "4", Precio < 350)
E5 <- casas_NorteEspacial %>%
filter( Estrato == "5", Precio < 350)
ofertas4 <- casas_NorteEspacial %>%
filter(Area_Construida >= 200, Estrato == "4",No.Banos >= 2, No.Parqueaderos>=1, No.Habitaciones >= 4, Precio < 350)
ofertas5 <- casas_NorteEspacial %>%
filter(Area_Construida >= 200, Estrato == "5", No.Banos >= 2, No.Parqueaderos>=1, No.Habitaciones >= 4, Precio < 350)
ZonalabelsMediana <- sprintf(
"<strong></strong><strong>%s</strong>",
zonas$Zonas_IDE
) %>% lapply(htmltools::HTML)
pal1 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(E4$Precio))
pal2 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(E5$Precio))
pal3 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(ofertas4$Precio))
pal4 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(ofertas5$Precio))
preciosLabels1 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
E4$Barrio, E4$Zona, E4$Precio
) %>% lapply(htmltools::HTML)
preciosLabels2 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
E5$Barrio, E5$Zona, E5$Precio
) %>% lapply(htmltools::HTML)
preciosLabels3 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
ofertas4$id, ofertas4$Area_Construida, ofertas4$Precio
) %>% lapply(htmltools::HTML)
preciosLabels4 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
ofertas5$id, ofertas5$Area_Construida, ofertas5$Precio
) %>% lapply(htmltools::HTML)
map <-leaflet::leaflet(height=700, width = 800)%>%
addProviderTiles(providers$CartoDB.DarkMatterNoLabels)%>%
setView(lng = -76.49478, lat = 3.45, zoom = 13)%>%
addPolygons(data = zonas,
opacity = 1,
color = "white",
label = ZonalabelsMediana,
group = "Zona",
stroke = 0.2)%>%
# addPolygons(data = Barrios, group = "Barrios", color = "grey",stroke = 0.2, opacity = 1)%>%
addFullscreenControl(position = "topleft", pseudoFullscreen = TRUE)%>%
addLayersControl(overlayGroups = c( "Zona","Casas E4", "Casas E5", "Ofertas E4", "Ofertas E5"), options = layersControlOptions(collapsed = FALSE))%>%
addScaleBar(position = c("topright", "bottomright", "bottomleft", "topleft"),options = scaleBarOptions(metric = TRUE,
imperial = FALSE, updateWhenIdle = TRUE))%>%
addMapPane("ames_lines", zIndex = 430) %>%
addCircles(data = E4,
color = ~pal1(Precio),
radius = ~Precio/10,
group ="Casas E4",
label = preciosLabels1,
labelOptions = labelOptions(
style = list("font-weight" = "normal",
padding = "3px 8px"),
textsize = "15px",
direction = "auto"))%>%
addCircles(data = E5,
color = ~pal2(Precio),
radius = ~Precio/10,
group ="Casas E5",
label = preciosLabels2,
labelOptions = labelOptions(
style = list("font-weight" = "normal",
padding = "3px 8px"),
textsize = "15px",
direction = "auto"))%>%
addCircles(data = ofertas4,
color = ~pal3(Precio),
radius = ~Precio/10,
group ="Ofertas E4",
label = preciosLabels3,
labelOptions = labelOptions(
style = list("font-weight" = "normal",
padding = "3px 8px"),
textsize = "15px",
direction = "auto"))%>%
addCircles(data = ofertas5,
color = ~pal4(Precio),
radius = ~Precio/10,
group ="Ofertas E5",
label = preciosLabels4,
labelOptions = labelOptions(
style = list("font-weight" = "normal",
padding = "3px 8px"),
textsize = "15px",
direction = "auto"))%>%
addLegend( position = "bottomleft", pal = pal1, values = na.omit(E5$Precio),
title = 'Precios',
opacity = 1)%>%
addMiniMap(tiles = "CartoDB.Voyager")
map
Figura 12. Mapa de la distribución de las casas de la zona norte de Cali que están dentro del conjunto de datos de C&A.
El modelo de regresión lineal múltiple fue ajustado para predecir el precio de los apartamentos utilizando como variables predictoras el área construida, el estrato, el número de habitaciones, el número de parqueaderos y el número de baños.
\(Precio=Area.Construida+Estrato+No.Habitaciones+No.Parqueaderos+No.Baños\)
library(caret)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
apartamentos$Area_Construida<-as.numeric(apartamentos$Area_Construida)
apartamentos$Estrato<-as.factor(apartamentos$Estrato)
modelo <- lm(Precio ~ Area_Construida + Estrato + No.Habitaciones + No.Parqueaderos + No.Banos, data = apartamentos)
summary(modelo)
##
## Call:
## lm(formula = Precio ~ Area_Construida + Estrato + No.Habitaciones +
## No.Parqueaderos + No.Banos, data = apartamentos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1335.39 -41.60 -1.78 40.14 829.89
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -47.29826 12.15017 -3.893 0.000101 ***
## Area_Construida 1.61474 0.05061 31.909 < 2e-16 ***
## Estrato4 25.41023 8.47920 2.997 0.002752 **
## Estrato5 47.71849 8.64608 5.519 3.71e-08 ***
## Estrato6 183.60669 10.24594 17.920 < 2e-16 ***
## No.Habitaciones -24.62444 3.62465 -6.794 1.33e-11 ***
## No.Parqueaderos 71.31824 4.30789 16.555 < 2e-16 ***
## No.Banos 43.86262 3.25399 13.480 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 104.6 on 2855 degrees of freedom
## Multiple R-squared: 0.7874, Adjusted R-squared: 0.7869
## F-statistic: 1511 on 7 and 2855 DF, p-value: < 2.2e-16
print(varImp(modelo))
## Overall
## Area_Construida 31.908669
## Estrato4 2.996772
## Estrato5 5.519091
## Estrato6 17.919941
## No.Habitaciones 6.793599
## No.Parqueaderos 16.555273
## No.Banos 13.479662
El modelo de regresión lineal múltiple explica una proporción considerable de la variabilidad en el precio de los apartamentos. El área construida, el estrato, el número de parqueaderos y el número de baños tienen efectos positivos y significativos sobre el precio. Por otro lado, el número de habitaciones tiene un efecto negativo inesperado, que podría ser resultado de alguna interacción no modelada o un posible sesgo en los datos.
Coefficients: El coeficiente del intercepto es -47.30 (p < 0.001), lo que indica que cuando todas las variables predictoras son cero, el precio estimado sería negativo, lo cual no es interpretable en un contexto real, pero esto suele suceder en modelos lineales cuando el rango de las variables predictoras no incluye cero. Cada aumento de una unidad en el área construida se asocia con un incremento de 1.61 unidades en el precio, siendo este efecto altamente significativo (p < 2e-16).
Estrato:
Número de Habitaciones: Sorprendentemente, el número de habitaciones tiene un efecto negativo sobre el precio (-24.62 unidades, p < 0.001), lo que podría indicar una correlación negativa o un efecto indirecto no capturado directamente por el modelo.
Número de Parqueaderos: Un incremento en el número de parqueaderos aumenta el precio en 71.32 unidades (p < 2e-16), lo cual es altamente significativo.
Número de Baños: Cada baño adicional aumenta el precio en 43.86 unidades (p < 2e-16), también con alta significancia.
Bondad de ajuste: Residual Standard Error: El error estándar residual es de 104.6, lo que da una idea de la variabilidad de los residuales en torno a los valores ajustados.
Multiple R-squared y Adjusted R-squared: El valor de R-cuadrado ajustado es 0.7869, lo que indica que aproximadamente el 78.69% de la variabilidad en el precio de los apartamentos puede ser explicada por el modelo. El modelo tiene un F-statistic de 1511 (p < 2e-16), indicando que el modelo en su conjunto es altamente significativo.
Residuales: Los residuales muestran un rango amplio, con un valor mínimo de -1335.39 y un valor máximo de 829.89. Los cuartiles indican una distribución relativamente simétrica alrededor de la mediana, que es cercana a cero. Sin embargo, los valores extremos de los residuales sugieren la presencia de algunos valores atípicos en los datos.
coeficientes <- summary(modelo)$coefficients
# Comprobar la normalidad de los residuos
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.79823, p-value < 2.2e-16
Según la prueba de Breusch-Pagan esta indica la presencia de heterocedasticidad .
# Comprobar homocedasticidad (prueba de Breusch-Pagan)
library(lmtest)
bptest(modelo)
##
## studentized Breusch-Pagan test
##
## data: modelo
## BP = 1064.5, df = 7, p-value < 2.2e-16
El valor del estadístico Durbin-Watson cercano a 2 indica una autocorrelación positiva leve. Sin embargo, el p-valor bajo sugiere que la autocorrelación de los errores es significativa, lo cual puede indicar que los errores no son independientes.
# 4.3. Comprobar la independencia de los residuos (prueba de Durbin-Watson)
dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.6632, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
Residuals vs Fitted: Este gráfico muestra una ligera tendencia no lineal en los residuales, lo que sugiere que podría haber una relación no capturada por el modelo. También se observan algunos puntos con valores de residuales altos, lo que indica posibles valores atípicos.
Q-Q Plot: Los residuales estandarizados no siguen completamente la línea de normalidad, especialmente en los extremos, lo que indica que los residuales no son perfectamente normales.
Scale-Location: Este gráfico muestra una dispersión creciente de los residuales a medida que aumenta el valor ajustado, lo que sugiere heterocedasticidad (varianza no constante de los errores).
Residuals vs Leverage: Muestra algunos puntos con alta influencia (alto leverage y residuales estandarizados altos), lo que indica que algunos valores tienen un impacto significativo en el modelo.
par(mfrow=c(2,2))
plot(modelo)
Los resultados de la prueba de Multicolinealidad no muestras valores alto que indiquen que haya multicolinealidad entre las variables analizadas.
# multicolinealidad (VIF)
library(car)
vif(modelo)
## GVIF Df GVIF^(1/(2*Df))
## Area_Construida 2.303460 1 1.517715
## Estrato 1.833015 3 1.106270
## No.Habitaciones 1.464154 1 1.210022
## No.Parqueaderos 2.048146 1 1.431134
## No.Banos 2.681307 1 1.637470
Las predicciones de precios basados en la variables del modelo para un apartamento de 300 m^2 con 3 parqueaderos, 3 baños y 5 habitaciones en el estrato 5 y en el estrato 6 está entre los 707 y los 843 millones de pesos cuyos costos están acorde con el presupuesto de los clientes.
predict(modelo,list(Area_Construida = 300, No.Parqueaderos = 3, No.Banos = 3,
No.Habitaciones = 5, Estrato = "5")) # Estrato 5
## 1
## 707.2627
predict(modelo,list(Area_Construida = 300, No.Parqueaderos = 3, No.Banos = 3,
No.Habitaciones = 5, Estrato = "6")) # Estrato 5
## 1
## 843.1509
Para explorar una mejora en el desempeño del modelo se proceso un análisis con una partición de un 70% de entrenamiento y un 30% de testeo junto a una validación cruzada de k-fold con un k=10.
El modelo de regresión lineal múltiple explica el 78.45% de la variabilidad de la precio de los apartamentos, con un buen ajuste y significancia estadística en la mayoría de las variables. El modelo tiene un buen ajuste global (\(R² = 0.7845\)) y la mejora frente al modelo anterior no es muy grande es solo del 0.0001.
library(caret)
apartamentos<-read.csv2("apartamentosEspacial_df.csv", header = TRUE, sep=",")
apartamentos$Precio<-as.numeric(apartamentos$Precio)
apartamentos$Area_Construida<-as.numeric(apartamentos$Area_Construida)
apartamentos$Estrato<-as.factor(apartamentos$Estrato)
apartamentos <- na.omit(apartamentos)
set.seed(123) # Para reproducibilidad
train_index <- sample(1:nrow(apartamentos), 0.7 * nrow(apartamentos))
apartamentos_train <- apartamentos[train_index, ]
apartamentos_test <- apartamentos[-train_index, ]
control <- trainControl(method = "cv", number = 10) # 10-fold cross-validation
formula_model <- Precio ~ Area_Construida + Estrato + No.Habitaciones + No.Parqueaderos + No.Banos
modelo_cv <- train(formula_model, data = apartamentos_train, method = "lm", trControl = control)
summary(modelo_cv)
##
## Call:
## lm(formula = .outcome ~ ., data = dat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1301.71 -42.79 -1.26 40.78 825.72
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -53.02034 14.70695 -3.605 0.00032 ***
## Area_Construida 1.57792 0.05948 26.528 < 2e-16 ***
## Estrato4 29.76709 10.26441 2.900 0.00377 **
## Estrato5 46.64443 10.45617 4.461 8.61e-06 ***
## Estrato6 187.52155 12.51798 14.980 < 2e-16 ***
## No.Habitaciones -26.04348 4.38380 -5.941 3.34e-09 ***
## No.Parqueaderos 74.51076 5.45484 13.660 < 2e-16 ***
## No.Banos 46.69610 4.02516 11.601 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 106.2 on 1996 degrees of freedom
## Multiple R-squared: 0.7845, Adjusted R-squared: 0.7837
## F-statistic: 1038 on 7 and 1996 DF, p-value: < 2.2e-16
print(varImp(modelo_cv))
## lm variable importance
##
## Overall
## Area_Construida 100.000
## Estrato6 51.126
## No.Parqueaderos 45.537
## No.Banos 36.825
## No.Habitaciones 12.870
## Estrato5 6.606
## Estrato4 0.000
predicciones <- predict(modelo_cv, newdata = apartamentos_test)
# Mostrar las primeras predicciones
head(predicciones)
## 3 6 15 19 21 22
## 108.53944 78.41933 92.62057 81.57516 81.57516 86.30891
# Comparar las predicciones con los valores reales
comparacion <- data.frame(Real = apartamentos_test$Precio, Predicho = predicciones)
head(comparacion)
## Real Predicho
## 3 152 108.53944
## 6 78 78.41933
## 15 125 92.62057
## 19 135 81.57516
## 21 130 81.57516
## 22 130 86.30891
Con la información obtenida se presentó la distribución espacial de los apartamentos del sur que pueden ser obtenidas por los clientes. Se presentan los apartamentos en el estrato 5 y 6 con precios inferiores a las 850 y las ofertas en estrato 5 y 6 con los requerimientos de los clientes (Area_Construida >= 300, No. Baños == 3, No. Parqueaderos==3, No.Habitaciones == 5).
Para los apartamentos solo se encontraron dos que pueden ser satisfactorios para los clientes. El primero con el id 7512 una área construida de 300 metros, con 5 baños 6 habitaciones y 3 parqueaderos en estrato 5 y el segundo con el id 7182 con un precio de 730 millones, un área construida de 573 \(m^2\), 3 parqueaderos, 8 baños y 5 habitaciones, también en estrato 5.
require(sf)
require(leaflet)
require(leaflet.extras)
require(dplyr)
#Carga de capas espaciales
Barrios<-sf::read_sf("Cali_WGS84.gpkg", layer='Barrios')
zonas<-sf::read_sf("Zonas.gpkg", layer='Zonas_Precio_Total')
crs <- sf::st_crs("+proj=longlat +datum=WGS84 +no_defs")
datosImputadosTotales<-read.csv2("datosImputadosTotales.csv", header = TRUE, sep=",")
Apartamentos_Imputadas<-subset(datosImputadosTotales, Tipo.Vivienda == "Apartamento")
apartamentosSur<-subset(Apartamentos_Imputadas, Zona == "Zona Sur")
datos_apartamentos_sin.na<- subset(Apartamentos_Imputadas, !is.na(Longitud) & !is.na(Latitud))
Viviendas_Espacial_apartamentos <- sf::st_as_sf(datos_apartamentos_sin.na, coords = c("Longitud", "Latitud"))
Viviendas_Espacial_apartamentos <- sf::st_set_crs(Viviendas_Espacial_apartamentos, crs)
apartamentos_joined_sf <- sf::st_join(Viviendas_Espacial_apartamentos,Barrios , join = st_within)
zona_Sur<-dplyr::filter(zonas, Zonas_IDE == "Zona Sur")
Apartamentos_SurEspacial<-sf::st_intersection(zona_Sur, apartamentos_joined_sf)
E5 <- Apartamentos_SurEspacial %>%
filter( Estrato == "5", Precio < 850, Area_Construida >= 300)
E6 <- Apartamentos_SurEspacial %>%
filter( Estrato == "6", Precio < 850, Area_Construida >= 300)
ofertas5 <- Apartamentos_SurEspacial %>%
filter(Area_Construida >= 300, Estrato == "5", No.Banos >= 3, No.Parqueaderos>=3, No.Habitaciones >= 5, Precio < 850)
ofertas6 <- Apartamentos_SurEspacial %>%
filter(Area_Construida >= 300, Estrato == "6",No.Banos >= 3, No.Parqueaderos>=3, No.Habitaciones >= 5, Precio < 850)
ZonalabelsMediana <- sprintf(
"<strong></strong><strong>%s</strong>",
zonas$Zonas_IDE
) %>% lapply(htmltools::HTML)
pal1 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(E5$Precio))
pal2 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(E6$Precio))
pal3 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(ofertas5$Precio))
pal4 <- colorNumeric(
palette = "YlOrRd",
domain = na.omit(ofertas6$Precio))
preciosLabels1 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
E5$Barrio, E5$Zona, E5$Precio
) %>% lapply(htmltools::HTML)
preciosLabels2 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
E6$Barrio, E6$Zona, E6$Precio
) %>% lapply(htmltools::HTML)
preciosLabels3 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
ofertas5$Barrio, ofertas5$Zona, ofertas5$Precio
) %>% lapply(htmltools::HTML)
preciosLabels4 <- sprintf(
"<strong></strong><strong>%s</strong><br/><strong> %s</strong><br/>%g millones",
ofertas6$Barrio, E5$Zona, ofertas6$Precio
) %>% lapply(htmltools::HTML)
map <-leaflet::leaflet(height=700, width = 800)%>%
addProviderTiles(providers$CartoDB.DarkMatterNoLabels)%>%
setView(lng = -76.549478, lat = 3.3903, zoom = 13)%>%
addPolygons(data = zonas,
opacity = 1,
color = "white",
label = ZonalabelsMediana,
group = "Zona",
stroke = 0.2)%>%
addFullscreenControl(position = "topleft", pseudoFullscreen = TRUE)%>%
addLayersControl(overlayGroups = c( "Zona","Apartamentos E5", "Apartamentos E6", "Ofertas E5", "Ofertas E6"), options = layersControlOptions(collapsed = FALSE))%>%
addScaleBar(position = c("topright", "bottomright", "bottomleft", "topleft"),options = scaleBarOptions(metric = TRUE,
imperial = FALSE, updateWhenIdle = TRUE))%>%
addMapPane("ames_lines", zIndex = 430) %>%
addCircles(data = E5,
color = ~pal1(Precio),
radius = ~Precio/10,
group ="Apartamentos E5",
label = preciosLabels1,
labelOptions = labelOptions(
style = list("font-weight" = "normal",
padding = "3px 8px"),
textsize = "15px",
direction = "auto"))%>%
addCircles(data = E6,
color = ~pal2(Precio),
radius = ~Precio/10,
group ="Apartamentos E6",
label = preciosLabels2,
labelOptions = labelOptions(
style = list("font-weight" = "normal",
padding = "3px 8px"),
textsize = "15px",
direction = "auto"))%>%
addCircles(data = ofertas5,
color = ~pal3(Precio),
radius = ~Precio/10,
group ="Ofertas E5",
label = preciosLabels3,
labelOptions = labelOptions(
style = list("font-weight" = "normal",
padding = "3px 8px"),
textsize = "15px",
direction = "auto"))%>%
addLegend( position = "bottomleft", pal = pal1, values = na.omit(E5$Precio),
title = 'Precios',
opacity = 1)%>%
addMiniMap(tiles = "CartoDB.Voyager")
map
Figura 12. Mapa de la distribución de las casas de la zona norte de Cali que están dentro del conjunto de datos de C&A.
A pesar de la amplia oferta existente en el mercado inmobiliario de Cali, no se ha encontrado disponibilidad de una vivienda que cumpla exactamente con las características específicas que los clientes buscan. Esta situación representa un desafío, ya que los compradores tienen expectativas precisas en cuanto a espacios como parqueaderos, baños, y habitaciones. No obstante, la empresa C&A tiene la capacidad de ofrecer un portafolio más extenso en dichas zonas, brindando opciones que, si bien no cumplen exactamente con todos los requerimientos iniciales de los clientes, presentan ventajas notables.
Por ejemplo, se han identificado propiedades que, aunque no coinciden al 100% con las especificaciones deseadas, ofrecen precios competitivos, inferiores al presupuesto establecido, y características similares que podrían resultar más beneficiosas. Estas alternativas permitirán a los clientes reevaluar sus prioridades y considerar opciones que, en última instancia, podrían superar sus expectativas iniciales.
En cuanto a las casas disponibles, se identificaron varias oportunidades que ofrecen una excelente relación características-precio. Algunas de ellas, además, cuentan con características que incluso mejores que las deseadas. Para los apartamentos, la oferta es más limitada pero hay dos muy buenas opciones que los clientes podrían encontrar como un muy buen negocio ya que están por encima de las exigencias y con un precio inferior.
El conjunto inicial de los datos se compone 8322 registros de características de las viviendas encontradas en el mercado inmobiliario de Cali.
Para analizar los datos por los tipos de vivienda requeridos se separaron los conjuntos de datos entre Apartamentos y Casas. El análisis requirió filtrar las casas que solo pertenecen a la Zona Norte y los apartamentos que pertenecen a la Zona Sur.
Para abordar el problema inicial se aplicó un filtro de registros para las casas que pertenecer a la zona norte según el conjunto de datos (Tabla 1).
Tabla 1. Estadísticas descriptivas de los precios y el área construida por tipo de vivienda en el mercado inmobiliario en Cali.
require(reactable)
datosImputadosTotales<-read.csv2("datosImputadosTotales.csv", header = TRUE, sep=",")
Casas_Imputadas<-subset(datosImputadosTotales, Tipo.Vivienda == "Casa")
casasNorte<-subset(Casas_Imputadas, Zona == "Zona Norte")
reactable(casasNorte)
Cuando se realizó la revisión de la distribución espacial con el filtro de registros, se observó que la etiqueta de “Zona Norte” no corresponde a las zonas de la Ciudad de Cali, designadas por la Infraestructura de Datos Espaciales del Municipio (Figura 12). Por esta razón se decidió realizar un filtro espacial basados en las capas espaciales de las zonas de Cali de la IDE- Municipio de Cali.
Para el análisis de las casas se filtraron los datos espacialmente y se exportaron para realizar los análisis posteriores.
require(sf)
require(leaflet)
require(leaflet.extras)
#Carga de capas espaciales
Barrios<-sf::read_sf("Cali_WGS84.gpkg", layer='Barrios')
zonas<-sf::read_sf("Zonas.gpkg", layer='Zonas_Precio_Total')
crs <- sf::st_crs("+proj=longlat +datum=WGS84 +no_defs")
#Carga de datos iniciales
datosImputadosTotales<-read.csv2("datosImputadosTotales.csv", header = TRUE, sep=",")
#Filtración de lso registros de las casas del
Casas_Imputadas<-subset(datosImputadosTotales, Tipo.Vivienda == "Casa")
casasNorte<-subset(Casas_Imputadas, Zona == "Zona Norte")
datos_Vivienda_sin.na<- subset(casasNorte, !is.na(Longitud) & !is.na(Latitud))
Viviendas_Espacial <- sf::st_as_sf(datos_Vivienda_sin.na, coords = c("Longitud", "Latitud"))
Viviendas_Espacial <- sf::st_set_crs(Viviendas_Espacial, crs)
joined_sf <- sf::st_join(Viviendas_Espacial,Barrios , join = st_within)
datos_casas_sin.na<- subset(Casas_Imputadas, !is.na(Longitud) & !is.na(Latitud))
Viviendas_Espacial_Casas <- sf::st_as_sf(datos_casas_sin.na, coords = c("Longitud", "Latitud"))
Viviendas_Espacial_Casas <- sf::st_set_crs(Viviendas_Espacial_Casas, crs)
Casas_joined_sf <- sf::st_join(Viviendas_Espacial_Casas,Barrios , join = st_within)
zona_Norte<-dplyr::filter(zonas, Zonas_IDE == "Zona Norte")
casas_NorteEspacial<-sf::st_intersection(zona_Norte, Casas_joined_sf)
ZonalabelsMediana <- sprintf(
"<strong></strong><strong>%s</strong>",
zonas$Zonas_IDE
) %>% lapply(htmltools::HTML)
map <-leaflet::leaflet(height=700, width = 800)%>%
addProviderTiles(providers$CartoDB.DarkMatterNoLabels)%>%
setView(lng = -76.5225, lat = 3.42, zoom = 11.5)%>%
addPolygons(data = zonas,
opacity = 1,
color = "white",
label = ZonalabelsMediana,
group = "Zona",
stroke = 0.2)%>%
# addPolygons(data = Barrios, group = "Barrios", color = "grey",stroke = 0.2, opacity = 1)%>%
addFullscreenControl(position = "topleft", pseudoFullscreen = TRUE)%>%
addLayersControl(overlayGroups = c( "Zona","Casas Norte Original", "Filtro Espacial"), options = layersControlOptions(collapsed = FALSE))%>%
addScaleBar(position = c("topright", "bottomright", "bottomleft", "topleft"),options = scaleBarOptions(metric = TRUE,
imperial = FALSE, updateWhenIdle = TRUE))%>%
addMapPane("ames_lines", zIndex = 430) %>%
addCircles(data = joined_sf,
color = "red",
group ="Casas Norte Original"
)%>%
addCircles(data = casas_NorteEspacial,
color = "blue",
group ="Filtro Espacial"
)%>%
addMiniMap(tiles = "CartoDB.Voyager")
map
Figura 12. Mapa de la distribución de las casas de la zona norte de Cali que están dentro del conjunto de datos de C&A.
Para los apartamentos se aplicó un filtro de registros sobre aquellso que pertenecen a la zona sur (Tabla 2).
require(reactable)
datosImputadosTotales<-read.csv2("datosImputadosTotales.csv", header = TRUE, sep=",")
Apartamento_Imputadas<-subset(datosImputadosTotales, Tipo.Vivienda == "Apartamento")
ApartamentoNorte<-subset(Apartamento_Imputadas, Zona == "Zona Norte")
reactable(ApartamentoNorte)
Similar a lo que ocurre con las casas, la distribución espacial de los apartamentos no corresponde con la etiqueta de los registros para la zona sur (Figura 13). Se decidió dejar el filtro espacial para hacer un análisis que correspondiera a lo que se observa en dicha distribución.
require(sf)
require(leaflet)
require(leaflet.extras)
Barrios<-sf::read_sf("Cali_WGS84.gpkg", layer='Barrios')
zonas<-sf::read_sf("Zonas.gpkg", layer='Zonas_Precio_Total')
crs <- sf::st_crs("+proj=longlat +datum=WGS84 +no_defs")
datosImputadosTotales<-read.csv2("datosImputadosTotales.csv", header = TRUE, sep=",")
Apartamentos_Imputadas<-subset(datosImputadosTotales, Tipo.Vivienda == "Apartamento")
apartamentosSur<-subset(Apartamentos_Imputadas, Zona == "Zona Sur")
datos_Vivienda_sin.na<- subset(apartamentosSur, !is.na(Longitud) & !is.na(Latitud))
Viviendas_Espacial <- sf::st_as_sf(datos_Vivienda_sin.na, coords = c("Longitud", "Latitud"))
Viviendas_Espacial <- sf::st_set_crs(Viviendas_Espacial, crs)
joined_sf <- sf::st_join(Viviendas_Espacial,Barrios , join = st_within)
datos_apartamentos_sin.na<- subset(Apartamentos_Imputadas, !is.na(Longitud) & !is.na(Latitud))
Viviendas_Espacial_apartamentos <- sf::st_as_sf(datos_apartamentos_sin.na, coords = c("Longitud", "Latitud"))
Viviendas_Espacial_apartamentos <- sf::st_set_crs(Viviendas_Espacial_apartamentos, crs)
apartamentos_joined_sf <- sf::st_join(Viviendas_Espacial_apartamentos,Barrios , join = st_within)
zona_Sur<-dplyr::filter(zonas, Zonas_IDE == "Zona Sur")
Apartamentos_SurEspacial<-sf::st_intersection(zona_Sur, apartamentos_joined_sf)
ZonalabelsMediana <- sprintf(
"<strong></strong><strong>%s</strong>",
zonas$Zonas_IDE
) %>% lapply(htmltools::HTML)
map <-leaflet::leaflet(height=700, width = 800)%>%
addProviderTiles(providers$CartoDB.DarkMatterNoLabels)%>%
setView(lng = -76.5225, lat = 3.42, zoom = 11.5)%>%
addPolygons(data = zonas,
opacity = 1,
color = "white",
label = ZonalabelsMediana,
group = "Zona",
stroke = 0.2)%>%
addFullscreenControl(position = "topleft", pseudoFullscreen = TRUE)%>%
addLayersControl(overlayGroups = c( "Zona","Apartamentos Sur Original", "Filtro Espacial"),
options = layersControlOptions(collapsed = FALSE))%>%
addScaleBar(position = c("topright", "bottomright", "bottomleft", "topleft"),
options = scaleBarOptions(metric = TRUE,
imperial = FALSE,
updateWhenIdle = TRUE))%>%
addMapPane("ames_lines", zIndex = 430) %>%
addCircles(data = joined_sf,
color = "red",
group ="Apartamentos Sur Original"
)%>%
addCircles(data = Apartamentos_SurEspacial,
color = "blue",
group ="Filtro Espacial"
)%>%
addMiniMap(tiles = "CartoDB.Voyager")
map
Figura 7. Distribución de los apartamentos y sus precios en el mercado inmmobiliario en Cali.