1. Problema

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 ## 2. Revisión de la Data

library(paqueteMODELOS)
## Loading required package: boot
## Loading required package: broom
## Loading required package: GGally
## Loading required package: ggplot2
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## Loading required package: gridExtra
## Loading required package: knitr
## Loading required package: summarytools
## Warning in fun(libname, pkgname): couldn't connect to display ":0"
## system might not have X11 capabilities; in case of errors when using dfSummary(), set st_options(use.x11 = FALSE)
library(cluster)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(tidyr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:gridExtra':
## 
##     combine
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(naniar)
vivienda<-data.frame(vivienda)
dim(vivienda)
## [1] 8322   13
names(vivienda)
##  [1] "id"           "zona"         "piso"         "estrato"      "preciom"     
##  [6] "areaconst"    "parqueaderos" "banios"       "habitaciones" "tipo"        
## [11] "barrio"       "longitud"     "latitud"
names(vivienda)<-c("Id", "Zona", "Piso", "Estrato", "PrecioM2",
                             "AreaConstruida", "NParqueaderos", "NBaños","NHabitaciones",
                             "TipoVivienda", "Barrio", "Longitud", "Latitud")

El conjunto de datos con el que se está trabajando está compuesto por 8322 filas y 13 columnas, lo que se traduce en 8322 observaciones (viviendas) con 13 variables para cada una de ellas.

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      
##     PrecioM2      AreaConstruida   NParqueaderos        NBaños      
##  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       
##  NHabitaciones    TipoVivienda          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

3. Revisión de faltantes

Se procede a validar el número de faltantes por cada variable

faltantes <- colSums(is.na(vivienda)) %>% # dataframe de faltantes por variable
  as.data.frame()
faltantes
##                   .
## Id                3
## Zona              3
## Piso           2638
## Estrato           3
## PrecioM2          2
## AreaConstruida    3
## NParqueaderos  1605
## NBaños            3
## NHabitaciones     3
## TipoVivienda      3
## Barrio            3
## Longitud          3
## Latitud           3

Las variables Piso y la Variable Número de parqueaderos son las que representan el mayor número de faltantes con 32% y un 19% respectivamente

missing_data <- vivienda %>%
  summarise_all(~ mean(is.na(.)) * 100) %>%
  gather(key = "variable", value = "percent_missing")
#  gráfico
ggplot(missing_data, aes(x = reorder(variable, -percent_missing), y = percent_missing, fill = percent_missing)) +
  geom_bar(stat = "identity", show.legend = FALSE) +  
  geom_text(aes(label = paste0(round(percent_missing, 1), "%")), 
            vjust = -0.5, size = 3, color = "black") + 
  scale_fill_gradient(low = "lightblue", high = "red") + 
  labs(title = "Porcentaje de valores faltantes por variable",
       x = "Variable",
       y = "Porcentaje de valores faltantes") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 10)) 

4. Tratamiento de valores faltantes

Se procede con la variable Piso para tratar los valores faltantes con la mediana,para ello se toma la decisión de dividir los faltantes por la variable tipo de vivienda, teniendo en cuenta que las casas y apartamentos tienen una estructura de pisos diferente.

vivienda$Piso<- as.numeric(
  as.factor(vivienda$Piso))

# valor variable cuando es apartamento
piso_aparta <- subset(vivienda, TipoVivienda == "Apartamento" & is.na(Piso))
dim(piso_aparta)
## [1] 1381   13
piso_aparta2 <- subset(vivienda, TipoVivienda == "Apartamento" & !is.na(Piso))
dim(piso_aparta2)
## [1] 3719   13
mediana_piso_apartamento <- median(piso_aparta2$Piso, na.rm = TRUE)
vivienda$Piso[vivienda$TipoVivienda == "Apartamento" & is.na(vivienda$Piso)] <-mediana_piso_apartamento
#valor variable cuando es casa
piso_casa <- subset(vivienda, TipoVivienda == "Casa" & is.na(Piso))
dim(piso_casa)
## [1] 1254   13
piso_casa2 <- subset(vivienda, TipoVivienda == "Casa" & !is.na(Piso))
dim(piso_casa2)
## [1] 1965   13
mediana_piso_casa <- median(piso_casa2$Piso, na.rm = TRUE)
vivienda$Piso[vivienda$TipoVivienda == "Casa" & is.na(vivienda$Piso)] <-mediana_piso_casa

Los faltantes correspondientes a la variable Parqueadero se aborda, asumiendo que los valores nulos indican que no se tiene parquedero por lo que se imputan con valor 0

vivienda$NParqueaderos[is.na(vivienda$NParqueaderos)] <- 0

5. Validación faltantes despues de tratar las variables Tipo de vivienda y Número de parqueaderos.

faltantes <- colSums(is.na(vivienda)) %>% # dataframe de faltantes por variable
  as.data.frame()
faltantes
##                .
## Id             3
## Zona           3
## Piso           3
## Estrato        3
## PrecioM2       2
## AreaConstruida 3
## NParqueaderos  0
## NBaños         3
## NHabitaciones  3
## TipoVivienda   3
## Barrio         3
## Longitud       3
## Latitud        3
gg_miss_var(vivienda)

vivienda_final<-na.omit(vivienda)
gg_miss_var(vivienda_final)

dim(vivienda_final)
## [1] 8319   13

Despues del tratamiento de datos faltantes, el conjunto de datos cuenta con 8319 registros.

6. Estandarización de variables numéricas

vivienda_final_scaled <- vivienda_final %>%
  select(Piso, PrecioM2, AreaConstruida, NParqueaderos, NBaños, NHabitaciones, Longitud, Latitud) %>%
  mutate_all(scale)

7. Datos referentes a casas en la ciudad de cali en zona norte

vivienda_norte <- subset(vivienda, vivienda_final$TipoVivienda == "Casa" & vivienda_final$Zona == "Zona Norte")
dim(vivienda_norte)
## [1] 722  13

Mapa Zona norte Cali-Casas

library(leaflet)
map <- leaflet(vivienda_norte) %>%
  addTiles() %>%
  addMarkers(
    lng = ~vivienda_norte$Longitud,
    lat = ~vivienda_norte$Latitud,
    popup = ~as.character(vivienda_norte$Latitud) # Puedes personalizar el contenido del popup aquí
  )

map

8 Análisis exploratorio

Precio de vivienda

library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
plot_ly(vivienda_norte, 
        x = ~PrecioM2, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Distribución de PrecioM2",
         xaxis = list(title = "Precio por metro cuadrado", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

Se evidencia que en la zona norte predomina las casas con precio por m2 igual o inferior a los 600M.

vivienda_norte %>% 
  plot_ly(y = ~PrecioM2, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Distribución de PrecioM2",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Precio por metro cuadrado"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

**Área construida

library(plotly)

plot_ly(vivienda_norte, 
        x = ~AreaConstruida, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Área construida",
         xaxis = list(title = "Área construida", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

De acuerdo a los datos la mayoria de las casas de la zona nortes tienen menos de 600 M2.

vivienda_norte %>% 
  plot_ly(y = ~AreaConstruida, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Área Construida",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Área Construida"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Número de habitaciones

plot_ly(vivienda_norte, 
        x = ~NHabitaciones, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Número de habitaciones",
         xaxis = list(title = "Número de habitaciones", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

Se evidencia que las casas en la zona norte tienen entre 3 a 5 habitaciones.

vivienda_norte %>% 
  plot_ly(y = ~NHabitaciones, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Número de habitaciones",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Número de habitaciones"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Número de parqueaderos

plot_ly(vivienda_norte, 
        x = ~NParqueaderos, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Número de parqueaderos",
         xaxis = list(title = "Número de parqueaderos", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

Los datos muestran que las casas de la zona norte en su mayoria no cuentan con parqueadero, seguido por las casas de 1 y 2 parqueaderos

vivienda_norte %>% 
  plot_ly(y = ~NParqueaderos, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Número de parqueaderos",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Número de parqueaderos"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Número de baños

plot_ly(vivienda_norte, 
        x = ~NBaños, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Número de baños",
         xaxis = list(title = "Número de baños", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)") 

La zona norte, las viviendas cuentan mayoritariamente entre 2 a 4 baños.

vivienda_norte %>% 
  plot_ly(y = ~NBaños, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Número de Baños",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Número de baños"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Matriz de correlación

library(corrplot)
## corrplot 0.95 loaded
cor_matrix <- cor(vivienda_norte[,c("PrecioM2","Piso","AreaConstruida","NParqueaderos","NHabitaciones","NBaños")])

# Matriz de correlación
corrplot(cor_matrix, method = "color", col = colorRampPalette(c("blue", "white", "red"))(200),
         addCoef.col = "black", 
         tl.col = "black", tl.srt = 45,
         number.cex = 0.7, 
         cl.pos = "r") 

library(GGally)
cor_1 <-vivienda_norte[,c("PrecioM2","Piso","AreaConstruida","NParqueaderos","NHabitaciones","NBaños")]
ggpairs(cor_1, title="GGally ") 

De acuerdo a la revisión de la matriz de correlación, se puede inferirque:

9. Estimación de la regresión lineal

modelo1 <- lm(PrecioM2 ~  AreaConstruida + Piso + NParqueaderos + Estrato+ NBaños + NHabitaciones, data = vivienda_norte)
summary(modelo1)
## 
## Call:
## lm(formula = PrecioM2 ~ AreaConstruida + Piso + NParqueaderos + 
##     Estrato + NBaños + NHabitaciones, data = vivienda_norte)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -959.81  -80.43  -17.42   50.54 1068.87 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -223.41398   39.44659  -5.664 2.15e-08 ***
## AreaConstruida    0.82738    0.04372  18.923  < 2e-16 ***
## Piso             -5.99485   11.54753  -0.519    0.604    
## NParqueaderos    -1.67863    4.31725  -0.389    0.698    
## Estrato          85.82055    7.49251  11.454  < 2e-16 ***
## NBaños           27.29998    5.38203   5.072 5.01e-07 ***
## NHabitaciones     1.47961    4.16679   0.355    0.723    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 159.2 on 715 degrees of freedom
## Multiple R-squared:  0.6509, Adjusted R-squared:  0.648 
## F-statistic: 222.2 on 6 and 715 DF,  p-value: < 2.2e-16

Precio=−223.41+0.82(areaconst)-5.99(Npiso)-1.67(Nparqueaderos)+85.82(Estrato)+27.29(Nbaños)+1.48(NHabitaciones)

El R2 es igual a 0.7091 lo que obtenemos que hay un 65% que las variables mencionadas tiene relación con el precio del inmueble.

Hipótesis para ßo:Ho:βo=0,Ha:β0≠0

Se evidencia que todas las variables en el modelo son significativas a excepción de la variable número de pisos, Número de habitaciones y Número de parqueaderos.

Como sugerencia, se podria validar un poco mas si las variables significativas cuentan con valores atipicosque afectan el modelo, de no tener ningun resultado positivo, se deberia proceder por eliminarlas del modelo.

10. Revisión de supuestos

Prueba de normalidad: Shapiro-Wilk

# Hipótesis:
# H0: Los errores están normalmente distribuidos.
# H1: Los errores no están normalmente distribuidos.
shapiro.test(residuals(modelo1))
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(modelo1)
## W = 0.83988, p-value < 2.2e-16
# Prueba de normalidad sobre los residuos para evaluar los errores del modelo original

p-value < 2.2e-16 → Es menor que 0.05, por lo que se rechaza la hipotesis nula y se concluye que los residuos no siguen una distribución normal.

Prueba de independencia de los errores: Durbin-Watson

library(lmtest) 
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
# Hipótesis:
# H0: No hay autocorrelación entre los errores (independencia).
# H1: Hay autocorrelación entre los errores (dependencia).
dwtest(modelo1)  # Realiza la prueba de Durbin-Watson para autocorrelación de los errores
## 
##  Durbin-Watson test
## 
## data:  modelo1
## DW = 1.6337, p-value = 2.927e-07
## alternative hypothesis: true autocorrelation is greater than 0

Hay evidencia de autocorrelación positiva en los residuos (DW = 1.63, p < 0.05)

Prueba de homocedasticidad: Breusch-Pagan

library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
## The following object is masked from 'package:boot':
## 
##     logit
# Hipótesis:
# H0: Los errores tienen varianza constante (homocedasticidad).
# H1: Los errores no tienen varianza constante (heterocedasticidad).
ncvTest(modelo1)  # Prueba de homocedasticidad basada en Breusch-Pagan
## Non-constant Variance Score Test 
## Variance formula: ~ fitted.values 
## Chisquare = 599.3523, Df = 1, p = < 2.22e-16

De acuerdo al resultado se rechaza la hipótesis nula y se concluye que hay heterocedasticidad en los residuos.

Verificación visual de los residuos (residuos vs ajustados)

par(mfrow = c(2, 2))  # Organizar gráficos
par(mar = c(4, 4, 2, 1))
plot(modelo1)  # Incluye gráficos de residuos y normalidad

Como sugerencia para ajustar el modelo de acuerdo a la validación de los supuestos se indica que:

Predicción modelo parte 1

nueva_obs <- data.frame(
  AreaConstruida = c(200,200),
  Piso = 1,
  NParqueaderos = 1,
  Estrato = c(4,5),
  NBaños = 2,
  NHabitaciones = 4
)
predict(modelo1, nueva_obs, interval = "confidence")
##        fit      lwr      upr
## 1 338.1891 310.8208 365.5574
## 2 424.0096 392.8779 455.1414

De acuerdo a las caracteristicas que se describen parauna casa en el estrato 4, el precio promedio es de 338 Millones y para estrato 5 de 424 Millones

12. Cinco opciones de casa en zona norte

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.

Revisión de variables Estrato-tipo vivienda

vivienda_norte_casas = vivienda_norte %>% 
    dplyr::filter(Estrato==4,AreaConstruida>=200,NParqueaderos>=1,NBaños>=2,NHabitaciones==4,PrecioM2<=350) 

vivienda_norte_casas
##     Id       Zona Piso Estrato PrecioM2 AreaConstruida NParqueaderos NBaños
## 1 4458 Zona Norte    2       4      315          270.0             2      4
## 2 3352 Zona Norte    2       4      335          300.0             3      4
## 3  937 Zona Norte    2       4      350          280.0             2      3
## 4 1108 Zona Norte    2       4      330          260.0             1      3
## 5 1144 Zona Norte    2       4      320          200.0             2      4
## 6 2544 Zona Norte    1       4      340          264.5             2      4
## 7 1822 Zona Norte    2       4      340          295.0             2      2
##   NHabitaciones TipoVivienda    Barrio  Longitud Latitud
## 1             4         Casa el bosque -76.53176 3.48780
## 2             4         Casa el bosque -76.52600 3.43400
## 3             4         Casa la merced -76.50603 3.46643
## 4             4         Casa la merced -76.51060 3.48108
## 5             4         Casa la merced -76.51156 3.48029
## 6             4         Casa    vipasa -76.52096 3.47665
## 7             4         Casa    vipasa -76.51777 3.48060

Se escoge las primeras 5

casas_estrato_4 = vivienda_norte_casas %>% 
    dplyr::filter(Id %in% c(3352,1822, 4458, 2544, 937))

head(casas_estrato_4)
##     Id       Zona Piso Estrato PrecioM2 AreaConstruida NParqueaderos NBaños
## 1 4458 Zona Norte    2       4      315          270.0             2      4
## 2 3352 Zona Norte    2       4      335          300.0             3      4
## 3  937 Zona Norte    2       4      350          280.0             2      3
## 4 2544 Zona Norte    1       4      340          264.5             2      4
## 5 1822 Zona Norte    2       4      340          295.0             2      2
##   NHabitaciones TipoVivienda    Barrio  Longitud Latitud
## 1             4         Casa el bosque -76.53176 3.48780
## 2             4         Casa el bosque -76.52600 3.43400
## 3             4         Casa la merced -76.50603 3.46643
## 4             4         Casa    vipasa -76.52096 3.47665
## 5             4         Casa    vipasa -76.51777 3.48060

Estrato 5

vivienda_norte_casas_5= vivienda_norte %>% 
    dplyr::filter(Estrato==5,AreaConstruida>=200,NParqueaderos>=1,NBaños>=2,NHabitaciones==4,PrecioM2<=350) 

vivienda_norte_casas_5
##      Id       Zona Piso Estrato PrecioM2 AreaConstruida NParqueaderos NBaños
## 1  4210 Zona Norte    1       5      350            200             3      3
## 2  4800 Zona Norte    1       5      340            250             2      4
## 3   819 Zona Norte    2       5      350            264             2      3
## 4  1343 Zona Norte    2       5      320            200             2      4
## 5  3053 Zona Norte    2       5      320            230             2      4
## 6  1163 Zona Norte    2       5      350            216             2      2
## 7  1849 Zona Norte    2       5      330            246             2      4
## 8  1887 Zona Norte    1       5      340            203             2      3
## 9  1842 Zona Norte    2       5      350            240             2      3
## 10 1943 Zona Norte    2       5      350            346             1      2
##    NHabitaciones TipoVivienda           Barrio  Longitud Latitud
## 1              4         Casa        el bosque -76.53010 3.48503
## 2              4         Casa        el bosque -76.53300 3.46500
## 3              4         Casa         la flora -76.50330 3.46412
## 4              4         Casa         la flora -76.51524 3.48893
## 5              4         Casa         la flora -76.52353 3.48352
## 6              4         Casa        la merced -76.51218 3.48181
## 7              4         Casa prados del norte -76.51800 3.47000
## 8              4         Casa           vipasa -76.51803 3.48257
## 9              4         Casa           vipasa -76.51800 3.48100
## 10             4         Casa           vipasa -76.51847 3.47503
casas_estrato_5 = vivienda_norte_casas_5 %>% 
    dplyr::filter(Id %in% c(4210,819, 1163, 1842, 1943))

head(casas_estrato_5)
##     Id       Zona Piso Estrato PrecioM2 AreaConstruida NParqueaderos NBaños
## 1 4210 Zona Norte    1       5      350            200             3      3
## 2  819 Zona Norte    2       5      350            264             2      3
## 3 1163 Zona Norte    2       5      350            216             2      2
## 4 1842 Zona Norte    2       5      350            240             2      3
## 5 1943 Zona Norte    2       5      350            346             1      2
##   NHabitaciones TipoVivienda    Barrio  Longitud Latitud
## 1             4         Casa el bosque -76.53010 3.48503
## 2             4         Casa  la flora -76.50330 3.46412
## 3             4         Casa la merced -76.51218 3.48181
## 4             4         Casa    vipasa -76.51800 3.48100
## 5             4         Casa    vipasa -76.51847 3.47503

Unificación de bases

base_opciones_caso1<- rbind(vivienda_norte_casas,vivienda_norte_casas_5)

head(base_opciones_caso1, 10)
##      Id       Zona Piso Estrato PrecioM2 AreaConstruida NParqueaderos NBaños
## 1  4458 Zona Norte    2       4      315          270.0             2      4
## 2  3352 Zona Norte    2       4      335          300.0             3      4
## 3   937 Zona Norte    2       4      350          280.0             2      3
## 4  1108 Zona Norte    2       4      330          260.0             1      3
## 5  1144 Zona Norte    2       4      320          200.0             2      4
## 6  2544 Zona Norte    1       4      340          264.5             2      4
## 7  1822 Zona Norte    2       4      340          295.0             2      2
## 8  4210 Zona Norte    1       5      350          200.0             3      3
## 9  4800 Zona Norte    1       5      340          250.0             2      4
## 10  819 Zona Norte    2       5      350          264.0             2      3
##    NHabitaciones TipoVivienda    Barrio  Longitud Latitud
## 1              4         Casa el bosque -76.53176 3.48780
## 2              4         Casa el bosque -76.52600 3.43400
## 3              4         Casa la merced -76.50603 3.46643
## 4              4         Casa la merced -76.51060 3.48108
## 5              4         Casa la merced -76.51156 3.48029
## 6              4         Casa    vipasa -76.52096 3.47665
## 7              4         Casa    vipasa -76.51777 3.48060
## 8              4         Casa el bosque -76.53010 3.48503
## 9              4         Casa el bosque -76.53300 3.46500
## 10             4         Casa  la flora -76.50330 3.46412

Se escogen las mejores 5

base_opciones_caso1_final = base_opciones_caso1 %>% 
    dplyr::filter(Id %in% c(1943, 3352, 1822, 937, 4458))
head(base_opciones_caso1_final)
##     Id       Zona Piso Estrato PrecioM2 AreaConstruida NParqueaderos NBaños
## 1 4458 Zona Norte    2       4      315            270             2      4
## 2 3352 Zona Norte    2       4      335            300             3      4
## 3  937 Zona Norte    2       4      350            280             2      3
## 4 1822 Zona Norte    2       4      340            295             2      2
## 5 1943 Zona Norte    2       5      350            346             1      2
##   NHabitaciones TipoVivienda    Barrio  Longitud Latitud
## 1             4         Casa el bosque -76.53176 3.48780
## 2             4         Casa el bosque -76.52600 3.43400
## 3             4         Casa la merced -76.50603 3.46643
## 4             4         Casa    vipasa -76.51777 3.48060
## 5             4         Casa    vipasa -76.51847 3.47503

Mapa ubicaciones

mapa_casas <- leaflet(base_opciones_caso1_final) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~Longitud, lat = ~Latitud, color = "blue", radius = 4)

# Mostrar el mapa
mapa_casas

13. Datos referentes a apartamentos en la ciudad de cali en zona norte

vivienda_norte_apto <- subset(vivienda, vivienda_final$TipoVivienda == "Apartamento" & vivienda_final$Zona == "Zona Norte")
dim(vivienda_norte_apto)
## [1] 1198   13

Mapa Zona norte Cali-Apto

library(leaflet)
map <- leaflet(vivienda_norte_apto) %>%
  addTiles() %>%
  addMarkers(
    lng = ~vivienda_norte$Longitud,
    lat = ~vivienda_norte$Latitud,
    popup = ~as.character(vivienda_norte$Latitud) # Puedes personalizar el contenido del popup aquí
  )

map

14 Análisis exploratorio

Precio de vivienda

library(plotly)

plot_ly(vivienda_norte_apto, 
        x = ~PrecioM2, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Distribución de PrecioM2",
         xaxis = list(title = "Precio por metro cuadrado", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

Se evidencia que en la zona norte predomina las casas con precio por m2 igual o inferior a los 400M.

vivienda_norte_apto %>% 
  plot_ly(y = ~PrecioM2, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Distribución de PrecioM2",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Precio por metro cuadrado"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

**Área construida

library(plotly)

plot_ly(vivienda_norte_apto, 
        x = ~AreaConstruida, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Área construida",
         xaxis = list(title = "Área construida", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

De acuerdo a los datos la mayoria de las casas de la zona nortes tienen menos de 200 M2.

vivienda_norte_apto %>% 
  plot_ly(y = ~AreaConstruida, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Área Construida",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Área Construida"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Número de habitaciones

plot_ly(vivienda_norte_apto, 
        x = ~NHabitaciones, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Número de habitaciones",
         xaxis = list(title = "Número de habitaciones", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

Se evidencia que las casas en la zona norte tienen entre 2 a 4 habitaciones.

vivienda_norte_apto %>% 
  plot_ly(y = ~NHabitaciones, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Número de habitaciones",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Número de habitaciones"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Número de parqueaderos

plot_ly(vivienda_norte_apto, 
        x = ~NParqueaderos, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Número de parqueaderos",
         xaxis = list(title = "Número de parqueaderos", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")  

Los datos muestran que las casas de la zona norte en su mayoria cuentan con 1 parqueadero.

vivienda_norte_apto %>% 
  plot_ly(y = ~NParqueaderos, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Número de parqueaderos",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Número de parqueaderos"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Número de baños

plot_ly(vivienda_norte_apto, 
        x = ~NBaños, 
        type = "histogram",
        marker = list(color = "rgba(55, 128, 191, 0.7)",
                      line = list(color = "rgba(55, 128, 191, 1)", width = 1.5))) %>%
  layout(title = "Número de baños",
         xaxis = list(title = "Número de baños", 
                      gridcolor = "rgba(200, 200, 200, 0.5)"), 
         yaxis = list(title = "Frecuencia"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)") 

La zona norte, las viviendas cuentan mayoritariamente con 2 baños.

vivienda_norte_apto %>% 
  plot_ly(y = ~NBaños, x = ~"Distribución", type = "box", 
          marker = list(color = "rgba(55, 128, 191, 0.7)"),  
          boxpoints = "all",   
          jitter = 0.3,        
          pointpos = -1.8,    
          line = list(color = "rgba(0, 0, 139, 1)", width = 2)) %>%  
  layout(title = "Número de Baños",
         xaxis = list(title = "", showgrid = FALSE), 
         yaxis = list(title = "Número de baños"),
         plot_bgcolor = "rgba(240, 240, 240, 0.8)")

Matriz de correlación

library(corrplot)

cor_matrix <- cor(vivienda_norte_apto[,c("PrecioM2","Piso","AreaConstruida","NParqueaderos","NHabitaciones","NBaños")])

# Matriz de correlación
corrplot(cor_matrix, method = "color", col = colorRampPalette(c("blue", "white", "red"))(200),
         addCoef.col = "black", 
         tl.col = "black", tl.srt = 45,
         number.cex = 0.7, 
         cl.pos = "r") 

library(GGally)
cor_1 <-vivienda_norte_apto[,c("PrecioM2","Piso","AreaConstruida","NParqueaderos","NHabitaciones","NBaños")]
ggpairs(cor_1, title="GGally ") 

De acuerdo a la revisión de la matriz de correlación, se puede inferir que:

15. Estimación de la regresión lineal Apartamentos

modelo2 <- lm(PrecioM2 ~  AreaConstruida + Piso + NParqueaderos + Estrato+ NBaños + NHabitaciones, data = vivienda_norte_apto)
summary(modelo2)
## 
## Call:
## lm(formula = PrecioM2 ~ AreaConstruida + Piso + NParqueaderos + 
##     Estrato + NBaños + NHabitaciones, data = vivienda_norte_apto)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -878.54  -38.81    2.34   33.64  718.95 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -223.22474   19.95067 -11.189  < 2e-16 ***
## AreaConstruida    1.69765    0.07653  22.183  < 2e-16 ***
## Piso              2.57758    1.14524   2.251  0.02459 *  
## NParqueaderos    22.20175    4.40181   5.044 5.27e-07 ***
## Estrato          61.68155    3.94433  15.638  < 2e-16 ***
## NBaños           34.47162    5.06160   6.810 1.54e-11 ***
## NHabitaciones   -13.53155    4.93279  -2.743  0.00618 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 98.14 on 1191 degrees of freedom
## Multiple R-squared:  0.7599, Adjusted R-squared:  0.7587 
## F-statistic: 628.2 on 6 and 1191 DF,  p-value: < 2.2e-16

Precio=−223.22+1.69(areaconst)}2.57(Npiso)+22.20(Nparqueaderos)+61.68(Estrato)+34.47(Nbaños)-13.33(NHabitaciones)

El R2 es igual a 0.7091 lo que obtenemos que hay un 76% que las variables mencionadas tiene relación con el precio del inmueble.

Hipótesis para ßo:Ho:βo=0,Ha:β0≠0

Se evidencia que todas las variables en el modelo son significativas.

16. Revisión de supuestos Apartamentos

Prueba de normalidad: Shapiro-Wilk

# Hipótesis:
# H0: Los errores están normalmente distribuidos.
# H1: Los errores no están normalmente distribuidos.
shapiro.test(residuals(modelo2))
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(modelo2)
## W = 0.81266, p-value < 2.2e-16
# Prueba de normalidad sobre los residuos para evaluar los errores del modelo original

p-value < 2.2e-16 → Es menor que 0.05, por lo que se rechaza la hipotesis nula y se concluye que los residuos no siguen una distribución normal.

Prueba de independencia de los errores: Durbin-Watson

library(lmtest) 
# Hipótesis:
# H0: No hay autocorrelación entre los errores (independencia).
# H1: Hay autocorrelación entre los errores (dependencia).
dwtest(modelo2)  # Realiza la prueba de Durbin-Watson para autocorrelación de los errores
## 
##  Durbin-Watson test
## 
## data:  modelo2
## DW = 1.434, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0

Hay evidencia de autocorrelación positiva en los residuos (DW = 1.63, p < 0.05)

Prueba de homocedasticidad: Breusch-Pagan

library(car)
# Hipótesis:
# H0: Los errores tienen varianza constante (homocedasticidad).
# H1: Los errores no tienen varianza constante (heterocedasticidad).
ncvTest(modelo2)  # Prueba de homocedasticidad basada en Breusch-Pagan
## Non-constant Variance Score Test 
## Variance formula: ~ fitted.values 
## Chisquare = 2340.927, Df = 1, p = < 2.22e-16

De acuerdo al resultado se rechaza la hipótesis nula y se concluye que hay heterocedasticidad en los residuos.

Verificación visual de los residuos (residuos vs ajustados)

par(mfrow = c(2, 2))  # Organizar gráficos
par(mar = c(4, 4, 2, 1))
plot(modelo2)  # Incluye gráficos de residuos y normalidad

Como sugerencia para ajustar el modelo de acuerdo a la validación de los supuestos se indica que:

Predicción modelo parte 2

nueva_obs <- data.frame(
  AreaConstruida = c(300,300),
  Piso = 1,
  NParqueaderos = 3,
  Estrato = c(5,6),
  NBaños = 3,
  NHabitaciones = 5
)
predict(modelo2, nueva_obs, interval = "confidence")
##        fit      lwr      upr
## 1 699.4174 665.7996 733.0353
## 2 761.0990 727.4555 794.7424
De acuerdo a las caracteristicas que se describen parauna casa en el estrato 5, el precio promedio es de 699 Millones y para estrato 6 de 761 Millones

## 17. Cinco opciones de apartamento en zona norte


``` r
vivienda_norte_ap = vivienda_norte_apto %>% 
    dplyr::filter(Estrato==5,AreaConstruida>=300,NParqueaderos>=3,NBaños>=3,NHabitaciones==5,PrecioM2<=850) 

vivienda_norte_ap
##     Id       Zona Piso Estrato PrecioM2 AreaConstruida NParqueaderos NBaños
## 1 3572 Zona Norte    5       5      450            307             4      4
##   NHabitaciones TipoVivienda    Barrio  Longitud Latitud
## 1             5  Apartamento versalles -76.52708 3.46439

Se encuentra un solo apartamento con las caracteristicas solicitadas en el estrato 5

vivienda_norte_ap_6 = vivienda_norte_apto %>% 
    dplyr::filter(Estrato==6,AreaConstruida>=300,NParqueaderos>=3,NBaños>=3,NHabitaciones==5,PrecioM2<=850) 

vivienda_norte_ap_6
##  [1] Id             Zona           Piso           Estrato        PrecioM2      
##  [6] AreaConstruida NParqueaderos  NBaños         NHabitaciones  TipoVivienda  
## [11] Barrio         Longitud       Latitud       
## <0 rows> (or 0-length row.names)

No se encuentra un solo apartamento con las caracteristicas solicitadas en el estrato 5.

Mapa ubicación del apartamento encontrado

mapa_apto <- leaflet(vivienda_norte_ap) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~Longitud, lat = ~Latitud, color = "blue", radius = 4)

# Mostrar el mapa
mapa_apto