Enunciado

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 baños 2 3 habitaciones 4 5 estrato 4 o 5 5 o 6 zona Norte Sur crédito preaprobado 350 millones 850 millones

Ayude a María a responder la solicitud, mediante técnicas modelación que usted conoce. Ella requiere le envíe un informe ejecutivo donde analice los dos casos y sus recomendaciones (Informe). Como soporte del informe debe anexar las estimaciones, validaciones y comparación de modelos requeridos (Anexos) .

Vivienda 1

Punto 1

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 que?).

Base de datos y variables

library(paqueteMODELOS)
data("vivienda")

Reconocimiento de las variables

head(vivienda,10)

Se identifican 13 variables

Realizamos una revisión de el contenido de estas variables

summary(vivienda)
##        id           zona               piso              estrato     
##  Min.   :   1   Length:8322        Length:8322        Min.   :3.000  
##  1st Qu.:2080   Class :character   Class :character   1st Qu.:4.000  
##  Median :4160   Mode  :character   Mode  :character   Median :5.000  
##  Mean   :4160                                         Mean   :4.634  
##  3rd Qu.:6240                                         3rd Qu.:5.000  
##  Max.   :8319                                         Max.   :6.000  
##  NA's   :3                                            NA's   :3      
##     preciom         areaconst       parqueaderos        banios      
##  Min.   :  58.0   Min.   :  30.0   Min.   : 1.000   Min.   : 0.000  
##  1st Qu.: 220.0   1st Qu.:  80.0   1st Qu.: 1.000   1st Qu.: 2.000  
##  Median : 330.0   Median : 123.0   Median : 2.000   Median : 3.000  
##  Mean   : 433.9   Mean   : 174.9   Mean   : 1.835   Mean   : 3.111  
##  3rd Qu.: 540.0   3rd Qu.: 229.0   3rd Qu.: 2.000   3rd Qu.: 4.000  
##  Max.   :1999.0   Max.   :1745.0   Max.   :10.000   Max.   :10.000  
##  NA's   :2        NA's   :3        NA's   :1605     NA's   :3       
##   habitaciones        tipo              barrio             longitud     
##  Min.   : 0.000   Length:8322        Length:8322        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   : 3.605                                         Mean   :-76.53  
##  3rd Qu.: 4.000                                         3rd Qu.:-76.52  
##  Max.   :10.000                                         Max.   :-76.46  
##  NA's   :3                                              NA's   :3       
##     latitud     
##  Min.   :3.333  
##  1st Qu.:3.381  
##  Median :3.416  
##  Mean   :3.418  
##  3rd Qu.:3.452  
##  Max.   :3.498  
##  NA's   :3

Base para trabajar

Filtro para la base 1: casas de la zona norte de la ciudad

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.2.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
baseinicial <- filter(vivienda, zona == "Zona Norte"& tipo == "Casa")
head(baseinicial, 3000)

Mapa

# Creación de mapa con flecha de norte y barra de escala
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.2.3
library(sf)
## Warning: package 'sf' was built under R version 4.2.3
## Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.2.3
mapa_casas_norte1<-leaflet(baseinicial) %>%
 addTiles() %>%
 addCircleMarkers(lng=~longitud,lat=~latitud,radius=3)

mapa_casas_norte1

Se hace evidente que no todas las viviendas se ubican en la zona norte. Es posible que se deba a errores en la digitación o en el levantamiento de la información de las latitudes y longitudes por lo que realizar un análisis que contemple estas variables no es acertado.

Se define insertar una nueva variable ajustando la zona de acuerdo a la latitud y longitud y se realizará tomando como centro en Cali la Latitud 3.409821 (Es un punto definido al azar como centro de la ciudad) . Todo lo que quede al norte de ese punto será definido como Zona Norte y lo que esté al sur de ese punto será definido como Zona Sur

Ajuste de localización

vivienda2<- vivienda %>% 
    dplyr::filter(areaconst >=0) %>%
    mutate(Nueva_Zona= case_when(latitud<3.409821~"New Zona Sur", latitud>3.409822~"New Zona Norte")) %>% 
    arrange(areaconst)

vivienda2

Con este ajuste aseguramos que las viviendas que podamos recomendar estén realmente en la zona de la ciudad solicitada teniendo en cuenta que por ahora, solo se habla de norte y sur. Una solución más sólida se presentaría en caso de requerir utilizar otras zonas como occidente y oriente pero por ahora, esta solución ayuda con el proceso.

Se realiza de nuevo el filtro para definir las casas en la zona norte de la ciudad.

Ajuste a la Zona

Filtro para la base 1: casas de la zona norte de la ciudad

library(dplyr)
base1 <- filter(vivienda2, Nueva_Zona == "New Zona Norte"& tipo == "Casa")
head(base1, 3000)
# Creación de mapa con flecha de norte y barra de escala
library(leaflet)
library(sf)
library(ggplot2)
mapa_casas_norte<-leaflet(base1) %>%
 addTiles() %>%
 addCircleMarkers(lng=~longitud,lat=~latitud,radius=3)

mapa_casas_norte

Punto 2

Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) 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.

Corelación con las variables

Inicialmente realizamos una exploración previa para abordar los datos

Exploración previa

library(dplyr)
glimpse(base1)
## Rows: 1,693
## Columns: 14
## $ id           <dbl> 502, 4485, 5050, 519, 481, 2817, 628, 5745, 5448, 487, 39…
## $ zona         <chr> "Zona Norte", "Zona Oriente", "Zona Oriente", "Zona Norte…
## $ piso         <chr> NA, NA, NA, "02", NA, "03", NA, "03", "05", "03", NA, NA,…
## $ estrato      <dbl> 3, 3, 3, 5, 3, 3, 3, 4, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, …
## $ preciom      <dbl> 190, 90, 105, 125, 131, 220, 100, 240, 340, 198, 130, 77,…
## $ areaconst    <dbl> 30, 40, 45, 45, 46, 48, 53, 54, 55, 55, 56, 58, 58, 60, 6…
## $ parqueaderos <dbl> 1, NA, NA, NA, NA, NA, NA, 1, 1, NA, NA, NA, 1, 1, NA, NA…
## $ banios       <dbl> 2, 1, 1, 2, 1, 2, 1, 2, 4, 2, 2, 1, 2, 1, 2, 1, 1, 3, 2, …
## $ habitaciones <dbl> 3, 3, 3, 3, 3, 2, 3, 3, 4, 4, 3, 2, 3, 3, 2, 2, 2, 2, 2, …
## $ tipo         <chr> "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "…
## $ barrio       <chr> "zona norte", "villa del lago", "compartir", "villa de ve…
## $ longitud     <dbl> -76.49763, -76.53198, -76.53464, -76.49800, -76.49700, -7…
## $ latitud      <dbl> 3.47273, 3.45165, 3.44987, 3.47600, 3.42500, 3.43391, 3.4…
## $ Nueva_Zona   <chr> "New Zona Norte", "New Zona Norte", "New Zona Norte", "Ne…
# Convertir a caracter
base1$estrato <- as.character(base1$estrato)
glimpse(base1)
## Rows: 1,693
## Columns: 14
## $ id           <dbl> 502, 4485, 5050, 519, 481, 2817, 628, 5745, 5448, 487, 39…
## $ zona         <chr> "Zona Norte", "Zona Oriente", "Zona Oriente", "Zona Norte…
## $ piso         <chr> NA, NA, NA, "02", NA, "03", NA, "03", "05", "03", NA, NA,…
## $ estrato      <chr> "3", "3", "3", "5", "3", "3", "3", "4", "3", "3", "4", "3…
## $ preciom      <dbl> 190, 90, 105, 125, 131, 220, 100, 240, 340, 198, 130, 77,…
## $ areaconst    <dbl> 30, 40, 45, 45, 46, 48, 53, 54, 55, 55, 56, 58, 58, 60, 6…
## $ parqueaderos <dbl> 1, NA, NA, NA, NA, NA, NA, 1, 1, NA, NA, NA, 1, 1, NA, NA…
## $ banios       <dbl> 2, 1, 1, 2, 1, 2, 1, 2, 4, 2, 2, 1, 2, 1, 2, 1, 1, 3, 2, …
## $ habitaciones <dbl> 3, 3, 3, 3, 3, 2, 3, 3, 4, 4, 3, 2, 3, 3, 2, 2, 2, 2, 2, …
## $ tipo         <chr> "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "…
## $ barrio       <chr> "zona norte", "villa del lago", "compartir", "villa de ve…
## $ longitud     <dbl> -76.49763, -76.53198, -76.53464, -76.49800, -76.49700, -7…
## $ latitud      <dbl> 3.47273, 3.45165, 3.44987, 3.47600, 3.42500, 3.43391, 3.4…
## $ Nueva_Zona   <chr> "New Zona Norte", "New Zona Norte", "New Zona Norte", "Ne…

Revisión de información

verificamos los NA que tengamos en la base

sum(is.na(base1$zona)) # NA en zona
## [1] 0
sum(is.na(base1$piso)) # NA en  piso
## [1] 729
sum(is.na(base1$estrato)) # NA en estrato
## [1] 0
sum(is.na(base1$preciom)) # NA en preciom
## [1] 0
sum(is.na(base1$areaconst)) # NA en areaconst
## [1] 0
sum(is.na(base1$parqueaderos)) # NA en parqueaderos
## [1] 548
sum(is.na(base1$banios)) # NA en baños
## [1] 0
sum(is.na(base1$habitaciones)) # NA en habitaciones
## [1] 0
sum(is.na(base1$tipo)) # NA en tipo
## [1] 0
sum(is.na(base1$barrio)) # NA en barrio
## [1] 0
sum(is.na(base1$longitud)) # NA en longitud
## [1] 0
sum(is.na(base1$latitud)) # NA en latitud
## [1] 0

Resumen y transformación de las variables

Se inicia un tratamiento de la base de datos para realizar el modelamiento de los datos. Estos ajustes se detallan a continuación:

Se eliminan las variables que más NA presentan que son parqueaderos y piso que inicialmente no se espera que aporten al análisis final adicional las variables latitud y longitud. También se elimina la variable tipo y zona que no son cuantitativas.

borrar <- c("piso","parqueaderos","barrio", "longitud", "latitud", "zona", "tipo")
base1a <- base1[ ,!(names(base1) %in% borrar)]
head(base1a,10)
View(base1a)

Asociación entre las variables cuantitativas

library(GGally)
## Warning: package 'GGally' was built under R version 4.2.3
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
ggpairs(base1a[,3:6], title="Revisión") 

Al observar las correlaciones entre la variable precio y las demás variables cuantitativas se pueden identificar las siguientes correlaciones:

  • Precio vs #habitaciones: 0.121 indica una correlación lineal positiva debil, que se traduce en que efectivamente mayor número de habitaciones indicaría un mayor precio, sin embargo no es fuerte esta relación.

  • Precio vs #baños: 0.508 indica una correlación lineal positiva un poco más fuerte, que también indica que el número de baños aporta significativamente a el precio

  • Precio vs Área construida: 0.643 indica una correlación lineal positiva fuerte, lo cual indica en que en cierto grado una casa más grande influye en mayor medida en un precio final mayor.

Punto 3

Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

Regresión Múltiple

modelo1 <- lm(preciom ~ areaconst + banios + habitaciones + estrato, data = base1a)
summary(modelo1)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + habitaciones + estrato, 
##     data = base1a)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1270.64   -87.82   -22.49    53.82  1134.70 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   65.0791    13.4810   4.827 1.51e-06 ***
## areaconst      0.7854     0.0312  25.172  < 2e-16 ***
## banios        37.5104     3.9192   9.571  < 2e-16 ***
## habitaciones -11.2516     2.9351  -3.833 0.000131 ***
## estrato4      89.3906    12.5938   7.098 1.86e-12 ***
## estrato5     152.3297    12.2573  12.428  < 2e-16 ***
## estrato6     468.8769    18.2960  25.627  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 184.3 on 1686 degrees of freedom
## Multiple R-squared:  0.653,  Adjusted R-squared:  0.6518 
## F-statistic: 528.9 on 6 and 1686 DF,  p-value: < 2.2e-16

Con los resultados del modelo se puede identificar lo siguiente:

La significancia individual de los estimadores se puede apreciar a través de la prueba t que:

En los estimadores del intercepto, el número de habitaciones no son significativos individualmente ya que el valor p de la prueba t es mayor a 0.05 lo cual lleva a no rechazar la hipotesis nula que significa que el valor de estos betas es 0.

Los estimadores de área construida y baños son significativas individualmente teniendo en cuenta que el valor de la prueba t es menor a 0,05 lo cual lleva a no tener evidencia para aceptar la hipotesis nula, por lo tanto el valor de los betas es diferente de 0.

Se puede llegar a las siguientes conclusiones:

¿El modelo estadístico es válido? P value menor a 0,5 nos indica que la hipótesis nula puede ser rechazada ¿Qué tanto los puntos explican, qué tanto se acercan a la línea? R cuadrado ajustado es 0,6518 indicando que el 65% se explica con el modelo con 2 variables predictoras

Los resultados son lógicos, en el entendido que los costos de finca raiz están altamente ligados al tamaño de la vivienda como el componente principal y con una relación similar frente a las habitaciones.

Estimación paso a paso

Mediante esta metodología se estima un 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 el modelo  ingenuo  y= b0
modelo_b0<- lm(preciom ~ 1, base1a)

#define model with all predictors
modelo_all <- lm(preciom ~ areaconst + banios + habitaciones + estrato, data = base1a)

# Se aplica el proceso forward stepwise regression
forward <- step(modelo_b0, direction='forward', scope=formula(modelo_all), trace=0)

# Visualización de los resultados 
forward$anova

Resultado final del modelo

# resultado final del modelo
summary(forward)
## 
## Call:
## lm(formula = preciom ~ estrato + areaconst + banios + habitaciones, 
##     data = base1a)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1270.64   -87.82   -22.49    53.82  1134.70 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   65.0791    13.4810   4.827 1.51e-06 ***
## estrato4      89.3906    12.5938   7.098 1.86e-12 ***
## estrato5     152.3297    12.2573  12.428  < 2e-16 ***
## estrato6     468.8769    18.2960  25.627  < 2e-16 ***
## areaconst      0.7854     0.0312  25.172  < 2e-16 ***
## banios        37.5104     3.9192   9.571  < 2e-16 ***
## habitaciones -11.2516     2.9351  -3.833 0.000131 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 184.3 on 1686 degrees of freedom
## Multiple R-squared:  0.653,  Adjusted R-squared:  0.6518 
## F-statistic: 528.9 on 6 and 1686 DF,  p-value: < 2.2e-16

El ajuste del modelo aún no es completo ya que se xplica con un porcentaje que no es contundente.

Punto 4

Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

Validación de los supuestos

Para dar mayor fuerza a lo antes mencionado a continuación se revisan las gráficas de residuales del modelo con el fin de identificar posibles problemas del modelo:

par(mfrow = c(2, 2))
plot(modelo1)

Al observar las gráficas de los residuales se puede apreciar lo siguiente: Los gráficos residuals vs fitted y scale-location permiten apreciar que la varianza se ve istorsionada por los valores atípicos generando una perturbación en la línea roja que demarca la trayectoria que idealmente debería ser lineal horizontal, pero que se desvía en los valores superiores, lo cual puede verse influido por la distribución de la variable respuesta y por la distribución de otras variables como el área construida.

El patrón identificado lleva a pensar en un posible problema de heterocedasticidad. Al revisar el gráfico de normalidad se puede apreciar que los residuales no se ajustan de manera satisfactoria a la línea y que presentan importantes desviaciones influidas por los valores atípicos. El gráfico de residuals vs leverage confirma la existencia de valores influyentes sobre el modelo que se confirman ante la ubicación de un punto por encima de la distancia de cook, lo cual indica que la remoción de atípicos podría tener un impacto sobre el resultado final del modelo. La convergencia de estos aspectos revisados gráficamente da lugar para perfilar posibles problemas de heterocedasticidad, normalidad e inclusive posibles problemas de autocorrelación. Con el fin de confirmar la posibilidad de existencia de los problemas mencionados más adelante se aplicarán pruebas de diagnóstico, no obstante, previamente se validará si el presente modelo tiene problemas de multicolinealidad por medio del cálculo del VIF

Confirmación de multicolinealidad

library(car)
## Warning: package 'car' was built under R version 4.2.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.2.3
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
vif(modelo1)
##                  GVIF Df GVIF^(1/(2*Df))
## areaconst    1.375726  1        1.172913
## banios       2.052153  1        1.432534
## habitaciones 1.721284  1        1.311977
## estrato      1.488445  3        1.068535

Al revisar los valores del VIF se puede observar que todos los valores son menores a 5 lo cual permite confirmar que el modelo planteado no tiene problemas de multicolinealidad por lo que encontramos que el modelo es apropiado.

Punto 5

Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

COntinuando con la información a partir del modelo analizado en los puntos anetriores se llevará a cabo la predicción introduciendo en el modelo los requerimientos del cliente para la casa en la zona norte para conocer el precio promedio que podria estar pagando por esta vivienda, para llevar a cabo esto se crea un dataframe con los atributos con el fin de introducirlos como input en el modelo.

requerimientos_cliente<-data.frame(
estrato=c(4,5),
areaconst=c(200,200),
parqueaderos=c(1,1),
banios=c(2,2),
habitaciones=c(4,4)
)
requerimientos_cliente <- requerimientos_cliente %>%
 mutate(estrato=as.factor(estrato))
requerimientos_cliente

Predicción

library(randomForest)
## Warning: package 'randomForest' was built under R version 4.2.3
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
## 
## Attaching package: 'randomForest'
## The following object is masked from 'package:ggplot2':
## 
##     margin
## The following object is masked from 'package:dplyr':
## 
##     combine
predict(modelo1,requerimientos_cliente)
##        1        2 
## 341.5652 404.5043

El modelo predice para una casa en la zona norte estrato 4 un valor de 341,565 millones de pesos y para el estrato 5 un valor de 404,504 millones.

Punto 6

Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

Ofertas de vivienda estrato 4

Filtramos las viviendas que cumplan con los requisitos y contemplamos valores por debajo de el crédito pre aprobado por el banco

base1_viviendas_e4<- base1 %>% 
    dplyr::filter(estrato ==4, areaconst >= 200 , parqueaderos >=1 , banios >= 2, habitaciones == 4, preciom <=350) %>% 
    mutate(promedio_reg=341.5652,diferencia_promedio=promedio_reg-preciom,diferencia_cupo=350-preciom, precio_m2=preciom/areaconst) %>% 
    arrange(precio_m2)

base1_viviendas_e4

Encontramos 10 viviendas que cumplen con los requisitos destacando el precio por metro cuadrado en donde los valores más pequeños apuntan a casas más grandes y menor valor relacionado.

Ofertas de vivienda estrato 5

Filtramos las viviendas que cumplan con los requisitos y contemplamos valores por debajo de el crédito pre aprobado por el banco

base1_viviendas_e5<- base1 %>% 
    dplyr::filter(estrato ==5, areaconst >= 200 , parqueaderos >=1 , banios >= 2, habitaciones == 4, preciom <=350) %>% 
    mutate(promedio_reg=404.5043,diferencia_promedio=promedio_reg-preciom,diferencia_cupo=350-preciom, precio_m2=preciom/areaconst) %>% 
    arrange(precio_m2)

base1_viviendas_e5

Encontramos 10 viviendas que cumplen con los requisitos destacando el precio por metro cuadrado en donde los valores más pequeños apuntan a casas más grandes y menor valor relacionado.

Casas recomendadas

Se presenta en un cuadro y mapa 6 casas que cumplen con los requisitos y son las mejores opciones en relación precio y tamaño.

viviendas_pot1<- base1 %>% 
    dplyr::filter(id %in% c(7436,7499,7903,1943,819,1849)) %>% 
    mutate(diferencia_cupo=350-preciom, precio_m2=preciom/areaconst) %>% 
    arrange(precio_m2)

viviendas_pot1

Mapa recomendación

# Creación de mapa con flecha de norte y barra de escala
library(leaflet)
library(sf)
library(ggplot2)
mapa_casas_potenciales1<-leaflet(viviendas_pot1) %>%
 addTiles() %>%
 addCircleMarkers(lng=~longitud,lat=~latitud,radius=7)

mapa_casas_potenciales1

Vivienda 2

Punto 1

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 que?).

Base para trabajar

Filtro para la base 1: casas de la zona sur de la ciudad

library(dplyr)
base2 <- filter(vivienda2, Nueva_Zona == "New Zona Sur"& tipo == "Apartamento")
head(base2, 3000)

Mapa

# Creación de mapa con flecha de norte y barra de escala
library(leaflet)
library(sf)
library(ggplot2)
mapa_casas_sur<-leaflet(base2) %>%
 addTiles() %>%
 addCircleMarkers(lng=~longitud,lat=~latitud,radius=3)

mapa_casas_sur

COn la nueva definición de Zona, ya podemos observar los apartamentos que están ubicados en la zona correpondiente de forma adecuada

Punto 2

Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) 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.

Corelación con las variables

Inicialmente realizamos una exploración previa para abordar los datos

Exploración previa

library(dplyr)
glimpse(base2)
## Rows: 2,312
## Columns: 14
## $ id           <dbl> 698, 6007, 7576, 5746, 7656, 5873, 7577, 1998, 1485, 1990…
## $ zona         <chr> "Zona Sur", "Zona Sur", "Zona Sur", "Zona Sur", "Zona Sur…
## $ piso         <chr> "02", NA, "04", "01", NA, NA, "05", "03", "07", "06", NA,…
## $ estrato      <dbl> 3, 4, 5, 4, 3, 5, 5, 5, 4, 4, 3, 4, 4, 3, 4, 4, 4, 3, 3, …
## $ preciom      <dbl> 78, 108, 155, 116, 110, 89, 165, 130, 145, 140, 70, 78, 1…
## $ areaconst    <dbl> 40, 40, 43, 43, 44, 44, 45, 45, 45, 45, 46, 46, 47, 47, 4…
## $ parqueaderos <dbl> 1, NA, 1, NA, NA, 1, 1, 1, NA, 1, 1, 1, NA, NA, NA, NA, 1…
## $ banios       <dbl> 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, …
## $ habitaciones <dbl> 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 2, …
## $ tipo         <chr> "Apartamento", "Apartamento", "Apartamento", "Apartamento…
## $ barrio       <chr> "aguablanca", "valle del lili", "cuarto de legua", "valle…
## $ longitud     <dbl> -76.50100, -76.54000, -76.55066, -76.53800, -76.55100, -7…
## $ latitud      <dbl> 3.40000, 3.37300, 3.40979, 3.40600, 3.37200, 3.37100, 3.4…
## $ Nueva_Zona   <chr> "New Zona Sur", "New Zona Sur", "New Zona Sur", "New Zona…
# Convertir a caracter
base2$estrato <- as.character(base2$estrato)
glimpse(base2)
## Rows: 2,312
## Columns: 14
## $ id           <dbl> 698, 6007, 7576, 5746, 7656, 5873, 7577, 1998, 1485, 1990…
## $ zona         <chr> "Zona Sur", "Zona Sur", "Zona Sur", "Zona Sur", "Zona Sur…
## $ piso         <chr> "02", NA, "04", "01", NA, NA, "05", "03", "07", "06", NA,…
## $ estrato      <chr> "3", "4", "5", "4", "3", "5", "5", "5", "4", "4", "3", "4…
## $ preciom      <dbl> 78, 108, 155, 116, 110, 89, 165, 130, 145, 140, 70, 78, 1…
## $ areaconst    <dbl> 40, 40, 43, 43, 44, 44, 45, 45, 45, 45, 46, 46, 47, 47, 4…
## $ parqueaderos <dbl> 1, NA, 1, NA, NA, 1, 1, 1, NA, 1, 1, 1, NA, NA, NA, NA, 1…
## $ banios       <dbl> 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, …
## $ habitaciones <dbl> 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 2, …
## $ tipo         <chr> "Apartamento", "Apartamento", "Apartamento", "Apartamento…
## $ barrio       <chr> "aguablanca", "valle del lili", "cuarto de legua", "valle…
## $ longitud     <dbl> -76.50100, -76.54000, -76.55066, -76.53800, -76.55100, -7…
## $ latitud      <dbl> 3.40000, 3.37300, 3.40979, 3.40600, 3.37200, 3.37100, 3.4…
## $ Nueva_Zona   <chr> "New Zona Sur", "New Zona Sur", "New Zona Sur", "New Zona…

Revisión de información

verificamos los NA que tengamos en la base

sum(is.na(base2$zona)) # NA en zona
## [1] 0
sum(is.na(base2$piso)) # NA en  piso
## [1] 570
sum(is.na(base2$estrato)) # NA en estrato
## [1] 0
sum(is.na(base2$preciom)) # NA en preciom
## [1] 0
sum(is.na(base2$areaconst)) # NA en areaconst
## [1] 0
sum(is.na(base2$parqueaderos)) # NA en parqueaderos
## [1] 360
sum(is.na(base2$banios)) # NA en baños
## [1] 0
sum(is.na(base2$habitaciones)) # NA en habitaciones
## [1] 0
sum(is.na(base2$tipo)) # NA en tipo
## [1] 0
sum(is.na(base2$barrio)) # NA en barrio
## [1] 0
sum(is.na(base2$longitud)) # NA en longitud
## [1] 0
sum(is.na(base2$latitud)) # NA en latitud
## [1] 0

Resumen y transformación de las variables

Se inicia un tratamiento de la base de datos para realizar el modelamiento de los datos. Estos ajustes se detallan a continuación:

Se eliminan las variables que más NA presentan que son parqueaderos y piso que inicialmente no se espera que aporten al análisis final adicional las variables latitud y longitud. También se elimina la variable tipo y zona que no son cuantitativas.

borrar <- c("piso","parqueaderos","barrio", "longitud", "latitud", "zona", "tipo")
base2a <- base2[ ,!(names(base2) %in% borrar)]
head(base2a,10)
View(base2a)

Asociación entre las variables cuantitativas

library(GGally)
ggpairs(base2a[,3:6], title="Revisión") 

Al observar las correlaciones entre la variable precio y las demás variables cuantitativas se pueden identificar las siguientes correlaciones:

  • Precio vs #habitaciones: 0.315 indica una correlación lineal positiva debil, que se traduce en que efectivamente mayor número de habitaciones indicaría un mayor precio, sin embargo no es fuerte esta relación.

  • Precio vs #baños: 0.730 indica una correlación lineal positiva fuerte, que también indica que el número de baños aporta significativamente a el precio

  • Precio vs Área construida: 0.758 indica una correlación lineal positiva fuerte, lo cual indica en que en cierto grado una casa más grande influye en mayor medida en un precio final mayor.

Punto 3

Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

Regresión Múltiple

modelo2 <- lm(preciom ~ areaconst + banios + habitaciones + estrato, data = base2a)
summary(modelo2)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + habitaciones + estrato, 
##     data = base2a)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1305.37   -40.33    -1.96    36.67   907.89 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -5.57105   12.93052  -0.431  0.66662    
## areaconst      1.55028    0.05237  29.603  < 2e-16 ***
## banios        54.20878    3.57788  15.151  < 2e-16 ***
## habitaciones -16.80542    3.96789  -4.235 2.37e-05 ***
## estrato4      24.53109    9.28314   2.643  0.00828 ** 
## estrato5      52.87011    9.46904   5.583 2.63e-08 ***
## estrato6     231.67697   11.42766  20.273  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 100.9 on 2305 degrees of freedom
## Multiple R-squared:  0.7603, Adjusted R-squared:  0.7597 
## F-statistic:  1219 on 6 and 2305 DF,  p-value: < 2.2e-16

Con los resultados del modelo se puede identificar lo siguiente:

La significancia individual de los estimadores se puede apreciar a través de la prueba t que:

En los estimadores del intercepto, el número de habitaciones no son significativos individualmente ya que el valor p de la prueba t es mayor a 0.05 lo cual lleva a no rechazar la hipotesis nula que significa que el valor de estos betas es 0.

Los estimadores de área construida y baños son significativas individualmente teniendo en cuenta que el valor de la prueba t es menor a 0,05 lo cual lleva a no tener evidencia para aceptar la hipotesis nula, por lo tanto el valor de los betas es diferente de 0.

Se puede llegar a las siguientes conclusiones:

¿El modelo estadístico es válido? P value menor a 0,5 nos indica que la hipótesis nula puede ser rechazada ¿Qué tanto los puntos explican, qué tanto se acercan a la línea? R cuadrado ajustado es 0.7597 indicando que el 76% se explica con el modelo con 2 variables predictoras

Los resultados son lógicos, en el entendido que los costos de finca raiz están altamente ligados al tamaño de la vivienda como el componente principal y con una relación similar frente a los baños

Estimación paso a paso

Mediante esta metodología se estima un 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 el modelo  ingenuo  y= b0
modelo_b01<- lm(preciom ~ 1, base2a)

#define model with all predictors
modelo_all1 <- lm(preciom ~ areaconst + banios + habitaciones + estrato, data = base2a)

# Se aplica el proceso forward stepwise regression
forward1 <- step(modelo_b01, direction='forward', scope=formula(modelo_all1), trace=0)

# Visualización de los resultados 
forward1$anova

Resultado final del modelo

# resultado final del modelo
summary(forward1)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitaciones, 
##     data = base2a)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1305.37   -40.33    -1.96    36.67   907.89 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -5.57105   12.93052  -0.431  0.66662    
## areaconst      1.55028    0.05237  29.603  < 2e-16 ***
## estrato4      24.53109    9.28314   2.643  0.00828 ** 
## estrato5      52.87011    9.46904   5.583 2.63e-08 ***
## estrato6     231.67697   11.42766  20.273  < 2e-16 ***
## banios        54.20878    3.57788  15.151  < 2e-16 ***
## habitaciones -16.80542    3.96789  -4.235 2.37e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 100.9 on 2305 degrees of freedom
## Multiple R-squared:  0.7603, Adjusted R-squared:  0.7597 
## F-statistic:  1219 on 6 and 2305 DF,  p-value: < 2.2e-16

El ajuste del modelo es completo ya que se explica con un porcentaje que es contundente.

Punto 4

Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

Validación de los supuestos

Para dar mayor fuerza a lo antes mencionado a continuación se revisan las gráficas de residuales del modelo con el fin de identificar posibles problemas del modelo:

par(mfrow = c(2, 2))
plot(modelo2)

Al observar las gráficas de los residuales se puede apreciar lo siguiente: Los gráficos residuals vs fitted y scale-location permiten apreciar que la varianza se ve istorsionada por los valores atípicos generando una perturbación en la línea roja que demarca la trayectoria que idealmente debería ser lineal horizontal, pero que se desvía en los valores superiores, lo cual puede verse influido por la distribución de la variable respuesta y por la distribución de otras variables como el área construida.

El patrón identificado lleva a pensar en un posible problema de heterocedasticidad. Al revisar el gráfico de normalidad se puede apreciar que los residuales no se ajustan de manera satisfactoria a la línea y que presentan importantes desviaciones influidas por los valores atípicos. El gráfico de residuals vs leverage confirma la existencia de valores influyentes sobre el modelo que se confirman ante la ubicación de un punto por encima de la distancia de cook, lo cual indica que la remoción de atípicos podría tener un impacto sobre el resultado final del modelo. La convergencia de estos aspectos revisados gráficamente da lugar para perfilar posibles problemas de heterocedasticidad, normalidad e inclusive posibles problemas de autocorrelación. Con el fin de confirmar la posibilidad de existencia de los problemas mencionados más adelante se aplicarán pruebas de diagnóstico, no obstante, previamente se validará si el presente modelo tiene problemas de multicolinealidad por medio del cálculo del VIF

Confirmación de multicolinealidad

library(car)
vif(modelo2)
##                  GVIF Df GVIF^(1/(2*Df))
## areaconst    1.951215  1        1.396859
## banios       2.605195  1        1.614062
## habitaciones 1.415232  1        1.189635
## estrato      1.738974  3        1.096602

Al revisar los valores del VIF se puede observar que todos los valores son menores a 5 lo cual permite confirmar que el modelo planteado no tiene problemas de multicolinealidad por lo que encontramos que el modelo es apropiado.

Punto 5

Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

COntinuando con la información a partir del modelo analizado en los puntos anetriores se llevará a cabo la predicción introduciendo en el modelo los requerimientos del cliente para la casa en la zona norte para conocer el precio promedio que podria estar pagando por esta vivienda, para llevar a cabo esto se crea un dataframe con los atributos con el fin de introducirlos como input en el modelo.

requerimientos_cliente1<-data.frame(
estrato=c(5,6),
areaconst=c(300,300),
parqueaderos=c(3,3),
banios=c(3,3),
habitaciones=c(5,5)
)
requerimientos_cliente1 <- requerimientos_cliente1 %>%
 mutate(estrato=as.factor(estrato))
requerimientos_cliente1

Predicción

library(randomForest)
predict(modelo2,requerimientos_cliente1)
##        1        2 
## 590.9819 769.7887

El modelo predice para una casa en la zona sur estrato 5 un valor de 590,981 millones de pesos y para el estrato 5 un valor de 769,788 millones.

Punto 6

Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 2. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 850 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

Ofertas de vivienda estrato 5

Filtramos las viviendas que cumplan con los requisitos y contemplamos valores por debajo de el crédito pre aprobado por el banco

base2_viviendas_e5<- base2 %>% 
    dplyr::filter(estrato ==5, areaconst >= 300 , parqueaderos >=3 , banios >= 3, habitaciones >= 4, preciom <=850) %>% 
    mutate(promedio_reg=590.9819,diferencia_promedio=promedio_reg-preciom,diferencia_cupo=850-preciom, precio_m2=preciom/areaconst) %>% 
    arrange(precio_m2)

base2_viviendas_e5

Para incluir más opciones se contempló apartamentos con más de 4 habitaciones y encontramos 2 vivienda que cumplen con los requisitos.

Ofertas de vivienda estrato 6

Filtramos las viviendas que cumplan con los requisitos y contemplamos valores por debajo de el crédito pre aprobado por el banco

base2_viviendas_e6<- base2 %>% 
    dplyr::filter(estrato ==6, areaconst >= 300 , parqueaderos >=2 , banios >= 2, habitaciones >= 3, preciom <=850) %>% 
    mutate(promedio_reg=769.7887,diferencia_promedio=promedio_reg-preciom,diferencia_cupo=850-preciom, precio_m2=preciom/areaconst) %>% 
    arrange(precio_m2)

base2_viviendas_e6

Para incluir alguna opción se contempló apartamentos con 3 o más habitaciones 2 o más baños y 2 o más parqueaderos y encontramos 1 vivienda que cumple con los requisitos.

Casas recomendadas

Se presenta en un cuadro y mapa 6 casas que cumplen con los requisitos y son las mejores opciones en relación precio y tamaño.

viviendas_pot2<- base2 %>% 
    dplyr::filter(id %in% c(7182,7512,5574)) %>% 
    mutate(diferencia_cupo=350-preciom, precio_m2=preciom/areaconst) %>% 
    arrange(precio_m2)

viviendas_pot2

Mapa recomendación

# Creación de mapa con flecha de norte y barra de escala
library(leaflet)
library(sf)
library(ggplot2)
mapa_casas_potenciales2<-leaflet(viviendas_pot2) %>%
 addTiles() %>%
 addCircleMarkers(lng=~longitud,lat=~latitud,radius=7)

mapa_casas_potenciales2

Conclusiones

  • Aún no se tiene un correcto proceso de levantamiento de información por parte de la constructora ya que se observan datso erroneos en la zona de la ciudad y campos vacíos en variables que se pueden convertir en un factor de decisión importante para los clientes como parqueadero.

  • Las variables utilizadas junto a la aproximación de los modelos permiten generar con alta exactitud una aproximación a datos muy específicos y se aumenta la posibilidad de compra por parte del cliente ya que sus expectativas iniciales se pueden responder de una manera cercana a la realidad y rápida frente a su solicitud.

  • Por medio de la regresión múltiple es posible aproximarse a resultados específicos aumentando la viabilidad de respuesta y la confianza de los consumidores finales de esta información.

  • Aún es importante desarrollar otros modelos que aproximen de una manera más exacta la información solicitada.

  • Las opciones de vivienda cumplen ampliamente con las solicitudes del cliente de la inmobiliaria y optimiza la solución al entregarle alternativas económicas y con suficiencia en sus componentes.