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, Maria recibió una carta solicitando asesoria 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:
Filtro de datos por zonas
Realice un filtro a la base de datos e incluya solo las ofertas de: base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. ¿Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por qué?).
Creamos una nueva variable llamada vivienda_filtrada la cual ubica casas dependiendo de su zona.
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4057 Zona N… 02 6 750 445 NA 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
##
## Casa
## Zona Norte 722
Se realiza una ánalisis espacial donde se muestran las viviendas del norte y se comparan los datos con el cargue de los diferentes SHP
Instalación de Librerías para manejo espacial
Se presenta en un mapa las viviendas
mapa <- leaflet() %>% addTiles() %>% addCircles(lng = vivienda_filtrada\(longitud, lat = vivienda_filtrada\)latitud)
mapa
Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio del apartamento) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.
Despues de hacer este analisis se encuentra que la variable piso con 2638 y parqueaderos cuenta con 1605 valores nulos. Con respecto a las demas varibles en promedio se tienen un maximo de 3 valores nulos.
Se realiza una revisión de las variables y se procede a hacer un análisis exploratorio por variable, filtrando por la variable apartamento y se revisa de acuerdo al precio y sus otras variables independiente
vivienda_apartamento <- subset(vivienda, tipo == "Apartamento")
apply(X = is.na(vivienda_apartamento), MARGIN = 2, FUN = sum)
## id zona piso estrato preciom areaconst
## 0 0 1381 0 0 0
## parqueaderos banios habitaciones tipo barrio longitud
## 869 0 0 0 0 0
## latitud
## 0
#Precio
Se revisa la relación de precios de los apartamentos teniendo 5100 apartamentos
plot_ly(vivienda_apartamento, x = ~preciom, type = "histogram")%>%
layout(title = "Grafica distribución de precios")
Se observa en el histograma que elmayor número de viviendas se encuentran en un rango mayor a 500M
#Baños
plot_ly(vivienda_apartamento, x = ~vivienda_apartamento$banios, type = "histogram")%>%
layout(title = "Grafica Número de Baños")
En la grafica anterior podemos ver que la mayoría de ofertas tienen 2 a 4 baños, es interesante observar que hay apartamentos que tienen 8 baños, lo cual llama la atención revisar la descripción de estas viviendas, adicional se observa que hay viviendas que tienen 0 baños por lo cual procederemos a eliminarlos ya que no cumple con las condiciones de la asesoría planteada con anterioridad.
vivienda_apartamento=vivienda_apartamento[vivienda_apartamento$banios!=0,]
summary(vivienda_apartamento$banios)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.000 2.000 2.000 2.624 3.000 8.000
#Habitaciones
plot_ly(vivienda_apartamento, x = ~habitaciones, type = "histogram")%>%
layout(title = "Grafica distribución de habitaciones")
Se observa el número de habitaciones con valores de 0. Por lo que se eliminan los registros con cero habitaciones.
vivienda_apartamento=vivienda_apartamento[vivienda_apartamento$habitaciones!=0,]
summary(vivienda_apartamento$habitaciones)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.000 3.000 3.000 2.984 3.000 9.000
#Estrato Socioeconomico
plot_ly(vivienda, labels = ~estrato, type = 'pie') %>%
layout(title = "Distribución de estrato")
Observando la grafica, se aprecia que el estrato 5 presenta la mayor concentración de apartamentos con un 33%, seguido de 4 con un 25%, 6 con 23% y 3 con 23%.
#Zona
plot_ly(vivienda_apartamento, labels = ~zona, type = 'pie') %>%
layout(title = "Distribución de zona")
Observando la grafica de pi se aprecia que el 54% de las viviendas de apartamento estan estan en la Zona Sur y el 23% en Norte.
#area construida
Encontramos que el valor mínimo de área es de 40 y el máximo de 932 metros cuadrados y la mayoría de los registros se encuentran desplazados hacia la izquierda con valores menores a los 400 metros cuadrados.
plot_ly(vivienda_apartamento, x = ~areaconst, type = "histogram") %>%
layout(title = "Distribución de areaconst")
summary(vivienda_apartamento$areaconst)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 40.0 68.0 90.0 112.5 130.0 932.0
summary(vivienda_apartamento)
## id zona piso estrato
## Min. : 3 Length:5074 Length:5074 Min. :3.000
## 1st Qu.:2178 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4283 Mean :4.727
## 3rd Qu.:6557 3rd Qu.:6.000
## Max. :8317 Max. :6.000
##
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 40.0 Min. : 1.000 Min. :1.000
## 1st Qu.: 175.0 1st Qu.: 68.0 1st Qu.: 1.000 1st Qu.:2.000
## Median : 276.0 Median : 90.0 Median : 1.000 Median :2.000
## Mean : 366.7 Mean :112.5 Mean : 1.566 Mean :2.623
## 3rd Qu.: 430.0 3rd Qu.:130.0 3rd Qu.: 2.000 3rd Qu.:3.000
## Max. :1950.0 Max. :932.0 Max. :10.000 Max. :8.000
## NA's :857
## habitaciones tipo barrio longitud
## Min. :1.000 Length:5074 Length:5074 Min. :-76.59
## 1st Qu.:3.000 Class :character Class :character 1st Qu.:-76.54
## Median :3.000 Mode :character Mode :character Median :-76.53
## Mean :2.984 Mean :-76.53
## 3rd Qu.:3.000 3rd Qu.:-76.52
## Max. :9.000 Max. :-76.46
##
## latitud
## Min. :3.334
## 1st Qu.:3.380
## Median :3.419
## Mean :3.419
## 3rd Qu.:3.453
## Max. :3.498
##
str(vivienda_apartamento)
## spc_tbl_ [5,074 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:5074] 1212 1724 2326 4386 7497 ...
## $ zona : chr [1:5074] "Zona Norte" "Zona Norte" "Zona Norte" "Zona Norte" ...
## $ piso : chr [1:5074] "01" "01" "01" "01" ...
## $ estrato : num [1:5074] 5 5 4 5 6 4 5 3 3 6 ...
## $ preciom : num [1:5074] 260 240 220 310 520 320 385 100 175 820 ...
## $ areaconst : num [1:5074] 90 87 52 137 98 108 103 49 80 377 ...
## $ parqueaderos: num [1:5074] 1 1 2 2 2 2 2 NA 1 1 ...
## $ banios : num [1:5074] 2 3 2 3 2 3 2 1 2 4 ...
## $ habitaciones: num [1:5074] 3 3 3 4 2 3 3 2 3 4 ...
## $ tipo : chr [1:5074] "Apartamento" "Apartamento" "Apartamento" "Apartamento" ...
## $ barrio : chr [1:5074] "acopi" "acopi" "acopi" "acopi" ...
## $ longitud : num [1:5074] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:5074] 3.46 3.37 3.43 3.38 3.44 ...
## - attr(*, "spec")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ";"
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
Se revisan los dtos y se procede a eliminar estos valores para la futura creación de un modelo, la cual nos permite preparar los datos.
vivienda_apartamento$estrato=as.numeric(vivienda_apartamento$estrato)
vivienda_1 <- na.omit(vivienda_apartamento[c("preciom","areaconst","estrato","banios","habitaciones", "parqueaderos")])
library(GGally)
cor_1=vivienda_1[,c("preciom","areaconst","estrato","banios","habitaciones", "parqueaderos")]
gcor<-ggplotly(ggpairs(cor_1))
gcor
Una vez todas las variables son del tipo correcto realizamos el análisis de correlación, para el caso de preciom y las variables predictoras habitaciones, banios, estrato, areaconst obtuvimos los siguientes resultados:
Las variables independientes indican que hay un grado de correlación positiva con el valor de los apartamentos donde se explican a continuación.
precio - habitaciones: Esto indica una correlación positiva débil con un valor de 0.294, lo que sugiere que a medida que el número de habitaciones en una propiedad aumenta, el precio también tiende a aumentar.
Precio - Baños: Esta relación es de 0.736, esto indica que es una relación positiva medianamente fuerte, además que a medida que aumenta el numero de baños tambien lo hace el precio de la vivienda.
precio - areacost: Esto indica una correlación positiva fuerte, lo que sugiere que a medida que el tamaño de la propiedad (área construida) aumenta, el precio también tiende a aumentar, y la relación es significativamente más fuerte.
Luego procedemos a revisar la correlación que tienen las variables predictoras entre sí:
Precio - Estrato: Esta relación es de 0.683, esto indica que es una relación positiva medianamente fuerte, por lo cual a medida que aumenta el estrato tambien lo hace el precio.
Precio - Parqueaderos: Esta relación es de 0.746, esto indica una relación positiva medianamente fuerte y es probabable que entre mas parqueaderos tenga una vivienda entonces el precio aumentará respectivamente.
Después de haber evaluado la correlación entre las variables, se ha observado que puede haber un problema de multicolinealidad entre los pares de variables (Baños y Habitaciones) y (Baños y Parqueaderos), ya que presentan una correlación positiva moderadamente fuerte, respectivamente. Por lo tanto, se recomienda utilizar un método de selección de variables o excluir una de ellas para evitar la multicolinealidad.
mod_multi = lm(vivienda_1$preciom~vivienda_1$areaconst+vivienda_1$estrato+vivienda_1$habitaciones+vivienda_1$parqueaderos+vivienda_1$banios, data = vivienda_1)
summary(mod_multi)
##
## Call:
## lm(formula = vivienda_1$preciom ~ vivienda_1$areaconst + vivienda_1$estrato +
## vivienda_1$habitaciones + vivienda_1$parqueaderos + vivienda_1$banios,
## data = vivienda_1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1754.63 -56.73 -0.11 48.68 1004.21
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -252.78084 16.06598 -15.73 <2e-16 ***
## vivienda_1$areaconst 2.07225 0.04897 42.31 <2e-16 ***
## vivienda_1$estrato 53.63903 3.04217 17.63 <2e-16 ***
## vivienda_1$habitaciones -50.36964 3.92325 -12.84 <2e-16 ***
## vivienda_1$parqueaderos 90.53152 4.25171 21.29 <2e-16 ***
## vivienda_1$banios 55.81867 3.44877 16.18 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 136.3 on 4211 degrees of freedom
## Multiple R-squared: 0.7893, Adjusted R-squared: 0.789
## F-statistic: 3155 on 5 and 4211 DF, p-value: < 2.2e-16
Este modelo de regresión lineal múltiple se ajusta a los datos de la variable “preciom” utilizando cinco variables predictoras: “areaconst”, “estrato”, “habitaciones”, “parqueaderos” y “banios”. El modelo tiene la siguiente forma:
preciom = -252.78 + 2.07 * areaconst + 53.64 * estrato - 50.37 * habitaciones + 90.53 * parqueaderos + 55.82 * banios
El valor de “Multiple R-squared” indica el coeficiente de determinación, que es una medida de la proporción de la variabilidad en la variable dependiente que se explica por el modelo. En este caso, el coeficiente de determinación es 0.7893, lo que significa que aproximadamente el 79% de la variabilidad en la variable “preciom” se puede explicar por las variables predictoras incluidas en el modelo. En este caso, el valor de “Adjusted R-squared” es 0.789, lo que significa que después de tener en cuenta el número de variables predictoras en el modelo, aproximadamente el 79% de la variabilidad en la variable “preciom” se puede explicar por las variables predictoras incluidas.
De igual manera el valor de “F-statistic” es 3155 y el valor de “p-value” es menor que 2.2e-16, lo que indica que el modelo es significativo en términos globales.
Se propone aplicar forward stepwise regression para estimar el modelo de manera gradual, partiendo de un modelo con solo el intercepto y en cada paso se incorpora una variable hasta cumplir con el criterio de parada.
Se define un modelo Y=b0
mod_b0 = lm(preciom~1, data = vivienda_1)
Se define un modelo con todas las predictoras
mod_all = lm(preciom~areaconst+estrato+habitaciones+parqueaderos+banios, data = vivienda_1)
Se aplica el proceso de forward stepwise regression
forward <- step(mod_b0, direction='forward', scope=formula(mod_all), trace=0)
Visualización de los resultados
forward$anova
## Step Df Deviance Resid. Df Resid. Dev AIC
## 1 NA NA 4216 371086534 48012.83
## 2 + areaconst -1 254217975 4215 116868558 43142.57
## 3 + parqueaderos -1 21710864 4214 95157694 42277.91
## 4 + estrato -1 11193504 4213 83964190 41752.17
## 5 + banios -1 2713959 4212 81250231 41615.62
## 6 + habitaciones -1 3060615 4211 78189616 41455.70
summary(forward)
##
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + estrato + banios +
## habitaciones, data = vivienda_1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1754.63 -56.73 -0.11 48.68 1004.21
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -252.78084 16.06598 -15.73 <2e-16 ***
## areaconst 2.07225 0.04897 42.31 <2e-16 ***
## parqueaderos 90.53152 4.25171 21.29 <2e-16 ***
## estrato 53.63903 3.04217 17.63 <2e-16 ***
## banios 55.81867 3.44877 16.18 <2e-16 ***
## habitaciones -50.36964 3.92325 -12.84 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 136.3 on 4211 degrees of freedom
## Multiple R-squared: 0.7893, Adjusted R-squared: 0.789
## F-statistic: 3155 on 5 and 4211 DF, p-value: < 2.2e-16
Este modelo busca explicar cómo varía el precio de una vivienda en función de varias variables predictoras (o independientes): área construida (areaconst), número de parqueaderos (parqueaderos), estrato, número de baños (banios) y número de habitaciones (habitaciones).
En este caso, la fórmula es preciom ~ areaconst + parqueaderos + estrato + banios + habitaciones, lo que significa que se está modelando el precio (preciom) como una función de las variables predictoras mencionadas.
Cada coeficiente indica la cantidad en que se espera que cambie el precio de la vivienda por unidad de cambio en la variable correspondiente, manteniendo todas las demás variables constantes. Por ejemplo, se espera que el precio de la vivienda aumente en $2.07 por cada unidad adicional de área construida, manteniendo constante el número de baños, el número de habitaciones, el estrato y el número de parqueaderos. Los coeficientes que tienen valores p menores que 0,05 son considerados estadísticamente significativos. En este caso, todas las variables predictoras son significativas, lo que indica que todas ellas tienen un efecto significativo en el precio de la vivienda.
El coeficiente de determinación múltiple (R-cuadrado múltiple) es 0,7893, lo que significa que aproximadamente el 79% de la variabilidad en el precio de la vivienda se explica por las variables predictoras incluidas en el modelo. El estadístico F y su valor p correspondiente indican si el modelo en general es significativo. En este caso, el valor p es muy bajo, lo que indica que el modelo en general es altamente significativo. En resumen, el modelo sugiere que el precio de una vivienda está altamente influenciado por su área construida, número de parqueaderos, estrato, número de baños y número de habitaciones.
interprete los resultados (no es necesario corregir en caso de presentar problemas solo realizar sugerencias de que se podría hacer).
par(mfrow = c(2,2))
plot(mod_multi)
La verificación de supuestos sobre el error implica examinar cuatro
aspectos principales. Primero, se verifica si los errores del modelo
tienen una media cero y un comportamiento aleatorio. Segundo, se
determina si los errores tienen una varianza constante y no muestran
ningún patrón en el gráfico de residuales vs. valores ajustados.
Tercero, se evalúa si los errores se distribuyen normalmente a través de
la observación del gráfico de normalidad. Por último, se comprueba si
los errores son independientes y no están correlacionados entre sí.
Para esta predicción tomaremos el modelo que tiene en cuenta la mayoría de variables de entrada de esta solicitud, como resultado obtenemos que para la primera solicitud el precio estimado es de 252.976.
Teniendo en cuenta las caracteristicas de la Vivienda 1 se hace un filtro de aspectos relevantes y se omiten algunas caracteristicas que no sean tan discriminatorias.
Ofertas <- filter(vivienda, zona == "Zona Norte" &
tipo == "Casa" & parqueaderos == 1 & banios == 2 & habitaciones >= 4 & preciom <= 350)
Ofertas <- Ofertas[order(-Ofertas$areaconst),]
Ofertas <- head(Ofertas, 5)
head(Ofertas, 5)
## # A tibble: 5 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1943 Zona N… <NA> 5 350 346 1 2 4
## 2 309 Zona N… <NA> 3 250 240 1 2 4
## 3 477 Zona N… <NA> 3 240 240 1 2 4
## 4 725 Zona N… <NA> 3 350 200 1 2 6
## 5 612 Zona N… 01 3 270 196 1 2 4
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Ofertas1 <- na.omit(Ofertas[c("latitud", "longitud", "preciom")])
Ofertas1$latitud = gsub(" ", "", paste("3.", substr(Ofertas1$latitud, start = 2, stop = 5) ))
Ofertas1$longitud = gsub(" ", "", paste("-76.", substr(Ofertas1$longitud, start = 4, stop = 5) ))
Ofertas$preciom <- as.character(Ofertas$preciom)
Ofertas$latitud <- as.numeric(Ofertas$latitud)
Ofertas$longitud <- as.numeric(Ofertas$longitud)
Ofertas$preciom <- as.character(Ofertas$preciom)
colores <- colorFactor(palette = "Set1", domain = Ofertas$preciom)
mapa <- leaflet(Ofertas) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(preciom), radius = 4)
mapa
Primero vamos a predecir el precio de una vivienda con las caracteristicas del segundo caso.
invisible(predict(mod_multi,list(areaconst=300,parqueaderos=3,estrato=6,habitaciones=5, banios=3)))
## 9
## 962.619
Tomando los valores maximos de la vivienda 9 obtuvimos una predicción de 962.619
Ahora mostraremos 5 ofertas donde se cumplan algunas condiciones relevantes y que estan disponibles en las ofertas.
Ofertas2 <- filter(vivienda, zona == "Zona Sur" & tipo == "Apartamento" & parqueaderos >= 3 & banios >= 3 & habitaciones >= 4 & preciom <= 850)
Ofertas2 <- Ofertas2[order(-Ofertas2$areaconst),]
Ofertas2 <- head(Ofertas2, 5)
head(Ofertas2, 5)
## # A tibble: 5 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7182 Zona S… <NA> 5 730 573 3 8 5
## 2 6868 Zona S… 03 3 370 300 3 6 5
## 3 7512 Zona S… <NA> 5 670 300 3 5 6
## 4 6175 Zona S… 05 5 350 270 3 3 4
## 5 8036 Zona S… <NA> 5 530 256 3 5 5
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
library(leaflet)
Ofertas2 <- na.omit(Ofertas2[c("latitud", "longitud", "preciom")])
colores <- colorFactor(palette = "Set1", domain = Ofertas$preciom)
mapa <- leaflet(Ofertas2) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(preciom), radius = 4)
mapa