Actividad 2 - RLM - Caso C&A

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

library(paqueteMODELOS)
data("vivienda")

Exploración de datos

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

Se procede a crear la variable base para poder realizar el filtro de las caracteristicas de la oferta de vivienda 1

attach(vivienda)

vivienda$base <- ifelse(vivienda$zona =="Zona Norte" & vivienda$tipo =="Casa", "Base 1", 
                         ifelse(vivienda$zona =="Zona Centro" & vivienda$tipo =="Casa", "Base 2",
                          ifelse(vivienda$zona =="Zona Oeste" & vivienda$tipo =="Casa", "Base 3",
                           ifelse(vivienda$zona =="Zona Oriente" & vivienda$tipo =="Casa", "Base 4",
                            ifelse(vivienda$zona == "Zona Sur" & vivienda$tipo == "Casa", "Base 5", "NA")))))
head(vivienda, 5)
##     id         zona piso estrato preciom areaconst parqueaderos banios
## 1 1147 Zona Oriente <NA>       3     250        70            1      3
## 2 1169 Zona Oriente <NA>       3     320       120            1      2
## 3 1350 Zona Oriente <NA>       3     350       220            2      2
## 4 5992     Zona Sur   02       4     400       280            3      5
## 5 1212   Zona Norte   01       5     260        90            1      2
##   habitaciones        tipo      barrio  longitud latitud   base
## 1            6        Casa 20 de julio -76.51168 3.43382 Base 4
## 2            3        Casa 20 de julio -76.51237 3.43369 Base 4
## 3            4        Casa 20 de julio -76.51537 3.43566 Base 4
## 4            3        Casa  3 de julio -76.54000 3.43500 Base 5
## 5            3 Apartamento       acopi -76.51350 3.45891     NA
  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.
library(dplyr)
## 
## 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
base1 <- filter(vivienda, zona == "Zona Norte" & tipo == "Casa")

head(base1, 3)
## # A tibble: 3 × 14
##      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
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## #   base <chr>

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

##install.packages("leaflet")
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.3.1
Casas_zona_norte <- subset(vivienda, tipo == "Casa" & zona == "Zona Norte")

Casas_zona_norte$base <- as.character(Casas_zona_norte$base)

map_casas_norte <- leaflet(Casas_zona_norte) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Casas_zona_norte$longitud ,
    lat = Casas_zona_norte$latitud,
    radius = 2,
    color = "violet"
  )

map_casas_norte # Muestra el mapa
library(leaflet)

Casas_zona_sur <- subset(vivienda, tipo == "Casa" & zona == "Zona Sur")

Casas_zona_sur$base <- as.character(Casas_zona_sur$base)

map_casas_sur <- leaflet(Casas_zona_sur) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Casas_zona_sur$longitud ,
    lat = Casas_zona_sur$latitud,
    radius = 2,
    color = "red"
  )

map_casas_sur # Muestra el mapa
library(leaflet)

Casas_zona_centro <- subset(vivienda, tipo == "Casa" & zona == "Zona Centro")

Casas_zona_centro$base <- as.character(Casas_zona_centro$base)

map_casas_centro <- leaflet(Casas_zona_centro) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Casas_zona_centro$longitud ,
    lat = Casas_zona_centro$latitud,
    radius = 2,
    color = "brown"
  )

map_casas_centro # Muestra el mapa
library(leaflet)

Casas_zona_oeste <- subset(vivienda, tipo == "Casa" & zona == "Zona Oeste")

Casas_zona_oeste$base <- as.character(Casas_zona_oeste$base)

map_casas_oeste <- leaflet(Casas_zona_oeste) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Casas_zona_oeste$longitud ,
    lat = Casas_zona_oeste$latitud,
    radius = 2,
    color = "#389"
  )

map_casas_oeste # Muestra el mapa
library(leaflet)

Casas_zona_oriente <- subset(vivienda, tipo == "Casa" & zona == "Zona Oriente")

Casas_zona_oriente$base <- as.character(Casas_zona_oriente$base)

map_casas_oriente <- leaflet(Casas_zona_oriente) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Casas_zona_oriente$longitud ,
    lat = Casas_zona_oriente$latitud,
    radius = 2,
    color = "purple"
  )

map_casas_oriente # Muestra el mapa

De acuerdo a los graficos obtenidos se puede evidenciar que en las zonas norte, sur y oriente presentan mayor dispersión respecto a la zona asociada en la base de datos, por lo que se podria concluir que los datos ingresados de longitud y latitud no son los correspondientes a las propiedades o que las zonas asociadas estan mal diligenciadas en la base de datos.

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.

Se realiza el filtro correspondiente a la base necesaria con variables númericas para poder realizar el analisis de correlación entre variables

vivienda_casas <- vivienda[vivienda$tipo == 'Casa', c("zona", "estrato",                                  "preciom", "areaconst",                                                        "parqueaderos", "banios", "habitaciones"
                            )]

# Crear un mapeo numérico
Zona_n <- c("Zona Norte" = 1, "Zona Sur" = 2, "Zona Centro" = 3, "Zona Oriente" = 4, "Zona Oeste" = 5)

# Aplicar el mapeo a la columna categórica
vivienda_casas$zona <- Zona_n[vivienda_casas$zona]

# Ver el dataframe resultante
print(vivienda_casas)
## # A tibble: 3,222 × 7
##     zona estrato preciom areaconst parqueaderos banios habitaciones
##    <dbl>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
##  1     4       3     250        70            1      3            6
##  2     4       3     320       120            1      2            3
##  3     4       3     350       220            2      2            4
##  4     2       4     400       280            3      5            3
##  5     1       5     320       150            2      4            6
##  6     1       5     780       380            2      3            3
##  7     1       6     750       445           NA      7            6
##  8     1       4     625       355            3      5            5
##  9     1       5     750       237            2      6            6
## 10     1       4     600       160            1      4            5
## # ℹ 3,212 more rows

Posteriormente se procede a realizar diferentes graficos para poder visualizar las relaciones entre la variables observadas

# Cargar la librería necesaria para la visualización de correlaciones
library(corrplot)
## corrplot 0.92 loaded
pairs(vivienda_casas[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])

# Calcular la matriz de correlación
correlation_matrix <- cor(na.omit(vivienda_casas)[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])
print(correlation_matrix)
##                 preciom   areaconst parqueaderos      banios         zona
## preciom      1.00000000 0.644537409   0.63914644  0.55967924  0.018559595
## areaconst    0.64453741 1.000000000   0.47055482  0.50061837  0.007838765
## parqueaderos 0.63914644 0.470554816   1.00000000  0.44725811 -0.070536196
## banios       0.55967924 0.500618368   0.44725811  1.00000000 -0.012355872
## zona         0.01855960 0.007838765  -0.07053620 -0.01235587  1.000000000
## habitaciones 0.08650974 0.297409809   0.09509244  0.45285126  0.062928637
## estrato      0.64175109 0.339767570   0.46302582  0.43300465 -0.133865875
##              habitaciones    estrato
## preciom        0.08650974  0.6417511
## areaconst      0.29740981  0.3397676
## parqueaderos   0.09509244  0.4630258
## banios         0.45285126  0.4330046
## zona           0.06292864 -0.1338659
## habitaciones   1.00000000 -0.1481480
## estrato       -0.14814801  1.0000000

De acuerdo a los datos obtenidos y el grafico de de correlacion se puede observar que las variables que presentan mayor correlación respecto al precio de la vivienda corresponde a: el area construida, el número de parqueaderos, el estrato y el número de baños de la vivienda.

# Crear un mapa de calor de correlación
heatmap(correlation_matrix, 
        main = "Mapa de Calor de Correlación")

  1. 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).
# Estimar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda_casas)

# Resumen del modelo
summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = vivienda_casas)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1190.80  -114.52   -25.94    74.59   986.16 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -413.87536   25.58852 -16.174  < 2e-16 ***
## areaconst       0.74227    0.02941  25.235  < 2e-16 ***
## estrato       116.07109    5.26618  22.041  < 2e-16 ***
## habitaciones  -14.74995    3.18137  -4.636 3.73e-06 ***
## parqueaderos   64.29943    3.47719  18.492  < 2e-16 ***
## banios         39.03498    4.05083   9.636  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 205.2 on 2480 degrees of freedom
##   (736 observations deleted due to missingness)
## Multiple R-squared:  0.6834, Adjusted R-squared:  0.6828 
## F-statistic:  1071 on 5 and 2480 DF,  p-value: < 2.2e-16

De acuerdo con los resultados obtenidos del modelo se puede concluir que todas las variables explicativas son significativas y explican en un 68,34% la variabilidad en el precio de la vivienda.

El coeficiente para el área construida es 0.74227. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el área construida se asocia con un aumento estimado de 0.74227 unidades en el precio de la vivienda.

El coeficiente para el estrato es 116.07109. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el estrato se asocia con un aumento estimado de 116.07109 unidades en el precio de la vivienda.

El coeficiente para las habitaciones es -14.74995. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de habitaciones se asocia con una disminución estimada de 14.74995 unidades en el precio de la vivienda. (parece que esta varible no es del todo logica, aunque si la calidad de la data es buena podría ser un hallazgo interesante)

El coeficiente para “parqueaderos” es 64.29943. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de parqueaderos se asocia con un aumento estimado de 64.29943 unidades en el precio de la vivienda.

El coeficiente para “baños” es 39.03498. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de baños se asocia con un aumento estimado de 39.03498 unidades en el precio de la vivienda.

El modelo podría mejorarse al tratar datos atipicos o validar los supuestos y de acuerdo a los resultados generar las tranformaciones que requieran para mejorar el R^2

  1. 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).

##Supuesto 1 - Linealidad

El modelo asume que la relación entre las variables independientes y la variable dependiente es lineal.

# Gráfico de residuos vs. valores ajustados
plot(modelo, which = 1)

Se puede observar que los residuos se distribuyen cerca al cero, lo cual indica no tener problemas de linealidad por lo cual el modelo cumpliria con este supuesto

##Supuesto 2 - Homocedasticidad

Este supuesto implica que la varianza de los residuos debe ser constante en todos los niveles de las variables independientes.

# Gráfico de dispersión de residuos vs. valores ajustados
plot(modelo, which = 3)

De acuerdo al grafico anterior se puede observar que la dispersión de los residuos es constante a lo largo de los valores ajustados.

##Supuesto 3 - Normalidad de los Residuos

Este supuesto indica que los residuos deben seguir una distribución normal

# Gráfico Q-Q para normalidad de residuos
qqnorm(modelo$residuals)
qqline(modelo$residuals)

# Prueba de normalidad de Shapiro-Wilk
shapiro.test(modelo$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo$residuals
## W = 0.89699, p-value < 2.2e-16

De acuerdo con los resultados obtenidos del grafico y la prueba de shapiro se puede concluir que los residuos no siguen una distribución normal ya que se plantean las siquientes hipotesis para la lectura del test y se evidencia que los residuos no siguen completamente la linea diagonal

Ho: Normalidad en los residuos Ha: No normalidad en los residuos

Criterio de decisión es P > alpha = Acepta Ho Criterio de decisión es P > alpha = Rechaza Ho

##Supuesto 4 - No Autocorrelación

Los residuos deben ser independientes unos de otros. Esto significa que no debe haber patrones temporales ni autocorrelación en los residuos.

# Gráfico de residuos vs. tiempo
plot(modelo, which = 5)

#install.packages("lmtest")
library(lmtest)
## Warning: package 'lmtest' was built under R version 4.3.1
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
# Prueba de Durbin Watson
resultado_dw <- dwtest(modelo)
print(resultado_dw)
## 
##  Durbin-Watson test
## 
## data:  modelo
## DW = 1.5759, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0

De acuerdo con los resultados obtenidos se puede concluir que los valores residuales estan correlacionados entre si, lo que que indica que el modelo no cumple con el supuesto de independencia en los residuos o tambien llamado supuesto de No autocorrelación

##Supuesto 5 - No multicolinealidad

Las variables independientes no deben estar altamente correlacionadas entre sí.

# Matriz de correlación
Corr_x <-cor(na.omit(vivienda_casas)[, c("areaconst", "estrato", "habitaciones", "parqueaderos", "banios")])
Corr_x
##              areaconst    estrato habitaciones parqueaderos    banios
## areaconst    1.0000000  0.3397676   0.29740981   0.47055482 0.5006184
## estrato      0.3397676  1.0000000  -0.14814801   0.46302582 0.4330046
## habitaciones 0.2974098 -0.1481480   1.00000000   0.09509244 0.4528513
## parqueaderos 0.4705548  0.4630258   0.09509244   1.00000000 0.4472581
## banios       0.5006184  0.4330046   0.45285126   0.44725811 1.0000000
heatmap(Corr_x, 
        main = "Mapa de Calor de Correlación")

#install.packages("car")
library(car)
## Warning: package 'car' was built under R version 4.3.1
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.3.1
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
vif_values <- vif(modelo)
vif_values
##    areaconst      estrato habitaciones parqueaderos       banios 
##     1.541765     1.694080     1.594265     1.535105     2.059733

De acuerdo con la prueba de VIF (Factor de Inflación de la Varianza) se puede concluir que no existe problemas de multicolinealidad en el modelo ya que todos los valores son < a 5

  1. Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.
# Crear un nuevo marco de datos con los valores de la nueva solicitud
solicitud_1 <- data.frame(areaconst = 200,
                          parqueaderos = 1,
                               estrato = 4,
                               habitaciones = 4,
                               estrato = c(4,5),
                               banios = 2,
                               zona = 1)


predicciones <- predict(modelo, newdata = solicitud_1)
solicitud_1$prediccion_precio <- predicciones

# Mostrar el marco de datos con las características y las predicciones
print(solicitud_1)
##   areaconst parqueaderos estrato habitaciones estrato.1 banios zona
## 1       200            1       4            4         4      2    1
## 2       200            1       4            4         5      2    1
##   prediccion_precio
## 1          282.2318
## 2          282.2318

La prediccion del modelo indica que el valor aproximado de la vivienda de la solicitud 1 es de 282.2 millones de pesos

  1. 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.
pos <- which(vivienda$areaconst>= 200 & vivienda$parqueaderos>=1 & vivienda$banios>=2 & vivienda$habitaciones>=4 & vivienda$estrato>=4 & vivienda$estrato<=5 & vivienda$preciom<=350 & vivienda$zona == "Zona Norte" & vivienda$tipo =="Casa")

Ofertas_casas <- vivienda[pos,]
Ofertas_casas_5 = Ofertas_casas[order(Ofertas_casas$areaconst, decreasing = TRUE), ]
ofertac5 <- head(Ofertas_casas_5, 5)
knitr::kable(head(Ofertas_casas_5, 5), caption = "5 Ofertas que cumple las caracterisiticas de la solicitud")
5 Ofertas que cumple las caracterisiticas de la solicitud
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud base
3101 Zona Norte 02 5 340 355 2 5 8 Casa san vicente -76.52377 3.46384 Base 1
5031 Zona Norte 03 4 350 350 1 4 5 Casa salomia -76.53464 3.44987 Base 1
1943 Zona Norte NA 5 350 346 1 2 4 Casa vipasa -76.51847 3.47503 Base 1
4209 Zona Norte 02 5 350 300 3 5 6 Casa el bosque -76.53010 3.48577 Base 1
3352 Zona Norte NA 4 335 300 3 4 4 Casa el bosque -76.52600 3.43400 Base 1
library(leaflet)

map_casas_oferta <- leaflet(ofertac5) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ofertac5$longitud ,
    lat = ofertac5$latitud,
    radius = 2,
    color = "purple"
  )

map_casas_oferta # Muestra el mapa
  1. Realice los pasos del 1 al 6. Para la segunda solicitud que tiene un crédito pre-aprobado por valor de $850 millones.

7.1. Realice un filtro a la base de datos e incluya solo las ofertas de : base2: Apartamentos, de la zona sur de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta.

library(dplyr)

base2 <- filter(vivienda, zona == "Zona Sur" & tipo == "Apartamento")

head(base2, 3)
## # A tibble: 3 × 14
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <chr>   <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1  5098 Zona S… 05          4     290        96            1      2            3
## 2   698 Zona S… 02          3      78        40            1      1            2
## 3  8199 Zona S… <NA>        6     875       194            2      5            3
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## #   base <chr>

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

##install.packages("leaflet")
library(leaflet)

Apartamentos_zona_sur <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Sur")

map_Apartamentos_zona_sur <- leaflet(Apartamentos_zona_sur) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Apartamentos_zona_sur$longitud ,
    lat = Apartamentos_zona_sur$latitud,
    radius = 2,
    color = "violet"
  )

map_Apartamentos_zona_sur # Muestra el mapa
library(leaflet)

Apartamentos_zona_norte <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Norte")

map_Apartamentos_zona_norte <- leaflet(Apartamentos_zona_norte) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Apartamentos_zona_norte$longitud ,
    lat = Apartamentos_zona_norte$latitud,
    radius = 2,
    color = "red"
  )

map_Apartamentos_zona_norte # Muestra el mapa
library(leaflet)

Apartamentos_zona_centro <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Centro")

map_Apartamentos_zona_centro <- leaflet(Apartamentos_zona_centro) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Apartamentos_zona_centro$longitud ,
    lat = Apartamentos_zona_centro$latitud,
    radius = 2,
    color = "brown"
  )

map_Apartamentos_zona_centro # Muestra el mapa
library(leaflet)

Apartamentos_zona_oeste <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Oeste")

map_Apartamentos_zona_oeste <- leaflet(Apartamentos_zona_oeste) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Apartamentos_zona_oeste$longitud ,
    lat = Apartamentos_zona_oeste$latitud,
    radius = 2,
    color = "#389"
  )

map_Apartamentos_zona_oeste # Muestra el mapa
library(leaflet)

Apartamentos_zona_oriente <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Oriente")

map_Apartamentos_zona_oriente <- leaflet(Apartamentos_zona_oriente) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = Apartamentos_zona_oriente$longitud ,
    lat = Apartamentos_zona_oriente$latitud,
    radius = 2,
    color = "purple"
  )

map_Apartamentos_zona_oriente # Muestra el mapa

De acuerdo con los graficos obtenidos se evidencia tambien que para el tipo de vivienda apartamentos existe bastante dispersión en la localización de las viviendas respecto a la zona asociada en la base de datos.

2. 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.

Se realiza el filtro correspondiente a la base necesaria con variables númericas para poder realizar el analisis de correlación entre variables

vivienda_apartamentos <- vivienda[vivienda$tipo == 'Apartamento', c("zona", "estrato",                                  "preciom", "areaconst",                                                        "parqueaderos", "banios", "habitaciones"
                            )]

# Crear un mapeo numérico
Zona_n <- c("Zona Norte" = 1, "Zona Sur" = 2, "Zona Centro" = 3, "Zona Oriente" = 4, "Zona Oeste" = 5)

# Aplicar el mapeo a la columna categórica
vivienda_apartamentos$zona <- Zona_n[vivienda_apartamentos$zona]

# Ver el dataframe resultante
print(vivienda_apartamentos)
## # A tibble: 5,103 × 7
##     zona estrato preciom areaconst parqueaderos banios habitaciones
##    <dbl>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
##  1     1       5     260        90            1      2            3
##  2     1       5     240        87            1      3            3
##  3     1       4     220        52            2      2            3
##  4     1       5     310       137            2      3            4
##  5     1       6     520        98            2      2            2
##  6     1       4     320       108            2      3            3
##  7     1       5     385       103            2      2            3
##  8     1       3     100        49           NA      1            2
##  9     1       3     175        80            1      2            3
## 10     1       6     820       377            1      4            4
## # ℹ 5,093 more rows

Posteriormente se procede a realizar diferentes graficos para poder visualizar las relaciones entre la variables observadas

# Cargar la librería necesaria para la visualización de correlaciones
library(corrplot)

pairs(vivienda_apartamentos[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])

# Calcular la matriz de correlación
correlation_matrix_a <- cor(na.omit(vivienda_apartamentos)[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])
print(correlation_matrix_a)
##                preciom areaconst parqueaderos    banios       zona habitaciones
## preciom      1.0000000 0.8231511    0.7385659 0.7297750 0.50157066   0.28286691
## areaconst    0.8231511 1.0000000    0.6779314 0.7246837 0.41476646   0.39818320
## parqueaderos 0.7385659 0.6779314    1.0000000 0.6211913 0.39601873   0.26717503
## banios       0.7297750 0.7246837    0.6211913 1.0000000 0.35628160   0.51573577
## zona         0.5015707 0.4147665    0.3960187 0.3562816 1.00000000   0.08573757
## habitaciones 0.2828669 0.3981832    0.2671750 0.5157358 0.08573757   1.00000000
## estrato      0.6383956 0.5210063    0.5437474 0.5695362 0.44201409   0.15939452
##                estrato
## preciom      0.6383956
## areaconst    0.5210063
## parqueaderos 0.5437474
## banios       0.5695362
## zona         0.4420141
## habitaciones 0.1593945
## estrato      1.0000000

De acuerdo a los datos obtenidos y el grafico de de correlacion se puede observar que las variables que presentan mayor correlación respecto al precio de la vivienda corresponde a: el area construida, el número de parqueaderos, el número de baños y el estrato de la vivienda.

# Crear un mapa de calor de correlación
heatmap(correlation_matrix_a, 
        main = "Mapa de Calor de Correlación")

  1. 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).
# Estimar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda_apartamentos)

# Resumen del modelo
summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = vivienda_apartamentos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1699.03   -57.72    -0.67    48.59  1005.44 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -278.47706   15.86822  -17.55   <2e-16 ***
## areaconst       2.00464    0.04839   41.42   <2e-16 ***
## estrato        56.24218    3.05907   18.39   <2e-16 ***
## habitaciones  -42.66447    3.80700  -11.21   <2e-16 ***
## parqueaderos   90.42324    4.14278   21.83   <2e-16 ***
## banios         54.84690    3.41824   16.05   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 137.7 on 4225 degrees of freedom
##   (872 observations deleted due to missingness)
## Multiple R-squared:  0.7845, Adjusted R-squared:  0.7843 
## F-statistic:  3077 on 5 and 4225 DF,  p-value: < 2.2e-16

De acuerdo con los resultados obtenidos del modelo se puede concluir que todas las variables explicativas son significativas y explican en un 68,34% la variabilidad en el precio de la vivienda.

El coeficiente para el área construida es 2.00464. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el área construida se asocia con un aumento estimado de 2.00464 unidades en el precio de la vivienda.

El coeficiente para el estrato es 56.24218. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el estrato se asocia con un aumento estimado de 56.24218 unidades en el precio de la vivienda.

El coeficiente para las habitaciones es -42.66447. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de habitaciones se asocia con una disminución estimada de 42.66447 unidades en el precio de la vivienda. (parece que esta varible no es del todo logica, aunque si la calidad de la data es buena podría ser un hallazgo interesante)

El coeficiente para “parqueaderos” es 90.42324. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de parqueaderos se asocia con un aumento estimado de 90.42324 unidades en el precio de la vivienda.

El coeficiente para “baños” es 54.84690. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de baños se asocia con un aumento estimado de 54.84690 unidades en el precio de la vivienda.

El modelo podría mejorarse al tratar datos atipicos o validar los supuestos y de acuerdo a los resultados generar las tranformaciones que requieran para mejorar el R^2

  1. 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).

##Supuesto 1 - Linealidad

El modelo asume que la relación entre las variables independientes y la variable dependiente es lineal.

# Gráfico de residuos vs. valores ajustados
plot(modelo, which = 1)

Se puede observar que los residuos se distribuyen cerca al cero, lo cual indica no tener problemas de linealidad por lo cual el modelo cumpliria con este supuesto

##Supuesto 2 - Homocedasticidad

Este supuesto implica que la varianza de los residuos debe ser constante en todos los niveles de las variables independientes.

# Gráfico de dispersión de residuos vs. valores ajustados
plot(modelo, which = 3)

De acuerdo al grafico anterior se puede observar que la dispersión de los residuos es parece seguir una tendencia en diagonal, lo que puede sugerir tener problemas de heterocedasticidad.

##Supuesto 3 - Normalidad de los Residuos

Este supuesto indica que los residuos deben seguir una distribución normal

# Gráfico Q-Q para normalidad de residuos
qqnorm(modelo$residuals)
qqline(modelo$residuals)

# Prueba de normalidad de Shapiro-Wilk
shapiro.test(modelo$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo$residuals
## W = 0.83758, p-value < 2.2e-16

De acuerdo con los resultados obtenidos del grafico y la prueba de shapiro se puede concluir que los residuos no siguen una distribución normal ya que se plantean las siquientes hipotesis para la lectura del test y se evidencia que los residuos no siguen completamente la linea diagonal

Ho: Normalidad en los residuos Ha: No normalidad en los residuos

Criterio de decisión es P > alpha = Acepta Ho Criterio de decisión es P > alpha = Rechaza Ho

##Supuesto 4 - No Autocorrelación

Los residuos deben ser independientes unos de otros. Esto significa que no debe haber patrones temporales ni autocorrelación en los residuos.

# Gráfico de residuos vs. tiempo
plot(modelo, which = 5)

#install.packages("lmtest")
library(lmtest)

# Prueba de Durbin Watson
resultado_dw <- dwtest(modelo)
print(resultado_dw)
## 
##  Durbin-Watson test
## 
## data:  modelo
## DW = 1.6551, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0

De acuerdo con los resultados obtenidos se puede concluir que los valores residuales estan correlacionados entre si, lo que que indica que el modelo no cumple con el supuesto de independencia en los residuos o tambien llamado supuesto de No autocorrelación

##Supuesto 5 - No multicolinealidad

Las variables independientes no deben estar altamente correlacionadas entre sí.

# Matriz de correlación
Corr_x <-cor(na.omit(vivienda_apartamentos)[, c("areaconst", "estrato", "habitaciones", "parqueaderos", "banios")])
Corr_x
##              areaconst   estrato habitaciones parqueaderos    banios
## areaconst    1.0000000 0.5210063    0.3981832    0.6779314 0.7246837
## estrato      0.5210063 1.0000000    0.1593945    0.5437474 0.5695362
## habitaciones 0.3981832 0.1593945    1.0000000    0.2671750 0.5157358
## parqueaderos 0.6779314 0.5437474    0.2671750    1.0000000 0.6211913
## banios       0.7246837 0.5695362    0.5157358    0.6211913 1.0000000
heatmap(Corr_x, 
        main = "Mapa de Calor de Correlación")

#install.packages("car")
library(car)
vif_values <- vif(modelo)
vif_values
##    areaconst      estrato habitaciones parqueaderos       banios 
##     2.602099     1.687459     1.428418     2.110436     2.910597

De acuerdo con la prueba de VIF (Factor de Inflación de la Varianza) se puede concluir que no existe problemas de multicolinealidad en el modelo ya que todos los valores son < a 5

  1. Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.
# Crear un nuevo marco de datos con los valores de la nueva solicitud
solicitud_2 <- data.frame(areaconst = 300,
                          parqueaderos = 3,
                               habitaciones = 5,
                               estrato = c(5,6),
                               banios = 3,
                               zona = 2)


predicciones <- predict(modelo, newdata = solicitud_2)
solicitud_2$prediccion_precio <- predicciones

# Mostrar el marco de datos con las características y las predicciones
print(solicitud_2)
##   areaconst parqueaderos habitaciones estrato banios zona prediccion_precio
## 1       300            3            5       5      3    2          826.6149
## 2       300            3            5       6      3    2          882.8570

La prediccion del modelo indica que el valor aproximado de la vivienda de la solicitud 2 se encuentra entre 827 y 883 millones de pesos.

  1. 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 850 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.
pos_a <- which(vivienda$areaconst>= 300 & vivienda$parqueaderos>=3 & vivienda$banios>=3 & vivienda$habitaciones>=5 & vivienda$estrato>=5 & vivienda$estrato<=6 & vivienda$preciom<=850 & vivienda$zona == "Zona Sur" & vivienda$tipo == "Apartamento")

Ofertas_apartamentos <- vivienda[pos_a,]
Ofertas_apartamentos_5 = Ofertas_apartamentos[order(Ofertas_apartamentos$areaconst, decreasing = TRUE), ]
oferta2 <- head(Ofertas_apartamentos_5, 5)
knitr::kable(head(Ofertas_apartamentos_5, 5), caption = "5 Ofertas que cumple las caracterisiticas de la solicitud")
5 Ofertas que cumple las caracterisiticas de la solicitud
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud base
7182 Zona Sur NA 5 730 573 3 8 5 Apartamento guadalupe -76.548 3.408 NA
7512 Zona Sur NA 5 670 300 3 5 6 Apartamento seminario -76.550 3.409 NA
library(leaflet)

map_Apartamentos_oferta <- leaflet(oferta2) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = oferta2$longitud ,
    lat = oferta2$latitud,
    radius = 2,
    color = "purple"
  )

map_Apartamentos_oferta # Muestra el mapa