Acitividad Caso 2: Caso C&A

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, Maria recibió una carta solicitando asesoria para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad.

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

Importación del set de datos

#install.packages("devtools") # solo la primera vez
devtools::install_github("dgonxalex80/paqueteMOD", force =TRUE)
## fs      (1.6.0 -> 1.6.1) [CRAN]
## cachem  (1.0.6 -> 1.0.7) [CRAN]
## fastmap (1.1.0 -> 1.1.1) [CRAN]
## httpuv  (1.6.8 -> 1.6.9) [CRAN]
## xfun    (0.36  -> 0.37 ) [CRAN]
## package 'fs' successfully unpacked and MD5 sums checked
## package 'cachem' successfully unpacked and MD5 sums checked
## package 'fastmap' successfully unpacked and MD5 sums checked
## package 'httpuv' successfully unpacked and MD5 sums checked
## package 'xfun' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\oscar\AppData\Local\Temp\RtmpeQOIuV\downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
##   
  
  
   checking for file 'C:\Users\oscar\AppData\Local\Temp\RtmpeQOIuV\remotes53a018a34303\dgonxalex80-paqueteMOD-f14d4b4/DESCRIPTION' ...
  
✔  checking for file 'C:\Users\oscar\AppData\Local\Temp\RtmpeQOIuV\remotes53a018a34303\dgonxalex80-paqueteMOD-f14d4b4/DESCRIPTION'
## 
  
  
  
─  preparing 'paqueteMOD':
##    checking DESCRIPTION meta-information ...
  
   checking DESCRIPTION meta-information ... 
  
✔  checking DESCRIPTION meta-information
## 
  
  
  
─  checking for LF line-endings in source and make files and shell scripts
## 
  
  
  
─  checking for empty or unneeded directories
## 
  
  
  
─  building 'paqueteMOD_0.0.0.1.tar.gz'
## 
  
   
## 
library(paqueteMOD)
data("vivienda")

Librerías Requeridas

#install.packages("leaflet")
#install.packages("fontawesome")
library(dplyr)
library(plotly)
library(paqueteMOD)

Paso 1: Filtro por zonas

Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).

Creamos una nueva variable llamada base la cual ubica en Base 1 a Base 5 las casas dependiendo de su zona.

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,3)
## # A tibble: 3 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <chr>  <chr>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <chr> <chr> 
## 1  1147 Zona … <NA>        3     250      70       1      3       6 Casa  20 de…
## 2  1169 Zona … <NA>        3     320     120       1      2       3 Casa  20 de…
## 3  1350 Zona … <NA>        3     350     220       2      2       4 Casa  20 de…
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Base 1

library(dplyr)

# Filtro para la base 1: casas de la zona norte de la ciudad
base1 <- filter(vivienda, zona == "Zona Norte" & tipo == "Casa")

# Mostrar los primeros 3 registros y una tabla
head(base1, 3)
## # A tibble: 3 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <chr>  <chr>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <chr> <chr> 
## 1  1209 Zona … 02          5     320     150       2      4       6 Casa  acopi 
## 2  1592 Zona … 02          5     780     380       2      3       3 Casa  acopi 
## 3  4057 Zona … 02          6     750     445      NA      7       6 Casa  acopi 
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Base 2

# Filtro para la base 2: casas de la zona centro de la ciudad
base2 <- filter(vivienda, zona == "Zona Centro" & tipo == "Casa")

# Mostrar los primeros 3 registros y una tabla
head(base2, 3)
## # A tibble: 3 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <chr>  <chr>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <chr> <chr> 
## 1  5298 Zona … 01          3     650     240       2      4       4 Casa  alame…
## 2  5107 Zona … 02          4     400     460      NA      5       7 Casa  alame…
## 3  5117 Zona … 02          3     380     290      NA      4       8 Casa  alame…
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Base 3

# Filtro para la base 3: casas de la zona oeste de la ciudad
base3 <- filter(vivienda, zona == "Zona Oeste" & tipo == "Casa")

# Mostrar los primeros 3 registros y una tabla
head(base3, 3)
## # A tibble: 3 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <chr>  <chr>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <chr> <chr> 
## 1  6928 Zona … 03          6    1850     302       4      4       3 Casa  aguac…
## 2  7510 Zona … 03          6    1950     400       4      5       3 Casa  aguac…
## 3  7586 Zona … 03          6     870     275       3      5       4 Casa  aguac…
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Base 4

# Filtro para la base 4: casas de la zona oriente de la ciudad
base4 <- filter(vivienda, zona == "Zona Oriente" & tipo == "Casa")

# Mostrar los primeros 3 registros y una tabla
head(base4, 3)
## # A tibble: 3 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <chr>  <chr>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <chr> <chr> 
## 1  1147 Zona … <NA>        3     250      70       1      3       6 Casa  20 de…
## 2  1169 Zona … <NA>        3     320     120       1      2       3 Casa  20 de…
## 3  1350 Zona … <NA>        3     350     220       2      2       4 Casa  20 de…
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Base 5

# Filtro para la base 5: casas de la zona sur de la ciudad
base5 <- filter(vivienda, zona == "Zona Sur" & tipo == "Casa")

# Mostrar los primeros 3 registros y una tabla
head(base5, 3)
## # A tibble: 3 × 14
##      id zona   piso  estrato preciom areac…¹ parqu…² banios habit…³ tipo  barrio
##   <dbl> <chr>  <chr>   <dbl>   <dbl>   <dbl>   <dbl>  <dbl>   <dbl> <chr> <chr> 
## 1  5992 Zona … 02          4     400     280       3      5       3 Casa  3 de …
## 2  5157 Zona … 02          3     500     354       1      2       4 Casa  alame…
## 3  5501 Zona … 02          3     175     102      NA      2       4 Casa  alame…
## # … with 3 more variables: longitud <dbl>, latitud <dbl>, base <chr>, and
## #   abbreviated variable names ¹​areaconst, ²​parqueaderos, ³​habitaciones

Mapa

Los colores correspondientes para cada zona son:

  • Norte: Rojo
  • Sur: Naranja
  • Centro: Azul
  • Oeste: Verde
  • Oriente: Morado

En la visualización del mapa se evidencian puntos de colores en zonas que no les corresponde, esto se puede dar porque desde el set las zonas de algunos registros no corresponden con la ubicación cartográfica dada por la longitud y latitud. Además, como solo tenemos 5 puntos cardinales y no se tienen en cuenta los puntos intermedios las ubicaciones que estén entre 2 de ellos van a tender a alguno de los dos generando esta variación en algunas zonas específicas.

library(leaflet)

# Filtrar solo las viviendas de tipo Casa
vivienda_casas <- subset(vivienda, tipo == "Casa")

# Convertir la variable "base" en una variable de tipo carácter
vivienda_casas$base <- as.character(vivienda_casas$base)

# Usar colorFactor() para asignar automáticamente un color único a cada nivel de la variable categórica
colores <- colorFactor(palette = "Set1", domain = vivienda_casas$base)

# Crear un mapa con las viviendas marcadas por su latitud y longitud y con el color dictado por la variable "base"
mapa <- leaflet(vivienda_casas) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(base), radius = 4)

# Mostrar el mapa
mapa

Paso 2: Analisis Exploratorio

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.

La variable parqueaderos es la que tiene mas valores vacios con 1605, de resto las demas variables tienen entre 3 y 2 datos vacios. Tiene 8 variables numericas, 5 categoricas y una de tipo character.

  • Entre las variables de tipo factor encontramos la variable estrato por lo que para realizar el analisis de correlacion tenemos que realizar una conversion para pasarla a tipo num y de esta forma poder realizar el analisis de correlacion.

Analisis Grafico

Revision grafica de las variables a utilziar en el modelo de regresion lineal multiple:

preciom

Encontramos que la mayoria de casas y a partamentos tienen un precio menor a 1000 millones, lo que genera que el grafico se desplace hacia la izquierda.

plot_ly(vivienda, x = ~preciom, type = "histogram")%>%
  layout(title = "Distribución de precios")

Habitaciones

Encontramos observaciones de habitaciones con valores de 0 y esto no es real puesto que caulquier casa o apartamento tendria por lo menos una habitación. Por lo que procedemos a eliminar los registros con cero habitaciones.

plot_ly(vivienda, x = ~habitaciones, type = "histogram") %>%
  layout(title = "Distribución de habitaciones")
vivienda=vivienda[vivienda$habitaciones!=0,]
summary(vivienda$habitaciones)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   3.000   3.000   3.634   4.000  10.000       3

banios

Encontramos registros de casas que tienen cero baños, esto no puede ser un dato real puesto que no seria conveniente utilizar una casa que no tenga baño. Por lo que procedemos a eliminar los registros con cero baños.

plot_ly(vivienda, x = ~banios, type = "histogram") %>%
  layout(title = "Distribución de baños")
vivienda=vivienda[vivienda$banios!=0,]
summary(vivienda$banios)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   2.000   3.000   3.128   4.000  10.000       3

Estrato

Se evidencia que la mayoria de casas y apartamentos se encuentran situados en estratos 3 y 4, desplazando la grafica hacia la derecha.

plot_ly(vivienda, x = ~estrato,y=~estrato, type = "bar") %>%
  layout(title = "Distribución de estrato")

areaconst

Encontramos que el valor minimo de area es de 30 y el maximo de 47.463 metros cuadrados y la mayoria de los registros se encuentran desplazados hacia la izquierda con valores menores a los 5000 metros cuadrados.

plot_ly(vivienda, x = ~areaconst, type = "histogram") %>%
  layout(title = "Distribución de areaconst")
summary(vivienda$areaconst)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##      30      80     122     174     227    1745       3

Zona

La mayoria de registros de casas y apartamentos se encuentran ubicados en la zona sur de la ciudad, aunque en el punto anterior identificamos que posiblemente esta clasificacion por zonas podria tener ciertos problemas.

plot_ly(vivienda, x = ~zona,y=~zona, type = "bar") %>%
  layout(title = "Distribución de Zona")
summary(vivienda)
##        id           zona               piso              estrato     
##  Min.   :   1   Length:8246        Length:8246        Min.   :3.000  
##  1st Qu.:2080   Class :character   Class :character   1st Qu.:4.000  
##  Median :4164   Mode  :character   Mode  :character   Median :5.000  
##  Mean   :4161                                         Mean   :4.637  
##  3rd Qu.:6244                                         3rd Qu.:5.000  
##  Max.   :8319                                         Max.   :6.000  
##  NA's   :3                                            NA's   :3      
##     preciom         areaconst     parqueaderos        banios      
##  Min.   :  58.0   Min.   :  30   Min.   : 1.000   Min.   : 1.000  
##  1st Qu.: 220.0   1st Qu.:  80   1st Qu.: 1.000   1st Qu.: 2.000  
##  Median : 330.0   Median : 122   Median : 2.000   Median : 3.000  
##  Mean   : 433.3   Mean   : 174   Mean   : 1.834   Mean   : 3.128  
##  3rd Qu.: 540.0   3rd Qu.: 227   3rd Qu.: 2.000   3rd Qu.: 4.000  
##  Max.   :1999.0   Max.   :1745   Max.   :10.000   Max.   :10.000  
##  NA's   :3        NA's   :3      NA's   :1558     NA's   :3       
##   habitaciones        tipo              barrio             longitud     
##  Min.   : 1.000   Length:8246        Length:8246        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.634                                         Mean   :-76.53  
##  3rd Qu.: 4.000                                         3rd Qu.:-76.52  
##  Max.   :10.000                                         Max.   :-76.46  
##  NA's   :3                                              NA's   :3       
##     latitud          base          
##  Min.   :3.333   Length:8246       
##  1st Qu.:3.381   Class :character  
##  Median :3.416   Mode  :character  
##  Mean   :3.418                     
##  3rd Qu.:3.452                     
##  Max.   :3.498                     
##  NA's   :3
str(vivienda)
## spc_tbl_ [8,246 × 14] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id          : num [1:8246] 1147 1169 1350 5992 1212 ...
##  $ zona        : chr [1:8246] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
##  $ piso        : chr [1:8246] NA NA NA "02" ...
##  $ estrato     : num [1:8246] 3 3 3 4 5 5 4 5 5 5 ...
##  $ preciom     : num [1:8246] 250 320 350 400 260 240 220 310 320 780 ...
##  $ areaconst   : num [1:8246] 70 120 220 280 90 87 52 137 150 380 ...
##  $ parqueaderos: num [1:8246] 1 1 2 3 1 1 2 2 2 2 ...
##  $ banios      : num [1:8246] 3 2 2 5 2 3 2 3 4 3 ...
##  $ habitaciones: num [1:8246] 6 3 4 3 3 3 3 4 6 3 ...
##  $ tipo        : chr [1:8246] "Casa" "Casa" "Casa" "Casa" ...
##  $ barrio      : chr [1:8246] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
##  $ longitud    : num [1:8246] -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ latitud     : num [1:8246] 3.43 3.43 3.44 3.44 3.46 ...
##  $ base        : chr [1:8246] "Base 4" "Base 4" "Base 4" "Base 5" ...
##  - attr(*, "spec")=List of 3
##   ..$ cols   :List of 13
##   .. ..$ id          : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ zona        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ piso        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ estrato     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ preciom     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ areaconst   : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ parqueaderos: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ banios      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ habitaciones: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ tipo        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ barrio      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ longitud    : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ latitud     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   ..$ default: list()
##   .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
##   ..$ delim  : chr ";"
##   ..- attr(*, "class")= chr "col_spec"
##  - attr(*, "problems")=<externalptr>
vivienda$estrato=as.numeric(vivienda$estrato)

Como los valores faltantes de las variables preciom, areaconst, estrato, banio, habitaciones son pocos entre 2 y 3 se procede a eliminar estos valores para la futura creacion de un modelo.

vivienda1 <- na.omit(vivienda[c("preciom","areaconst","estrato","banios","habitaciones")])

Correlacion

Una vez todas las variables son del tipo correcto realizamos el analisis de correlacion, para el caso de preciom y las variables predictoras habitaciones, banios, estrato, areaconst obtuvimos los siguientes resultados:

  • preciom y habitaciones: Tienen una correlacion positiva debil (0.275).Esto significa que a medida que aumenta el número de habitaciones, es más probable que aumente el precio de la vivienda, pero la relación no es muy fuerte.

  • preciom y banios: Tienen una correlación positiva moderadamente fuerte (0.685). Esto significa que a medida que aumenta el número de baños, es más probable que aumente el precio de la vivienda, y la relación es más fuerte que en el caso de las habitaciones.

  • preciom y estrato: Tienen una correlación positiva moderadamente fuerte (0.612). Esto significa que a medida que aumenta el estrato de la vivienda, es más probable que aumente el precio de la vivienda, y la relación es similar a la de los baños.

  • preciom y areacost: tienen una correlación positiva muy débil (0.083). Esto significa que hay una relación muy débil entre el tamaño de la vivienda y su precio.

Luego procedemos a revisar la correlacion que tienen las variables predictoras entre si:

  • areaconst y habiaciones: Tienen una correlación positiva muy débil (0.065). Esto significa que hay una relación muy débil entre el tamaño de la vivienda y el número de habitaciones.

  • areaconst y banios: Tienen una correlación positiva muy débil (0.094). Esto significa que hay una relación muy débil entre el tamaño de la vivienda y el número de baños.

  • areaconst y estrato: Tienen una correlación positiva muy débil (0.066). Esto significa que hay una relación muy débil entre el tamaño de la vivienda y su estrato.

  • estrato y habitaciones: Tienen una correlación negativa muy débil (-0.085). Esto significa que hay una relación muy débil entre el estrato de la vivienda y el número de habitaciones.

  • estrato y banios: Tienen una correlación positiva moderadamente fuerte (0.425). Esto significa que hay una relación moderadamente fuerte entre el estrato de la vivienda y el número de baños.

  • banios y habitaciones: Tienen una correlación positiva moderadamente fuerte (0.594). Esto significa que hay una relación moderadamente fuerte entre el número de baños y el número de habitaciones.

Encontramos que la correlacion entre banios y habitaciones indica cierta presencia de multicolinealidad entre las variables. Esto puede generar problemas en el modelo de regresion lineal y conducir a una mayor variacion en variabilidad en los errores de prediccion. Por eso a la hora de construir el modelo sera importante utilizar metodos como el de seleccion de variables en especial el stepwise.

cor_1 <-vivienda1[,c("preciom","areaconst","estrato","banios","habitaciones")]
library(GGally)
ggpairs(cor_1, title=" ") 

vivienda %>% 
  select(preciom, zona) %>% 
  mutate(zona = as.numeric(factor(vivienda$zona))) %>% 
  cor(method = "spearman")
##         preciom zona
## preciom       1   NA
## zona         NA    1