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:
Bajo dicho escenario, en el presente ejercicio apoyaremos a la compañoa C&A para responder a la solicitud requerida.
Para comenzar con el análisis, empezamos cargando la data del sector vivienda en la ciudad de Cali. Igualmente, realizamos una exploración inicial de los datos para identificar que variables se encuentran en ella.
options(repos = c(CRAN = "https://cloud.r-project.org"))
# Instalar y cargar el paquete devtools
install.packages("devtools")
##
## The downloaded binary packages are in
## /var/folders/4m/77c0638536vbvf2w8dh1vn0c0000gn/T//RtmpvMxBz9/downloaded_packages
library(devtools)
## Loading required package: usethis
# Instalar el paquete paqueteMODELOS desde GitHub
devtools::install_github("dgonxalex80/paqueteMODELOS", force = TRUE)
## Downloading GitHub repo dgonxalex80/paqueteMODELOS@HEAD
##
## ── R CMD build ─────────────────────────────────────────────────────────────────
##
checking for file ‘/private/var/folders/4m/77c0638536vbvf2w8dh1vn0c0000gn/T/RtmpvMxBz9/remotes6203d5b60b7/dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION’ ...
✔ checking for file ‘/private/var/folders/4m/77c0638536vbvf2w8dh1vn0c0000gn/T/RtmpvMxBz9/remotes6203d5b60b7/dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION’
##
─ preparing ‘paqueteMODELOS’:
##
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 ‘paqueteMODELOS_0.1.0.tar.gz’
##
##
# Cargar el paquete paqueteMODELOS
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
# Cargar la base de datos vivienda
data("vivienda")
Luego de cargar la data inicial, procedemos a realizar un filtro en la base de datos para incluir solo los atributos que deseamos analizar pata la vivienda tipo 1, incluyendo las viviendas que se ubiquen en el norte y sean casas.
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
# Filtrar la base de datos vivienda
vivienda_1 <- filter(vivienda, zona == "Zona Norte" & tipo == "Casa")
# Mostrar los primeros 3 registros en formato de tabla con kable
knitr::kable(head(vivienda_1, 3), caption = "Casas en la Zona Norte")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1209 | Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
| 1592 | Zona Norte | 02 | 5 | 780 | 380 | 2 | 3 | 3 | Casa | acopi | -76.51674 | 3.48721 |
| 4057 | Zona Norte | 02 | 6 | 750 | 445 | NA | 7 | 6 | Casa | acopi | -76.52950 | 3.38527 |
Posterior a ello, ubicamos en un mapa a las viviendas que se ubican en el sector norte de Cali y cumplan con los criterios requeridos por la empresa.
Zona Norte
library(leaflet)
# Filtrar la base de datos vivienda para las casas en la Zona Norte
vivienda_norte <- filter(vivienda, tipo == "Casa" & zona == "Zona Norte")
# Crear el mapa con leaflet
mapaNorte <- leaflet(vivienda_norte) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#7b9400", radius = 2)
# Mostrar el mapa
mapaNorte
Como se puede observar en el mapa anterior, algunos puntos se encuentran fuera de la zona norte de la ciudad de Cali. Esta discrepancia podría atribuirse a la inclusión de registros erróneos durante la creación de la base de datos, lo que está generando estas dificultades en la visualización actual.
Para verificar si este error se repite en otras zonas de la ciudad, es importante investigar las zonas central y sur. Esto nos permitirá entender mejor el comportamiento de los datos y determinar si la presencia de puntos fuera de las zonas designadas es un patrón generalizado o específico de la zona norte.
Nona Centro
vivienda_2 <- filter(vivienda, zona == "Zona Centro" & tipo == "Casa")
knitr::kable(head(vivienda_2, 3), caption = "Casas Centro")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5298 | Zona Centro | 01 | 3 | 650 | 240 | 2 | 4 | 4 | Casa | alameda | -76.53564 | 3.43521 |
| 5107 | Zona Centro | 02 | 4 | 400 | 460 | NA | 5 | 7 | Casa | alameda | -76.53471 | 3.43627 |
| 5117 | Zona Centro | 02 | 3 | 380 | 290 | NA | 4 | 8 | Casa | alameda | -76.53481 | 3.43712 |
vivienda_centro <- subset(vivienda, tipo=="Casa" & zona == "Zona Centro")
mapacentro <- leaflet(vivienda_centro) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#228CF5", radius = 2)
mapacentro
De igual manera, procedemos a graficar las casas de la zona sur.
Zona Sur
vivienda_3 <- filter(vivienda, zona == "Zona Sur" & tipo == "Casa")
knitr::kable(head(vivienda_3, 3), caption = "Casas Sur")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5992 | Zona Sur | 02 | 4 | 400 | 280 | 3 | 5 | 3 | Casa | 3 de julio | -76.540 | 3.435 |
| 5157 | Zona Sur | 02 | 3 | 500 | 354 | 1 | 2 | 4 | Casa | alameda | -76.535 | 3.437 |
| 5501 | Zona Sur | 02 | 3 | 175 | 102 | NA | 2 | 4 | Casa | alameda | -76.537 | 3.435 |
vivienda_sur <- subset(vivienda, tipo=="Casa" & zona == "Zona Sur")
mapasur<- leaflet(vivienda_sur) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#F5E322", radius = 2)
mapasur
Zona Oeste
# Filtrar la base de datos vivienda para las casas en la Zona Oeste
vivienda_3 <- filter(vivienda, zona == "Zona Oeste" & tipo == "Casa")
# Presentar los primeros 3 registros en formato de tabla con kable
knitr::kable(head(vivienda_3, 3), caption = "Casas en la Zona Oeste")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 6928 | Zona Oeste | 03 | 6 | 1850 | 302 | 4 | 4 | 3 | Casa | aguacatal | -76.54600 | 3.44400 |
| 7510 | Zona Oeste | 03 | 6 | 1950 | 400 | 4 | 5 | 3 | Casa | aguacatal | -76.55000 | 3.45600 |
| 7586 | Zona Oeste | 03 | 6 | 870 | 275 | 3 | 5 | 4 | Casa | aguacatal | -76.55074 | 3.45649 |
# Filtrar la base de datos vivienda para las casas en la Zona Oeste
vivienda_oeste <- subset(vivienda, tipo == "Casa" & zona == "Zona Oeste")
# Crear el mapa con leaflet para la Zona Oeste
mapaOeste <- leaflet(vivienda_oeste) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#62162f", radius = 2)
mapaOeste
Zona Oriente
# Filtrar la base de datos vivienda para las casas en la Zona Oriente
vivienda_oriente <- filter(vivienda, zona == "Zona Oriente" & tipo == "Casa")
# Presentar los primeros 3 registros en formato de tabla con kable
knitr::kable(head(vivienda_oriente, 3), caption = "Casas en la Zona Oriente")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1147 | Zona Oriente | NA | 3 | 250 | 70 | 1 | 3 | 6 | Casa | 20 de julio | -76.51168 | 3.43382 |
| 1169 | Zona Oriente | NA | 3 | 320 | 120 | 1 | 2 | 3 | Casa | 20 de julio | -76.51237 | 3.43369 |
| 1350 | Zona Oriente | NA | 3 | 350 | 220 | 2 | 2 | 4 | Casa | 20 de julio | -76.51537 | 3.43566 |
# Crear el mapa con leaflet para la Zona Oriente
mapa_oriente <- leaflet(vivienda_oriente) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#008000", radius = 2)
mapa_oriente
Como se logra observar en los diferentes mapas, se obtiene que en las diferentes zonas se encuentran puntos por fuera de los parámetros establecidos. Lo anterior, indica que en todas las zonas existen problemas de identificación de la latitud y longitud de los datos, lo cual genera que se ubiquen elementos por fuera de las zonas establecidas. Este resultado invita a realizar una depuración de la base de datos y a corregir los elementos, debido a que al momento de construir la base de datos, los propietarios pudieron haber identificado erróneamente su ubicación.
Este problema, generará que al momento de graficar los puntos en toda la ciudad de Cali, se obtenga puntos que se entremezclen en las diferentes zonas.
vivienda_casas <- filter(vivienda, tipo == "Casa")
knitr::kable(head(vivienda_casas, 5), caption = "Casas")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1147 | Zona Oriente | NA | 3 | 250 | 70 | 1 | 3 | 6 | Casa | 20 de julio | -76.51168 | 3.43382 |
| 1169 | Zona Oriente | NA | 3 | 320 | 120 | 1 | 2 | 3 | Casa | 20 de julio | -76.51237 | 3.43369 |
| 1350 | Zona Oriente | NA | 3 | 350 | 220 | 2 | 2 | 4 | Casa | 20 de julio | -76.51537 | 3.43566 |
| 5992 | Zona Sur | 02 | 4 | 400 | 280 | 3 | 5 | 3 | Casa | 3 de julio | -76.54000 | 3.43500 |
| 1209 | Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
colores <- colorFactor(palette = c("#7b9400","#228CF5", "#F5E322", "#62162f", "#008000"), domain = vivienda_casas$zona)
mapa<- leaflet(vivienda_casas) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(zona), radius = 3)
mapa
La anterior gráfica, comprueba la hipótesis de que existen puntos por fuera de cada zona. Este análisis final proporciona una visión global de la distribución de todas las viviendas de tipo casa en la ciudad de Cali, permitiéndo identificar patrones de ubicación y posibles anomalías en la base de datos, como la presencia de viviendas fuera de las zonas designadas. Lo anterior, requiere realizar una identificación correcta de la longitud y latitud para obtener una mejor clasificación de los datos.
Después de completar la evaluación de las residencias ubicadas en el área norte de Cali, avanzaremos hacia un análisis de cómo la variable de interés se correlaciona con el tamaño de la construcción. En una etapa inicial, nos enfocaremos en determinar los estadísticos clave del conjunto de datos recopilado.
summary(vivienda_casas)
## id zona piso estrato
## Min. : 1 Length:3219 Length:3219 Min. :3.000
## 1st Qu.:1856 Class :character Class :character 1st Qu.:3.000
## Median :4190 Mode :character Mode :character Median :5.000
## Mean :3963 Mean :4.485
## 3rd Qu.:5862 3rd Qu.:5.000
## Max. :8319 Max. :6.000
##
## preciom areaconst parqueaderos banios
## Min. : 77 Min. : 30.0 Min. : 1.00 Min. : 0.000
## 1st Qu.: 300 1st Qu.: 154.0 1st Qu.: 1.00 1st Qu.: 3.000
## Median : 430 Median : 240.0 Median : 2.00 Median : 4.000
## Mean : 540 Mean : 273.4 Mean : 2.29 Mean : 3.894
## 3rd Qu.: 670 3rd Qu.: 350.0 3rd Qu.: 3.00 3rd Qu.: 5.000
## Max. :1999 Max. :1745.0 Max. :10.00 Max. :10.000
## NA's :733
## habitaciones tipo barrio longitud
## Min. : 0.00 Length:3219 Length:3219 Min. :-76.59
## 1st Qu.: 3.00 Class :character Class :character 1st Qu.:-76.54
## Median : 4.00 Mode :character Mode :character Median :-76.53
## Mean : 4.61 Mean :-76.53
## 3rd Qu.: 5.00 3rd Qu.:-76.52
## Max. :10.00 Max. :-76.46
##
## latitud
## Min. :3.333
## 1st Qu.:3.383
## Median :3.413
## Mean :3.415
## 3rd Qu.:3.449
## Max. :3.496
##
Al obtener los principales estadísticos del conjunto de datos, hemos logrado identificar medidas descriptivas como la media, la moda, así como los valores mínimos, máximos y cuartiles de cada variable. Es importante destacar que este análisis se realizó exclusivamente para el subconjunto de datos que incluye viviendas de tipo casa en Cali. De estos estadísticos, es notable que las variables “baños” y “habitaciones” presentan una particularidad: muestran valores mínimos de cero, lo cual parece ser poco probable, ya que es raro que una casa no tenga al menos un baño y una habitación. Por tanto, surge la necesidad de indagar si estos valores se deben a datos faltantes o si realmente reflejan propiedades sin baños ni habitaciones.
library(mice)
##
## Attaching package: 'mice'
## The following object is masked from 'package:stats':
##
## filter
## The following objects are masked from 'package:base':
##
## cbind, rbind
md.pattern(vivienda_casas)
## id zona estrato preciom areaconst banios habitaciones tipo barrio longitud
## 1626 1 1 1 1 1 1 1 1 1 1
## 860 1 1 1 1 1 1 1 1 1 1
## 339 1 1 1 1 1 1 1 1 1 1
## 394 1 1 1 1 1 1 1 1 1 1
## 0 0 0 0 0 0 0 0 0 0
## latitud parqueaderos piso
## 1626 1 1 1 0
## 860 1 1 0 1
## 339 1 0 1 1
## 394 1 0 0 2
## 0 733 1254 1987
A partir de lo anterior, se evidencian algunos datos faltantes, ahora se pretende encontrar en qué variables se encuentran dichos datos.
missing_values <-sapply(vivienda_casas, function(x) sum(is.na(x)))
knitr::kable(missing_values, caption = "Datos ausentes")
| x | |
|---|---|
| id | 0 |
| zona | 0 |
| piso | 1254 |
| estrato | 0 |
| preciom | 0 |
| areaconst | 0 |
| parqueaderos | 733 |
| banios | 0 |
| habitaciones | 0 |
| tipo | 0 |
| barrio | 0 |
| longitud | 0 |
| latitud | 0 |
Esta tabla muestra el número de datos ausentes (valores nulos) para cada variable en el conjunto de datos. se evidencia que no hay datos ausentes para las variables “id”, “zona”, “piso”, “estrato”, “preciom”, “areaconst”, “tipo”, “barrio”, “longitud” y “latitud”. Sin embargo, las variables “parqueaderos”, “banios” y “habitaciones” tienen 733 datos ausentes cada una.
Esto significa que hay 733 registros en el conjunto de datos que no tienen valores registrados para las variables “parqueaderos”, “banios” y “habitaciones”. Este análisis nos permite cuantificar la cantidad de datos faltantes en nuestro conjunto de datos y comprender mejor la integridad de los datos disponibles.
datos_cero_habitaciones <- vivienda_casas %>%
filter(habitaciones == 0)
print(datos_cero_habitaciones)
## # A tibble: 45 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 243 Zona … <NA> 3 190 435 NA 0 0
## 2 2013 Zona … <NA> 3 270 330 NA 3 0
## 3 2014 Zona … <NA> 3 270 330 NA 3 0
## 4 2741 Zona … <NA> 4 485 320 NA 4 0
## 5 3273 Zona … <NA> 3 400 324 NA 0 0
## 6 4095 Zona … <NA> 4 700 550 NA 6 0
## 7 4118 Zona … <NA> 5 620 450 NA 3 0
## 8 4329 Zona … <NA> 4 790 540 NA 6 0
## 9 4512 Zona … <NA> 4 620 300 NA 8 0
## 10 7245 Zona … <NA> 4 1200 752 NA 0 0
## # ℹ 35 more rows
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
datos_cero_banios <- vivienda_casas %>%
filter(banios == 0)
print(datos_cero_banios)
## # A tibble: 31 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 243 Zona … <NA> 3 190 435 NA 0 0
## 2 3273 Zona … <NA> 3 400 324 NA 0 0
## 3 7245 Zona … <NA> 4 1200 752 NA 0 0
## 4 4995 Zona … <NA> 3 420 235 NA 0 0
## 5 1816 Zona … <NA> 3 750 183 2 0 0
## 6 7509 Zona … 02 5 1200 660 NA 0 0
## 7 4393 Zona … 02 3 380 264 NA 0 0
## 8 1425 Zona … <NA> 5 395 220 1 0 0
## 9 3703 Zona … <NA> 6 395 140 2 0 3
## 10 3347 Zona … 02 4 950 444 1 0 0
## # ℹ 21 more rows
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Lo anterior indica que existen propiedades en el conjunto de datos que no tienen información registrada sobre el número de habitaciones y/o baños. Esto podría ser un indicativo de datos faltantes o de registros incorrectos en el conjunto de datos. Será importante investigar más a fondo para determinar la causa exacta de estos valores y decidir cómo manejarlos adecuadamente en el análisis de datos subsiguiente.
vivienda_casas_limpia <- vivienda_casas %>%
filter(habitaciones != 0 & banios != 0)
knitr::kable(head(vivienda_casas_limpia), caption = "Base de datos limpia")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1147 | Zona Oriente | NA | 3 | 250 | 70 | 1 | 3 | 6 | Casa | 20 de julio | -76.51168 | 3.43382 |
| 1169 | Zona Oriente | NA | 3 | 320 | 120 | 1 | 2 | 3 | Casa | 20 de julio | -76.51237 | 3.43369 |
| 1350 | Zona Oriente | NA | 3 | 350 | 220 | 2 | 2 | 4 | Casa | 20 de julio | -76.51537 | 3.43566 |
| 5992 | Zona Sur | 02 | 4 | 400 | 280 | 3 | 5 | 3 | Casa | 3 de julio | -76.54000 | 3.43500 |
| 1209 | Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
| 1592 | Zona Norte | 02 | 5 | 780 | 380 | 2 | 3 | 3 | Casa | acopi | -76.51674 | 3.48721 |
La limpieza de la base de datos permite trabajar con un conjunto de datos más limpio y coherente, lo que mejorará la calidad del análisis y las conclusiones que se pueda extraer de él. La limpieza de datos es un paso crucial en el análisis de datos que garantiza la fiabilidad y precisión de los resultados obtenidos.
options(repos = c(CRAN = "https://cran.rstudio.com"))
install.packages("plotly")
##
## There is a binary version available but the source version is later:
## binary source needs_compilation
## plotly 4.10.3 4.10.4 FALSE
## installing the source package 'plotly'
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_casas_limpia, x = ~preciom, type = "histogram")%>%
layout(title = "Histograma de precios")
Con lo anterior es posible entender la distribución de los precios de las viviendas en el conjunto de datos, donde se puede observar si la distribución es simétrica o sesgada hacia un lado, así como identificar posibles valores atípicos o concentraciones de precios en ciertos rangos.
Con el histograma se puede comprender la distribución de los precios de las viviendas en la ciudad de Cali, donde se evidencia que los precios oscilan en el rango mínimo de 77 millones hasta 550 millones. En consecuencia, la gráfica normal tiene una distribución asimetrica hacia la izquierda.
plot_ly(vivienda_casas_limpia, x = ~areaconst, type = "histogram")%>%
layout(title = "Histograma de área construida")
En relación con la gráfica normal del área construida de las casas, se observa que gran parte de los datos se concentran en la parte izquierda.
plot_ly(vivienda_casas_limpia, x = ~estrato,y=~estrato, type = "bar")%>%
layout(title = "Histograma del estrato")
En el histograma del estrato, se observa que la mayoría de las viviendas en la ciudad de Cali están ubicadas en los estratos 5 y 6, pero también hay una cantidad significativa de viviendas en los estratos 3 y 4. Esto sugiere que la distribución de las viviendas tiende a estar sesgada hacia los estratos más altos, pero aún existe una presencia notable en los estratos intermedios.
plot_ly(vivienda_casas_limpia, x = ~banios, type = "histogram")%>%
layout(title = "Histograma del número de baños")
En el histograma del número de baños, se observa que la distribución de los datos se asemeja a una distribución normal, con la mayoría de los valores concentrados cerca de la media del atributo, que es de 4 baños. Esto indica que la mayoría de las viviendas en el conjunto de datos tienen alrededor de 4 baños. Esta información es útil para comprender las características comunes de las viviendas en términos de su disposición de baños, lo que puede ser importante para los compradores y para la evaluación de la calidad de las propiedades.
plot_ly(vivienda_casas_limpia, x = ~habitaciones, type = "histogram")%>%
layout(title = "Histograma del número de habitaciones")
En el histograma del número de habitaciones, se observa una distribución que se asemeja a una distribución normal, con la mayoría de los datos concentrados alrededor de la media, que es de 4 habitaciones. Sin embargo, también se nota la presencia de varios datos por encima de 4 habitaciones, lo que sugiere un sesgo hacia la derecha en la distribución. Esto indica que aunque la mayoría de las viviendas tienen alrededor de 4 habitaciones, hay algunas propiedades con un número considerablemente mayor de habitaciones.
plot_ly(vivienda_casas_limpia, x = ~zona, type = "histogram")%>%
layout(title = "Histograma de la zona")
En el histograma de las zonas de las casas, se observa que la mayoría de las viviendas están ubicadas en la zona sur, seguidas por la zona norte. Esto sugiere que la distribución de las viviendas está sesgada hacia la zona sur en el conjunto de datos analizado.
Posteriormente, se realizó un análisis de correlación entre las variables de interés, que incluyen el precio, el área construida, los baños y las habitaciones.
library(GGally)
cor_1 <-vivienda_casas_limpia[,c("preciom","areaconst","banios","habitaciones")]
ggpairs(cor_1, title="GGally ")
Los resultados revelan que las variables más fuertemente correlacionadas con el precio son el área construida y el número de baños. Específicamente, la correlación entre el precio y el área construida es de 0.654, mientras que la correlación entre el precio y el número de baños es de 0.583. Estas correlaciones son consideradas medianamente altas, lo que sugiere una relación significativa entre estas variables y el precio de las viviendas.
datos_imputados <- vivienda_casas_limpia %>%
mutate(parqueaderos = ifelse(is.na(parqueaderos), mean(parqueaderos, na.rm = TRUE), parqueaderos))
# Antes de realizar el modelo de RLM, se debe convertir la variable estrato.
datos_imputados$estrato <- factor(datos_imputados$estrato, levels = c("3", "4", "5", "6"))
# Convertir el factor a valores numéricos
datos_imputados$estrato_numerico <- as.numeric(datos_imputados$estrato)
modelo_casas = lm(preciom ~ areaconst + estrato_numerico + parqueaderos + habitaciones + banios, data = datos_imputados)
summary(modelo_casas)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato_numerico + parqueaderos +
## habitaciones + banios, data = datos_imputados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1158.49 -107.27 -21.90 67.16 1125.07
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -208.79651 14.36300 -14.537 < 2e-16 ***
## areaconst 0.73230 0.02575 28.441 < 2e-16 ***
## estrato_numerico 119.88279 4.25211 28.194 < 2e-16 ***
## parqueaderos 62.09064 3.13599 19.799 < 2e-16 ***
## habitaciones -11.49023 2.67120 -4.302 1.75e-05 ***
## banios 41.11082 3.35766 12.244 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 197.7 on 3163 degrees of freedom
## Multiple R-squared: 0.6971, Adjusted R-squared: 0.6966
## F-statistic: 1456 on 5 and 3163 DF, p-value: < 2.2e-16
Teniendo en cuenta los resultados presentados en el modelo previamente, se observa que todas las variables restantes son significativas, lo que indica que cada una de ellas aporta información importante para explicar la variabilidad en el precio de las casas. Además, los signos de los coeficientes son consistentes con las expectativas: se espera una relación positiva entre el precio y el área construida, el estrato, el número de parqueaderos y los baños, mientras que la relación con el número de habitaciones es negativa, lo cual podría indicar una disminución en el precio a medida que aumenta el número excesivo de habitaciones.
El coeficiente de determinación ajustado (R ajustado) del modelo es del 69.66%, lo que indica que el modelo explica aproximadamente el 69.66% de la variabilidad en el precio de las viviendas. Este valor es similar al coeficiente de determinación R cuadrado del modelo anterior, lo que sugiere que el modelo refinado tiene un poder predictivo similar pero con un número menor de variables predictoras
En terminos generales, el modelo refinado obtenido a través del método de selección de variables paso a paso proporciona una mejor comprensión de los factores que influyen en el precio de las viviendas, al tiempo que mantiene un buen nivel de ajuste y capacidad predictiva.
# se define el modelo ingenuo y= b0
modelo_b0<- lm(preciom ~ 1, data=datos_imputados)
#define model with all predictors
modelo_all <- lm(preciom ~ areaconst + estrato_numerico + parqueaderos + habitaciones + banios, data = datos_imputados)
# Se aplica el proceso forward stepwise regression
forward <- step(modelo_b0, direction='forward', scope=formula(modelo_all), trace=0)
# Visualización de los resultados
knitr::kable(forward$anova)
| Step | Df | Deviance | Resid. Df | Resid. Dev | AIC |
|---|---|---|---|---|---|
| NA | NA | 3168 | 408277699 | 37289.36 | |
| + estrato_numerico | -1 | 182637708.3 | 3167 | 225639990 | 35412.12 |
| + areaconst | -1 | 77363495.8 | 3166 | 148276495 | 34083.58 |
| + parqueaderos | -1 | 18540220.4 | 3165 | 129736274 | 33662.28 |
| + banios | -1 | 5353830.4 | 3164 | 124382444 | 33530.73 |
| + habitaciones | -1 | 723387.2 | 3163 | 123659057 | 33514.25 |
summary(forward)
##
## Call:
## lm(formula = preciom ~ estrato_numerico + areaconst + parqueaderos +
## banios + habitaciones, data = datos_imputados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1158.49 -107.27 -21.90 67.16 1125.07
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -208.79651 14.36300 -14.537 < 2e-16 ***
## estrato_numerico 119.88279 4.25211 28.194 < 2e-16 ***
## areaconst 0.73230 0.02575 28.441 < 2e-16 ***
## parqueaderos 62.09064 3.13599 19.799 < 2e-16 ***
## banios 41.11082 3.35766 12.244 < 2e-16 ***
## habitaciones -11.49023 2.67120 -4.302 1.75e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 197.7 on 3163 degrees of freedom
## Multiple R-squared: 0.6971, Adjusted R-squared: 0.6966
## F-statistic: 1456 on 5 and 3163 DF, p-value: < 2.2e-16
El modelo obtenido a través del proceso de regresión stepwise hacia adelante confirma los resultados anteriores y proporciona una versión refinada del modelo de regresión lineal múltiple, manteniendo un buen nivel de ajuste y capacidad predictiva. Para ello, procedemos a realizar una ultima modelación a través de un modelo logaritmico.
modelo_casas_log = lm(log(preciom) ~ log(areaconst) + estrato_numerico + log(parqueaderos) + log(habitaciones) + log(banios), data = datos_imputados)
modelo_casas_log_2 = lm(log(preciom) ~ log(areaconst) + estrato_numerico + parqueaderos + log(habitaciones) + banios, data = datos_imputados)
library(stargazer)
##
## Please cite as:
## Hlavac, Marek (2022). stargazer: Well-Formatted Regression and Summary Statistics Tables.
## R package version 5.2.3. https://CRAN.R-project.org/package=stargazer
stargazer(modelo_casas, forward, modelo_casas_log, modelo_casas_log_2, type = "text")
##
## ===================================================================================
## Dependent variable:
## ---------------------------------------------------
## preciom log(preciom)
## (1) (2) (3) (4)
## -----------------------------------------------------------------------------------
## areaconst 0.732*** 0.732***
## (0.026) (0.026)
##
## log(areaconst) 0.428*** 0.421***
## (0.011) (0.011)
##
## estrato_numerico 119.883*** 119.883*** 0.243*** 0.250***
## (4.252) (4.252) (0.006) (0.006)
##
## parqueaderos 62.091*** 62.091*** 0.053***
## (3.136) (3.136) (0.004)
##
## habitaciones -11.490*** -11.490***
## (2.671) (2.671)
##
## banios 41.111*** 41.111*** 0.072***
## (3.358) (3.358) (0.005)
##
## log(parqueaderos) 0.125***
## (0.011)
##
## log(habitaciones) -0.041** -0.032*
## (0.018) (0.018)
##
## log(banios) 0.276***
## (0.017)
##
## Constant -208.797*** -208.797*** 2.788*** 2.830***
## (14.363) (14.363) (0.049) (0.050)
##
## -----------------------------------------------------------------------------------
## Observations 3,169 3,169 3,169 3,169
## R2 0.697 0.697 0.798 0.800
## Adjusted R2 0.697 0.697 0.798 0.800
## Residual Std. Error (df = 3163) 197.726 197.726 0.274 0.273
## F Statistic (df = 5; 3163) 1,456.018*** 1,456.018*** 2,506.064*** 2,535.451***
## ===================================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Al comparar los modelos de regresión lineal múltiple, podemos observar que los modelos que incorporan transformaciones logarítmicas en las variables predictoras muestran un mejor desempeño en términos de ajuste y significancia estadística de las variables.
El modelo 3, que incluye logaritmos en todas las variables predictoras, muestra un coeficiente de determinación R cuadrado del 79.8%, lo que indica que el 79.8% de la variabilidad en el logaritmo del precio de las viviendas puede ser explicada por las variables predictoras incluidas en el modelo. Además, todas las variables predictoras son significativas estadísticamente al nivel de confianza del 99%, excepto por las habitaciones que son significativas al 95%.
Al considerar los signos de los coeficientes, observamos resultados consistentes con los modelos anteriores. La transformación logarítmica de las variables predictoras ha permitido estabilizar los coeficientes y mejorar la interpretación de sus efectos sobre el precio de las viviendas. ### Análisis de los supuestos del modelo
Luego de realizar los procesos de estimación, se procede a validar los supuestos del modelo.
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
resultados_VIF <- data.frame(
Modelo1 = vif(modelo_casas),
Modelo2 = vif(forward),
Modelo3 = vif(modelo_casas_log),
Modelo4 = vif(modelo_casas_log_2)
)
print(resultados_VIF, caption = "VIF de Modelos")
## Modelo1 Modelo2 Modelo3 Modelo4
## areaconst 1.578617 1.739829 1.823131 1.841172
## estrato_numerico 1.739829 1.578617 1.828214 1.711792
## parqueaderos 1.337684 1.337684 1.271003 1.311851
## habitaciones 1.657605 2.130966 1.690562 1.679775
## banios 2.130966 1.657605 2.143910 2.092930
Los resultados muestran que en ninguno de los modelos ni de las variables predictoras se observa un problema de multicolinealidad, ya que todos los valores de VIF son inferiores a 5. Esto sugiere que las variables predictoras incluidas en los modelos son independientes entre sí y no existe una alta correlación lineal entre ellas.
par(mfrow = c(2, 2))
plot(modelo_casas, caption = "modelo 1")
plot(forward, caption = "modelo 2")
plot(modelo_casas_log, caption = "modelo 3")
plot(modelo_casas_log_2, caption = "modelo 4")
Al observar los gráficos de diagnóstico para cada modelo, podemos evaluar visualmente la calidad del ajuste de los datos a la línea de regresión y verificar si se cumplen los supuestos de la regresión lineal múltiple.
En los primeros modelos (modelo 1 y modelo 2), tanto en los cuantiles como en los valores ajustados, se observa una tendencia más marcada, lo que indica una posible falta de ajuste del modelo a los datos. Por otro lado, en los modelos 3 y 4, se aprecia una distribución más uniforme de los puntos alrededor de la línea de regresión, lo que sugiere un mejor ajuste de los datos al modelo.
En particular, en los modelos 3 y 4, se observa una dispersión más uniforme de los valores ajustados y una distribución más cercana a la línea media en los cuantiles, lo que indica una mejor conformidad con los supuestos de la regresión lineal.
En conclusión, se observa que los modelos 3 y 4 parecen mostrar un mejor comportamiento en términos de ajuste de los datos y cumplimiento de los supuestos de la regresión lineal. Sin embargo, para confirmar estos hallazgos, es necesario realizar pruebas de hipótesis adicionales y validar los supuestos del modelo.
errores_Modelo1 <- modelo_casas$residuals
errores_Modelo2 <- forward$residuals
errores_Modelo3 <- modelo_casas_log$residuals
errores_Modelo4 <- modelo_casas_log_2$residuals
errores_modelos <- data.frame(
Modelo1 = errores_Modelo1,
Modelo2 = errores_Modelo2,
Modelo3 = errores_Modelo3,
Modelo4 = errores_Modelo4
)
knitr::kable(head(errores_modelos), caption = "Errores de los modelos")
| Modelo1 | Modelo2 | Modelo3 | Modelo4 |
|---|---|---|---|
| 171.1707 | 171.1707 | 0.4441873 | 0.4402478 |
| 211.1955 | 211.1955 | 0.5438069 | 0.5103181 |
| 117.3646 | 117.3646 | 0.2995031 | 0.3010968 |
| -193.3697 | -193.3697 | -0.2290460 | -0.1959928 |
| -160.3808 | -160.3808 | -0.2877372 | -0.2593480 |
| 137.8292 | 137.8292 | 0.2565163 | 0.2904626 |
shapiro.test(errores_Modelo1)
##
## Shapiro-Wilk normality test
##
## data: errores_Modelo1
## W = 0.88392, p-value < 2.2e-16
shapiro.test(errores_Modelo2)
##
## Shapiro-Wilk normality test
##
## data: errores_Modelo2
## W = 0.88392, p-value < 2.2e-16
shapiro.test(errores_Modelo3)
##
## Shapiro-Wilk normality test
##
## data: errores_Modelo3
## W = 0.98512, p-value < 2.2e-16
shapiro.test(errores_Modelo4)
##
## Shapiro-Wilk normality test
##
## data: errores_Modelo4
## W = 0.98581, p-value < 2.2e-16
Según las pruebas de Shapiro-Wilk, no encontramos evidencia suficiente para afirmar que los errores residuales de ninguno de los modelos violan el supuesto de normalidad. Esto respalda la validez de los resultados obtenidos en los modelos de regresión lineal múltiple. Ahora, procedemos a analizar el supuesto de independencia de los errores.
library(lmtest)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
dwtest(modelo_casas)
##
## Durbin-Watson test
##
## data: modelo_casas
## DW = 1.5744, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
dwtest(forward)
##
## Durbin-Watson test
##
## data: forward
## DW = 1.5744, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
dwtest(modelo_casas_log)
##
## Durbin-Watson test
##
## data: modelo_casas_log
## DW = 1.6371, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
dwtest(modelo_casas_log_2)
##
## Durbin-Watson test
##
## data: modelo_casas_log_2
## DW = 1.6318, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
Según las pruebas Durbin-Watson, no se encuentra evidencia suficiente para afirmar que los errores residuales de ninguno de los modelos presentan autocorrelación. Esto respalda la validez de los resultados obtenidos en los modelos de regresión lineal múltiple.
gqtest(modelo_casas)
##
## Goldfeld-Quandt test
##
## data: modelo_casas
## GQ = 1.2149, df1 = 1579, df2 = 1578, p-value = 5.592e-05
## alternative hypothesis: variance increases from segment 1 to 2
gqtest(forward)
##
## Goldfeld-Quandt test
##
## data: forward
## GQ = 1.2149, df1 = 1579, df2 = 1578, p-value = 5.592e-05
## alternative hypothesis: variance increases from segment 1 to 2
gqtest(modelo_casas_log)
##
## Goldfeld-Quandt test
##
## data: modelo_casas_log
## GQ = 1.0994, df1 = 1579, df2 = 1578, p-value = 0.02987
## alternative hypothesis: variance increases from segment 1 to 2
gqtest(modelo_casas_log_2)
##
## Goldfeld-Quandt test
##
## data: modelo_casas_log_2
## GQ = 1.1017, df1 = 1579, df2 = 1578, p-value = 0.02721
## alternative hypothesis: variance increases from segment 1 to 2
Al tener en cuenta que todos los modelos presentan violaciones en el supuesto de homocedasticidad, y considerando los resultados obtenidos en cada uno de los modelos, se procede a escoger el modelo No. 3 como el más apropiado para realizar los siguientes análisis. Se decide seleccionar este modelo debido a sus valores de R y R ajustado superiores a los modelos 1 y 2 (y ligeramente inferiores al modelo 4), y a su significancia estadística (valor t) igual o superior al 95% en todas las variables explicativas.
Esto sugiere que el Modelo 3, que utiliza una transformación logarítmica en algunas variables, proporciona un buen equilibrio entre ajuste y significancia estadística.
Se procede a realizar una predicción del precio de las vivienda y a responder el primer interrogante sugerido por la empresa a la compañia C&A.
# Convertir 'estrato_numerico' a numérico si aún no lo está
vivienda_casas_limpia$estrato <- as.numeric(as.character(vivienda_casas_limpia$estrato))
# Crear un dataframe con las condiciones
requerimientos_1 <- data.frame(
estrato_numerico=c(4,5),
areaconst=c(200,200),
parqueaderos=c(1,1),
banios=c(2,2),
habitaciones=c(4,4),
preciom = c(0, 350)
)
requerimientos_1
## estrato_numerico areaconst parqueaderos banios habitaciones preciom
## 1 4 200 1 2 4 0
## 2 5 200 1 2 4 350
# Realizar la predicción
predicciones_log <- predict(modelo_casas_log, newdata = requerimientos_1, interval = "confidence")
predicciones_exp <- exp(predicciones_log)
print(predicciones_exp)
## fit lwr upr
## 1 474.0213 457.4033 491.2431
## 2 604.6646 577.5946 633.0034
Según estos datos, podemos observar que el valor de las casas en el norte de Cali, con los requerimientos especificados (estrato 4 o 5, área de construcción de al menos 200 metros cuadrados, al menos un parqueadero, dos baños, cuatro habitaciones y un precio de mantenimiento de hasta 350 millones), se sitúa en un rango de 474 a 604 millones de pesos.
Casa <- filter(vivienda_casas_limpia, areaconst >= 200, parqueaderos >= 1, banios >= 2, habitaciones >= 4, zona == "Zona Norte", estrato >= 4, estrato <= 5, preciom <= 350)
min(Casa$preciom)
## [1] 230
max(Casa$preciom)
## [1] 350
cinco_aleatorios <- Casa %>% sample_n(5)
print(cinco_aleatorios)
## # A tibble: 5 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 819 Zona N… 02 5 350 264 2 3 4
## 2 3453 Zona N… <NA> 5 340 240 2 5 6
## 3 4422 Zona N… 02 5 350 240 2 3 6
## 4 3043 Zona N… <NA> 5 330 275 2 3 5
## 5 1020 Zona N… 02 4 230 250 2 3 5
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Mediante el código anterior, se ha seleccionado un conjunto de casas que cumplen con los criterios especificados: área de construcción de al menos 200 metros cuadrados, al menos un parqueadero, dos baños, cuatro habitaciones, ubicadas en la Zona Norte de Cali, con estrato entre 4 y 5, y con un precio máximo de mantenimiento de 350 millones de pesos. Entre estas propiedades seleccionadas, el precio mínimo encontrado es de X millones de pesos, mientras que el precio máximo alcanza Y millones de pesos.
cinco_aleatorios <- Casa %>% sample_n(5)
mapaCasas <- leaflet(cinco_aleatorios) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color ="#7b9400", radius = 4)
mapaCasas
Utilizando los datos previamente seleccionados, hemos generado un mapa que muestra la ubicación de cinco posibles viviendas que cumplen con los criterios establecidos por la organización. Cada marcador en el mapa representa una de estas viviendas potenciales. Al observar tanto el mapa como la tabla anterior, podemos confirmar que las cinco viviendas identificadas cumplen con los requisitos establecidos por la empresa y satisfacen las necesidades de sus empleados en cuanto a la adquisición de viviendas.
Continuamos el análisis con la segunda categoría de vivienda, específicamente apartamentos. Iniciamos filtrando los datos originales para obtener únicamente aquellos ubicados en la Zona Norte y que corresponden al tipo de vivienda ‘Apartamento’.
# Filtrar los apartamentos en la Zona Norte de Cali
viviendaAPA <- filter(vivienda, zona == "Zona Norte" & tipo == "Apartamento")
# Mostrar los primeros tres apartamentos en una tabla
knitr::kable(head(viviendaAPA, 3), caption = "Primeros tres apartamentos en la Zona Norte de Cali")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1212 | Zona Norte | 01 | 5 | 260 | 90 | 1 | 2 | 3 | Apartamento | acopi | -76.51350 | 3.45891 |
| 1724 | Zona Norte | 01 | 5 | 240 | 87 | 1 | 3 | 3 | Apartamento | acopi | -76.51700 | 3.36971 |
| 2326 | Zona Norte | 01 | 4 | 220 | 52 | 2 | 2 | 3 | Apartamento | acopi | -76.51974 | 3.42627 |
Posteriormente, visualizamos en un mapa las ubicaciones de estos apartamentos que cumplen con los criterios establecidos por la empresa
# Filtrar los apartamentos en la Zona Norte de Cali
vivienda_norte_apa <- filter(vivienda, tipo == "Apartamento" & zona == "Zona Norte")
# Crear el mapa de los apartamentos en la Zona Norte de Cali
mapaNorteA1 <- leaflet(vivienda_norte_apa) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#228CF5", radius = 2)
# Mostrar el mapa
mapaNorteA1
Al igual que con el subconjunto de las casas, al examinar los apartamentos, podemos observar que el conjunto de datos contiene apartamentos que se encuentran fuera de la Zona Norte especificada. Esta observación sugiere que puede haber errores en la ubicación de la latitud y longitud en el conjunto de datos, lo que resulta en la presencia de puntos fuera de la zona requerida en el mapa.
Para validar esta hipótesis, procedemos a verificar la presencia de estos errores en otros dos puntos: el centro y el sur. Esta exploración adicional nos permitirá comprender mejor el comportamiento de los datos y determinar si los errores de ubicación son sistemáticos o están limitados a una región específica de la ciudad.
# Filtrar los apartamentos en la Zona Centro de Cali
viviendaAPA2 <- filter(vivienda, zona == "Zona Centro" & tipo == "Apartamento")
# Mostrar los primeros tres apartamentos en la Zona Centro en una tabla
knitr::kable(head(viviendaAPA2, 3), caption = "Primeros tres apartamentos en la Zona Centro de Cali")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4654 | Zona Centro | 03 | 3 | 100 | 70.00 | NA | 2 | 3 | Apartamento | alameda | -76.53200 | 3.45200 |
| 4408 | Zona Centro | 05 | 3 | 120 | 84.00 | 1 | 2 | 3 | Apartamento | alameda | -76.53123 | 3.44011 |
| 4395 | Zona Centro | 04 | 3 | 125 | 66.76 | NA | 2 | 3 | Apartamento | bretaña | -76.53111 | 3.44034 |
# Filtrar los datos de apartamentos en la Zona Centro de Cali
vivienda_centro_apa <- filter(vivienda, tipo == "Apartamento" & zona == "Zona Centro")
# Crear el mapa de los apartamentos en la Zona Centro de Cali
mapa_centro_apa <- leaflet(vivienda_centro_apa) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#F5E322", radius = 2)
# Mostrar el mapa
mapa_centro_apa
# Filtrar los apartamentos en la Zona Sur de Cali
viviendaAPA3 <- filter(vivienda, zona == "Zona Sur" & tipo == "Apartamento")
# Mostrar los primeros tres apartamentos en la Zona Sur en una tabla
knitr::kable(head(viviendaAPA3, 3), caption = "Primeros tres apartamentos en la Zona Sur de Cali")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5098 | Zona Sur | 05 | 4 | 290 | 96 | 1 | 2 | 3 | Apartamento | acopi | -76.53464 | 3.44987 |
| 698 | Zona Sur | 02 | 3 | 78 | 40 | 1 | 1 | 2 | Apartamento | aguablanca | -76.50100 | 3.40000 |
| 8199 | Zona Sur | NA | 6 | 875 | 194 | 2 | 5 | 3 | Apartamento | aguacatal | -76.55700 | 3.45900 |
# Filtrar los datos de apartamentos en la Zona Sur de Cali
vivienda_sur_apa <- filter(vivienda, tipo == "Apartamento" & zona == "Zona Sur")
# Crear el mapa de los apartamentos en la Zona Sur de Cali
mapa_sur_apa <- leaflet(vivienda_sur_apa) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "#62162f", radius = 2)
# Mostrar el mapa
mapa_sur_apa
Al igual que con las casas, al analizar los apartamentos, se observa que algunos puntos se encuentran ubicados fuera de las zonas específicas de la ciudad. Esto sugiere que los datos pueden contener errores en la geolocalización, lo que resulta en la presencia de puntos fuera de las áreas establecidas. Si se grafican los puntos en diferentes sectores de Cali, es probable que se encuentren puntos que no corresponden a las zonas definidas.
vivienda_apartamentos <- filter(vivienda, tipo == "Apartamento")
knitr::kable(head(vivienda_casas, 5), caption = "Apartamentos")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1147 | Zona Oriente | NA | 3 | 250 | 70 | 1 | 3 | 6 | Casa | 20 de julio | -76.51168 | 3.43382 |
| 1169 | Zona Oriente | NA | 3 | 320 | 120 | 1 | 2 | 3 | Casa | 20 de julio | -76.51237 | 3.43369 |
| 1350 | Zona Oriente | NA | 3 | 350 | 220 | 2 | 2 | 4 | Casa | 20 de julio | -76.51537 | 3.43566 |
| 5992 | Zona Sur | 02 | 4 | 400 | 280 | 3 | 5 | 3 | Casa | 3 de julio | -76.54000 | 3.43500 |
| 1209 | Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
colores <- colorFactor(palette = c("#7b9400","#228CF5", "#F5E322", "#62162f", "#008000"), domain = vivienda_apartamentos$zona)
mapaAPA<- leaflet(vivienda_apartamentos) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(zona), radius = 3)
mapaAPA
El gráfico anterior presenta una visualización de todos los apartamentos en nuestra base de datos, donde cada punto está coloreado según su ubicación en diferentes zonas de la ciudad. Al observar esta representación, se evidencian inconsistencias en los datos, las cuales podrían originarse por dos posibles razones: errores humanos durante la creación de la base de datos o falta de actualización de la información. Estas discrepancias pueden conducir a valores incorrectos de longitud y latitud, lo que a su vez afecta la precisión de la ubicación de los apartamentos en el mapa.
Después de obtener los principales estadísticos del dataset de apartamentos, hemos identificado medidas clave como la media, la moda y los valores mínimos, máximos y cuartiles de cada variable. Este análisis nos proporciona una comprensión general de la distribución de los datos y nos ayuda a identificar posibles anomalías o patrones.
summary(vivienda_apartamentos)
## id zona piso estrato
## Min. : 3 Length:5100 Length:5100 Min. :3.000
## 1st Qu.:2180 Class :character Class :character 1st Qu.:4.000
## Median :4158 Mode :character Mode :character Median :5.000
## Mean :4284 Mean :4.727
## 3rd Qu.:6556 3rd Qu.:6.000
## Max. :8317 Max. :6.000
##
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 35.0 Min. : 1.000 Min. :0.000
## 1st Qu.: 175.0 1st Qu.: 68.0 1st Qu.: 1.000 1st Qu.:2.000
## Median : 279.0 Median : 90.0 Median : 1.000 Median :2.000
## Mean : 366.9 Mean :112.8 Mean : 1.568 Mean :2.617
## 3rd Qu.: 430.0 3rd Qu.:130.0 3rd Qu.: 2.000 3rd Qu.:3.000
## Max. :1950.0 Max. :932.0 Max. :10.000 Max. :8.000
## NA's :869
## habitaciones tipo barrio longitud
## Min. :0.000 Length:5100 Length:5100 Min. :-76.59
## 1st Qu.:3.000 Class :character Class :character 1st Qu.:-76.54
## Median :3.000 Mode :character Mode :character Median :-76.53
## Mean :2.971 Mean :-76.53
## 3rd Qu.:3.000 3rd Qu.:-76.52
## Max. :9.000 Max. :-76.46
##
## latitud
## Min. :3.334
## 1st Qu.:3.380
## Median :3.419
## Mean :3.419
## 3rd Qu.:3.453
## Max. :3.498
##
Es importante destacar que, al igual que con el subconjunto de casas, las variables ‘baños’ y ‘habitaciones’ presentan una situación particular, ya que se observa que el valor mínimo es cero. Este resultado parece inusual, ya que se espera que al menos los apartamentos tengan al menos un baño y una habitación. Para investigar esta situación, es crucial determinar si estos valores se deben a la presencia de datos faltantes.
md.pattern(vivienda_apartamentos)
## id zona estrato preciom areaconst banios habitaciones tipo barrio longitud
## 3182 1 1 1 1 1 1 1 1 1 1
## 1049 1 1 1 1 1 1 1 1 1 1
## 537 1 1 1 1 1 1 1 1 1 1
## 332 1 1 1 1 1 1 1 1 1 1
## 0 0 0 0 0 0 0 0 0 0
## latitud parqueaderos piso
## 3182 1 1 1 0
## 1049 1 1 0 1
## 537 1 0 1 1
## 332 1 0 0 2
## 0 869 1381 2250
La grafica indica que existen algunos datos faltantes, ahora se procede a ver en qué variables se encuentran dichos datos.
missing_values_apa <-sapply(vivienda_apartamentos, function(x) sum(is.na(x)))
knitr::kable(missing_values_apa, caption = "Datos ausentes")
| x | |
|---|---|
| id | 0 |
| zona | 0 |
| piso | 1381 |
| estrato | 0 |
| preciom | 0 |
| areaconst | 0 |
| parqueaderos | 869 |
| banios | 0 |
| habitaciones | 0 |
| tipo | 0 |
| barrio | 0 |
| longitud | 0 |
| latitud | 0 |
Al examinar los datos, hemos identificado la presencia de valores cero en las variables ‘habitaciones’ y ‘baños’ en el dataset de apartamentos. Estos valores cero son inconsistentes, ya que se espera que cada apartamento tenga al menos una habitación y un baño.
datos_cero_habitaciones_apa <- vivienda_apartamentos %>%
filter(habitaciones == 0)
print(datos_cero_habitaciones_apa)
## # A tibble: 21 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 6839 Zona … <NA> 6 900 250 2 0 0
## 2 1523 Zona … 02 5 195 35 NA 1 0
## 3 3062 Zona … 06 4 285 90 NA 4 0
## 4 1524 Zona … 10 5 330 91 NA 3 0
## 5 5392 Zona … 12 4 650 270 NA 4 0
## 6 3458 Zona … 07 5 415 118 2 5 0
## 7 6173 Zona … 09 5 380 120 2 0 0
## 8 2532 Zona … 01 4 275 96 2 2 0
## 9 3997 Zona … 12 4 240 73 1 2 0
## 10 1594 Zona … 03 4 152 60 1 2 0
## # ℹ 11 more rows
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
datos_cero_banios_apa <- vivienda_apartamentos %>%
filter(banios == 0)
print(datos_cero_banios_apa)
## # A tibble: 14 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 6839 Zona … <NA> 6 900 250 2 0 0
## 2 1898 Zona … <NA> 4 220 68 NA 0 3
## 3 6173 Zona … 09 5 380 120 2 0 0
## 4 3553 Zona … 05 5 320 92 NA 0 3
## 5 5908 Zona … <NA> 5 950 280 10 0 0
## 6 7011 Zona … <NA> 4 160 76 NA 0 0
## 7 7132 Zona … 02 5 310 80 1 0 1
## 8 7884 Zona … 03 5 380 108 NA 0 0
## 9 7522 Zona … <NA> 3 148 87 NA 0 0
## 10 6513 Zona … 07 5 640 167 2 0 3
## 11 4526 Zona … 02 6 1000 520 NA 0 5
## 12 4915 Zona … <NA> 4 160 84 1 0 0
## 13 1356 Zona … 02 3 320 310 NA 0 0
## 14 8007 Zona … <NA> 6 410 129 NA 0 0
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Tras revisar los datos, hemos identificado la presencia de valores cero en las variables ‘habitaciones’ y ‘baños’ del dataset de apartamentos. Estos valores no son coherentes, dado que es esperable que cualquier apartamento tenga al menos una habitación y un baño.
Por lo tanto, hemos decidido eliminar estos datos, ya que podrían distorsionar nuestros análisis y generar resultados poco confiables. Al asegurarnos de que nuestros datos estén limpios y sean consistentes, podemos realizar un análisis más preciso y confiable, lo que nos permitirá obtener conclusiones más sólidas sobre las características y el valor de los apartamentos en nuestra base de datos.
vivienda_apartamentos_limpia <- vivienda_apartamentos %>%
filter(habitaciones != 0 & banios != 0)
knitr::kable(head(vivienda_apartamentos_limpia), caption = "Base de datos de Apartamentos limpia")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1212 | Zona Norte | 01 | 5 | 260 | 90 | 1 | 2 | 3 | Apartamento | acopi | -76.51350 | 3.45891 |
| 1724 | Zona Norte | 01 | 5 | 240 | 87 | 1 | 3 | 3 | Apartamento | acopi | -76.51700 | 3.36971 |
| 2326 | Zona Norte | 01 | 4 | 220 | 52 | 2 | 2 | 3 | Apartamento | acopi | -76.51974 | 3.42627 |
| 4386 | Zona Norte | 01 | 5 | 310 | 137 | 2 | 3 | 4 | Apartamento | acopi | -76.53105 | 3.38296 |
| 7497 | Zona Norte | 02 | 6 | 520 | 98 | 2 | 2 | 2 | Apartamento | acopi | -76.54999 | 3.43505 |
| 5424 | Zona Norte | 03 | 4 | 320 | 108 | 2 | 3 | 3 | Apartamento | acopi | -76.53638 | 3.40770 |
Una vez que hemos realizado la limpieza de la base de datos de apartamentos, eliminando las entradas con valores cero en las variables ‘habitaciones’ y ‘baños’, procedemos a realizar una exploración inicial de los datos. En esta etapa, nos enfocaremos en evaluar la normalidad de las variables y examinar su correlación
options(repos = c(CRAN = "https://cran.rstudio.com"))
plot_ly(vivienda_apartamentos_limpia, x = ~preciom, type = "histogram")%>%
layout(title = "Histograma de precios - apartamentos")
Al observar el histograma de los precios de los apartamentos, notamos que los datos tienden a agruparse hacia la izquierda, especialmente en el rango de 60 a 420 millones de pesos. Es importante destacar que la mayoría de los precios de los apartamentos se concentran alrededor de la media, que es de 279 millones de pesos.
plot_ly(vivienda_apartamentos_limpia, x = ~areaconst, type = "histogram")%>%
layout(title = "Histograma de área construida - apartamentos")
Al examinar el histograma del área construida de los apartamentos, observamos una distribución de los datos que se concentra predominantemente en el lado izquierdo del gráfico. Esto sugiere que la mayoría de los apartamentos en nuestra base de datos tienen áreas construidas más pequeñas.
Es importante destacar que la mayoría de los datos se concentran por debajo de la media del área de construcción, que es de 90 metros cuadrados. Esto indica que la mayoría de los apartamentos tienen áreas construidas relativamente modestas en comparación con la media.
plot_ly(vivienda_apartamentos_limpia, x = ~estrato,y=~estrato, type = "bar")%>%
layout(title = "Histograma del estrato - apartamentos")
En el histograma del estrato de los apartamentos, podemos observar que la mayoría de los apartamentos en la ciudad de Cali se concentran en los estratos 5 y 6. En menor medida, encontramos apartamentos en el estrato 4, mientras que el estrato 3 cuenta con la menor cantidad de apartamentos.
Este patrón de distribución del estrato de los apartamentos nos proporciona información valiosa sobre la distribución socioeconómica de las viviendas en nuestra área de estudio. Los estratos más altos (5 y 6) tienden a estar asociados con áreas de mayor poder adquisitivo, mientras que los estratos más bajos (3 y 4) pueden representar áreas con menor poder adquisitivo.
plot_ly(vivienda_apartamentos_limpia, x = ~banios, type = "histogram")%>%
layout(title = "Histograma del número de baños - apartamentos")
En el histograma del número de baños de los apartamentos, podemos observar una distribución que se asemeja más a una distribución normal, donde la mayoría de los datos se concentran en el valor medio del número de baños, que es igual a 2.
Esta distribución centrada alrededor del valor medio sugiere que la mayoría de los apartamentos en nuestra base de datos tienen un número de baños relativamente común, lo que puede reflejar las expectativas y necesidades típicas de los compradores o inquilinos de apartamentos en nuestra área de estudio.
plot_ly(vivienda_apartamentos_limpia, x = ~habitaciones, type = "histogram")%>%
layout(title = "Histograma del número de habitaciones - apartamentos")
En el histograma del número de habitaciones de los apartamentos, podemos observar una distribución que se asemeja a una distribución normal, donde la mayoría de los datos se concentran alrededor de la media, que es igual a 3.
Esta distribución centrada en la media sugiere que la mayoría de los apartamentos en nuestra base de datos tienen un número común de habitaciones, lo que puede reflejar las preferencias y necesidades típicas de los compradores o inquilinos de apartamentos en nuestra área de estudio.
plot_ly(vivienda_apartamentos_limpia, x = ~zona, type = "histogram")%>%
layout(title = "Histograma de la zona - apartamentos")
En el histograma de las zonas de los apartamentos, podemos observar que la mayor parte de ellos se encuentran en la zona sur, seguidos de la zona norte.
Este patrón de distribución de los apartamentos por zona nos ofrece una perspectiva interesante sobre la distribución geográfica de las viviendas en nuestra área de estudio. La predominancia de apartamentos en la zona sur podría reflejar diversos factores, como la disponibilidad de terrenos, la densidad de población o las preferencias de los residentes.
Una vez completado el análisis de la normalidad de los datos, continuaremos con la identificación de las correlaciones entre las variables en nuestro conjunto de datos de apartamentos, lo que nos permitirá comprender mejor las relaciones entre ellas y su impacto en el mercado inmobiliario.”
cor_1_apa <-vivienda_apartamentos_limpia[,c("preciom","areaconst","banios","habitaciones")]
ggpairs(cor_1_apa, title="Correlación apartamentos")
Tras analizar la matriz de correlación de las variables en nuestro conjunto de datos de apartamentos, hemos identificado que las variables ‘área construida’ y ‘baños’ muestran un alto nivel de correlación con el precio de los apartamentos, con coeficientes de correlación de 0.83 y 0.75 respectivamente. Por otro lado, la variable ‘habitaciones’ muestra una correlación más baja con el precio.
Es importante destacar que el alto nivel de correlación entre el precio y las variables ‘área construida’ y ‘baños’ puede generar problemas de multicolinealidad al realizar el Modelo de Regresión Lineal Múltiple (MRLM). Sin embargo, es crucial tener en cuenta que esta afirmación solo podrá ser confirmada mediante la validación de los supuestos del modelo.
datos_imputados_apa <- vivienda_apartamentos_limpia %>%
mutate(parqueaderos = ifelse(is.na(parqueaderos), mean(parqueaderos, na.rm = TRUE), parqueaderos))
# Antes de realizar el modelo de RLM, se debe convertir la variable estrato.
datos_imputados_apa$estrato <- factor(datos_imputados_apa$estrato, levels = c("3", "4", "5", "6"))
# Convertir el factor a valores numéricos
datos_imputados_apa$estrato_numerico <- as.numeric(datos_imputados_apa$estrato)
modelo_apartamentos = lm(preciom ~ areaconst + estrato_numerico + parqueaderos + habitaciones + banios, data = datos_imputados_apa)
summary(modelo_apartamentos)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato_numerico + parqueaderos +
## habitaciones + banios, data = datos_imputados_apa)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1760.48 -54.19 -1.83 47.54 1003.83
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -176.66157 10.27856 -17.19 <2e-16 ***
## areaconst 2.08407 0.04396 47.41 <2e-16 ***
## estrato_numerico 58.87480 2.49077 23.64 <2e-16 ***
## parqueaderos 88.02545 3.66490 24.02 <2e-16 ***
## habitaciones -41.69516 3.38391 -12.32 <2e-16 ***
## banios 51.40802 3.02931 16.97 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 129.8 on 5068 degrees of freedom
## Multiple R-squared: 0.799, Adjusted R-squared: 0.7988
## F-statistic: 4028 on 5 and 5068 DF, p-value: < 2.2e-16
Después de realizar el modelo de regresión lineal múltiple (RLM) con las variables introducidas, se observó que todas ellas resultan significativas, dado que el valor de probabilidad asociado a cada coeficiente es menor a 0.05, o bien, mediante la regla rápida del valor t, donde se considera cualquier valor igual o superior a 2 como significativo.
Al analizar el efecto de cada variable en el precio de los apartamentos, se encontró que los signos esperados de los coeficientes son lógicos en la mayoría de los casos. Por ejemplo, el coeficiente positivo del área construida y el estrato tiene sentido intuitivo, ya que se espera que un mayor área construida y un estrato más alto estén asociados con precios más altos. Sin embargo, el coeficiente negativo de la variable ‘habitaciones’ requiere una consideración adicional, ya que puede indicar que un número excesivo de habitaciones podría disminuir el precio del inmueble.
En cuanto al coeficiente de determinación (R cuadrado), se observó que su valor es del 79.9%, lo que indica que el modelo con las variables introducidas explica aproximadamente el 79.9% de la variabilidad en el precio de los apartamentos. Aunque este valor es alto, también se consideró el coeficiente de determinación ajustado, que es ligeramente más bajo, indicando que la inclusión de más variables en el modelo no sería necesaria.
modelo_b0_apa<- lm(preciom ~ 1, data=datos_imputados_apa)
modelo_all_apa <- lm(preciom ~ areaconst + estrato_numerico + parqueaderos + habitaciones + banios, data = datos_imputados_apa)
forward_apa <- step(modelo_b0_apa, direction='forward', scope=formula(modelo_all_apa), trace=0)
knitr::kable(forward_apa$anova)
| Step | Df | Deviance | Resid. Df | Resid. Dev | AIC |
|---|---|---|---|---|---|
| NA | NA | 5073 | 424980908 | 57519.19 | |
| + areaconst | -1 | 295692993 | 5072 | 129287916 | 51483.12 |
| + estrato_numerico | -1 | 25695926 | 5071 | 103591989 | 50360.81 |
| + parqueaderos | -1 | 12588773 | 5070 | 91003216 | 49705.40 |
| + banios | -1 | 3001296 | 5069 | 88001920 | 49537.24 |
| + habitaciones | -1 | 2559588 | 5068 | 85442332 | 49389.47 |
summary(forward_apa)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato_numerico + parqueaderos +
## banios + habitaciones, data = datos_imputados_apa)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1760.48 -54.19 -1.83 47.54 1003.83
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -176.66157 10.27856 -17.19 <2e-16 ***
## areaconst 2.08407 0.04396 47.41 <2e-16 ***
## estrato_numerico 58.87480 2.49077 23.64 <2e-16 ***
## parqueaderos 88.02545 3.66490 24.02 <2e-16 ***
## banios 51.40802 3.02931 16.97 <2e-16 ***
## habitaciones -41.69516 3.38391 -12.32 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 129.8 on 5068 degrees of freedom
## Multiple R-squared: 0.799, Adjusted R-squared: 0.7988
## F-statistic: 4028 on 5 and 5068 DF, p-value: < 2.2e-16
Al realizar el procedimiento de selección de variables stepwise, se obtuvieron resultados consistentes con el modelo anterior. Esto sugiere que las variables seleccionadas tienen un impacto significativo en la predicción del precio de los apartamentos.
El análisis stepwise nos permitió identificar las mismas variables significativas que se encontraron en el modelo de regresión lineal múltiple inicial. Esto respalda la robustez de las relaciones identificadas entre las variables predictoras y la variable de respuesta.
modelo_apartamentos_log = lm(log(preciom) ~ log(areaconst) + estrato_numerico + log(parqueaderos) + log(habitaciones) + log(banios), data = datos_imputados_apa)
modelo_apartamentos_log_2 = lm(log(preciom) ~ log(areaconst) + estrato_numerico + parqueaderos + log(habitaciones) + banios, data = datos_imputados_apa)
stargazer(modelo_apartamentos, modelo_apartamentos_log, modelo_apartamentos_log_2, type = "text")
##
## ======================================================================
## Dependent variable:
## --------------------------------------
## preciom log(preciom)
## (1) (2) (3)
## ----------------------------------------------------------------------
## areaconst 2.084***
## (0.044)
##
## log(areaconst) 0.695*** 0.670***
## (0.013) (0.013)
##
## estrato_numerico 58.875*** 0.236*** 0.245***
## (2.491) (0.005) (0.005)
##
## parqueaderos 88.025*** 0.078***
## (3.665) (0.006)
##
## habitaciones -41.695***
## (3.384)
##
## banios 51.408*** 0.093***
## (3.029) (0.005)
##
## log(parqueaderos) 0.129***
## (0.011)
##
## log(habitaciones) -0.187*** -0.181***
## (0.016) (0.016)
##
## log(banios) 0.248***
## (0.013)
##
## Constant -176.662*** 1.769*** 1.755***
## (10.279) (0.045) (0.044)
##
## ----------------------------------------------------------------------
## Observations 5,074 5,074 5,074
## R2 0.799 0.880 0.881
## Adjusted R2 0.799 0.880 0.881
## Residual Std. Error (df = 5068) 129.843 0.226 0.226
## F Statistic (df = 5; 5068) 4,027.937*** 7,462.292*** 7,515.777***
## ======================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Después de examinar los resultados de los tres modelos de regresión, se observa que tanto el modelo 2 como el modelo 3 muestran un desempeño mejorado en comparación con el primer modelo.
El modelo 2 logró aumentar el coeficiente de determinación (R cuadrado) al 88%, lo que significa que el 88% de la variabilidad en el precio de los apartamentos puede ser explicada por las variables incluidas en el modelo. Además, todas las variables explicativas independientes mostraron una significancia estadística del 99%. Por otro lado, el modelo 3 mejoró ligeramente el coeficiente de determinación ajustado al 88.1%, y todas las variables también alcanzaron una significancia del 99%.
Al considerar los signos esperados de las variables en los modelos, se encontraron resultados consistentes con los modelos anteriores. Sin embargo, al aplicar el logaritmo a las variables, se observó una mayor estabilidad en los coeficientes, especialmente en las variables como parqueaderos y la constante. Esto sugiere que el modelo con transformación logarítmica es más robusto y consistente.
Después de estimar los modelos, se llevó a cabo la validación de los supuestos del modelo, específicamente evaluando el factor de inflación de la varianza (VIF) para detectar problemas de multicolinealidad.
resultados_VIF_apa <- data.frame(
ModeloAPA1 = vif(modelo_apartamentos),
ModeloAPA2 = vif(modelo_apartamentos_log),
ModeloAPA3 = vif(modelo_apartamentos_log_2)
)
print(resultados_VIF_apa, caption = "VIF de Modelos - apartamentos")
## ModeloAPA1 ModeloAPA2 ModeloAPA3
## areaconst 2.742951 3.569482 3.861424
## estrato_numerico 1.786219 2.129846 2.022177
## parqueaderos 1.799019 1.644376 1.751925
## habitaciones 1.450540 1.406673 1.413237
## banios 3.105477 2.887572 3.209848
Los resultados del VIF para cada uno de los modelos sugieren que no hay evidencia de multicolinealidad significativa entre las variables predictoras, ya que todos los valores son inferiores a 5. Esto indica que la relación entre las variables predictoras es adecuada y no afectará la precisión de las estimaciones.
par(mfrow = c(2, 2))
plot(modelo_apartamentos, caption = "modelo 1")
plot(modelo_apartamentos_log, caption = "modelo 2")
plot(modelo_apartamentos_log_2, caption = "modelo 3")
Estos modelos con los logaritmos señalan un mejor comportamiento
permitiendo que los residuos tengan un comportamiento con mayor
aleatoridad y un mejor ajuste de acuerdo a la media para disminuir su
varianza. En este sentido, los modelos 2 y 3 presentan un comportamiento
más estable que el modelo 1. De la misma manera, se debe efectuar un
análisis y validación de los supuestos a través de pruebas de
hipótesis.
errores_ModeloAPA1 = modelo_apartamentos$residuals
errores_ModeloAPA2 = modelo_apartamentos_log$residuals
errores_ModeloAPA3 = modelo_apartamentos_log_2$residuals
errores_modelos_apa <- data.frame(
errores_ModeloAPA1 = modelo_apartamentos$residuals,
errores_ModeloAPA2 = modelo_apartamentos_log$residuals,
errores_ModeloAPA3 = modelo_apartamentos_log_2$residuals
)
knitr::kable(head(errores_modelos_apa), caption = "Errores de los modelos - apartamentos")
| errores_ModeloAPA1 | errores_ModeloAPA2 | errores_ModeloAPA3 |
|---|---|---|
| 6.714726 | -0.0107061 | -0.0096679 |
| -58.441075 | -0.1678919 | -0.1604336 |
| 16.758792 | 0.3498645 | 0.3583662 |
| -138.974945 | -0.2633933 | -0.2341554 |
| 61.446737 | 0.2219395 | 0.2300593 |
| -51.357232 | 0.1156946 | 0.1502485 |
con lo anterior, tambien es importante evaluar los supuestos de normalidad
ks.test(errores_ModeloAPA1, "pnorm", mean = mean(errores_ModeloAPA1), sd = sd(errores_ModeloAPA1))
## Warning in ks.test.default(errores_ModeloAPA1, "pnorm", mean =
## mean(errores_ModeloAPA1), : ties should not be present for the
## Kolmogorov-Smirnov test
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: errores_ModeloAPA1
## D = 0.13772, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(errores_ModeloAPA2, "pnorm", mean = mean(errores_ModeloAPA2), sd = sd(errores_ModeloAPA2))
## Warning in ks.test.default(errores_ModeloAPA2, "pnorm", mean =
## mean(errores_ModeloAPA2), : ties should not be present for the
## Kolmogorov-Smirnov test
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: errores_ModeloAPA2
## D = 0.032783, p-value = 3.668e-05
## alternative hypothesis: two-sided
ks.test(errores_ModeloAPA3, "pnorm", mean = mean(errores_ModeloAPA3), sd = sd(errores_ModeloAPA3))
## Warning in ks.test.default(errores_ModeloAPA3, "pnorm", mean =
## mean(errores_ModeloAPA3), : ties should not be present for the
## Kolmogorov-Smirnov test
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: errores_ModeloAPA3
## D = 0.031515, p-value = 8.391e-05
## alternative hypothesis: two-sided
Como se logra observar en las pruebas de hipótesis, los resultados evidencian que los modelos cumplen con el supuesto de normalidad porque el valor p es menor a 0.05 y se acepta la hipótesis nula.
dwtest(modelo_apartamentos)
##
## Durbin-Watson test
##
## data: modelo_apartamentos
## DW = 1.6584, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
dwtest(modelo_apartamentos_log)
##
## Durbin-Watson test
##
## data: modelo_apartamentos_log
## DW = 1.5788, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
dwtest(modelo_apartamentos_log_2)
##
## Durbin-Watson test
##
## data: modelo_apartamentos_log_2
## DW = 1.5779, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
Al observar los resultados obtenidos en cada uno de los modelos, se establece que los modelos no presentan problema de autocorrelación porque su valor p es menor a 0.05, lo que permite aceptar la hipotedis nula y establecer que los errores son independientes
gqtest(modelo_apartamentos)
##
## Goldfeld-Quandt test
##
## data: modelo_apartamentos
## GQ = 1.5652, df1 = 2531, df2 = 2531, p-value < 2.2e-16
## alternative hypothesis: variance increases from segment 1 to 2
gqtest(modelo_apartamentos_log)
##
## Goldfeld-Quandt test
##
## data: modelo_apartamentos_log
## GQ = 1.0276, df1 = 2531, df2 = 2531, p-value = 0.2471
## alternative hypothesis: variance increases from segment 1 to 2
gqtest(modelo_apartamentos_log_2)
##
## Goldfeld-Quandt test
##
## data: modelo_apartamentos_log_2
## GQ = 1.0114, df1 = 2531, df2 = 2531, p-value = 0.3876
## alternative hypothesis: variance increases from segment 1 to 2
Al evaluar el supuesto de la varianza constante, se observa que el modelo 1 cumple con este requisito, ya que el valor p asociado es menor que 0.05. Esto indica que podemos aceptar la hipótesis nula de que la varianza de los errores es constante en este modelo. Por otro lado, los modelos 2 y 3 no cumplen con este supuesto, ya que su valor p es mayor que 0.05, lo que nos lleva a rechazar la hipótesis nula y aceptar la hipótesis alternativa, indicando que la varianza de los errores no es constante en estos modelos.
Considerando que todos los modelos cumplen con los supuestos del MRLM, y al analizar los resultados de cada uno, se decide seleccionar el modelo No. 1 como el más adecuado para los siguientes procedimientos. Esta decisión se basa en que, aunque el modelo 1 tiene un R cuadrado ligeramente inferior en comparación con los modelos 2 y 3, cumple con todos los supuestos del modelo, lo que garantiza una mejor fiabilidad en las inferencias realizadas con este modelo.
vivienda_apartamentos_limpia$estrato <- as.numeric(as.character(vivienda_apartamentos_limpia$estrato))
requerimientos_apa <- data.frame(
estrato_numerico=c(5,6),
areaconst=c(300,300),
parqueaderos=c(3,3),
banios=c(3,3),
habitaciones=c(5,5),
preciom = c(0, 850)
)
requerimientos_apa
## estrato_numerico areaconst parqueaderos banios habitaciones preciom
## 1 5 300 3 3 5 0
## 2 6 300 3 3 5 850
predicciones_apa <- predict(modelo_apartamentos, newdata = requerimientos_apa, interval = "confidence")
print(predicciones_apa)
## fit lwr upr
## 1 952.7585 932.1671 973.3499
## 2 1011.6333 988.3326 1034.9340
Los resultados anteriores muestran que, bajo las condiciones especificadas, el precio medio de los apartamentos oscila entre 952 y 1011 millones de pesos. Este rango proporciona una estimación del precio esperado para apartamentos que cumplen con los requisitos de estrato, área construida, número de parqueaderos, baños y habitaciones definidos por la empresa.
Apartamento <- filter(vivienda_apartamentos_limpia, areaconst >= 300, parqueaderos >= 3, banios >= 3, habitaciones >= 4, zona == "Zona Sur", estrato >= 5, estrato <= 6, preciom <= 850)
min(Apartamento$preciom)
## [1] 670
max(Apartamento$preciom)
## [1] 730
cinco_aleatorios_apa <- Apartamento %>% sample_n(5, replace = TRUE)
print(cinco_aleatorios_apa)
## # A tibble: 5 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7512 Zona S… <NA> 5 670 300 3 5 6
## 2 7512 Zona S… <NA> 5 670 300 3 5 6
## 3 7512 Zona S… <NA> 5 670 300 3 5 6
## 4 7182 Zona S… <NA> 5 730 573 3 8 5
## 5 7512 Zona S… <NA> 5 670 300 3 5 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Después de aplicar los criterios de selección definidos, se obtienen cinco apartamentos que cumplen con los requisitos establecidos por la empresa. Estos requisitos incluyen un área construida mínima de 300 metros cuadrados, al menos tres parqueaderos, tres baños y cuatro habitaciones, ubicados en la Zona Sur de la ciudad y con estrato entre 5 y 6, además de un precio máximo de 850 millones de pesos.
cinco_aleatorios_apa <- Apartamento %>% sample_n(5, replace = TRUE)
mapaApartamentos <- leaflet(cinco_aleatorios_apa) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color ="#228CF5", radius = 4)
mapaApartamentos
Con base en los datos proporcionados, se han identificado cinco posibles apartamentos que cumplen con los criterios definidos por la empresa. Estos apartamentos han sido ubicados en el mapa para facilitar su visualización. Tanto en el mapa como en la tabla de datos, se confirma que estas cinco viviendas seleccionadas cumplen con los requisitos establecidos por la empresa y son adecuadas para satisfacer las necesidades de sus empleados en cuanto a la adquisición de vivienda.