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:
| Caracteristicas | Vivienda_1 | Vivienda_2 |
|---|---|---|
| Tipo | Casa | Apartamento |
| Área construida | 200 | 300 |
| Parqueaderos | 1 | 3 |
| Baños | 2 | 3 |
| Habitaciones | 4 | 5 |
| Estrato | 4 o 5 | 5 o 6 |
| Zona | Norte | Sur |
| Crédito preaprobado | 350 millones | 850 millones |
Ayude a María a responder la solicitud, mediante técnicas modelación que usted conoce. Ella requiere le envíe un informe ejecutivo donde analice los dos casos y sus recomendaciones (Informe). Como soporte del informe debe anexar las estimaciones, validaciones y comparación de modelos requeridos (Anexos) .
##
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
| Variable | Descripción |
|---|---|
| zona | ubicación de la vivienda: Zona Centro, Zona Norte,… |
| piso | piso que ocupa la vivienda: primer piso, segundo piso… |
| estrato | estrato socio-económico: 3, 4, 5, 6 |
| preciom | precio de la vivienda en millones de pesos |
| areaconst | área construida |
| parqueaderos | número de parqueaderos |
| banios | número de baños |
| habitaciones | número de habitaciones |
| tipo | tipo de vivienda: Casa, Apartamento |
| barrio | barrio de ubicación de la vivienda: 20 de Julio, alamos,… |
| longitud | coordenada geográfica |
| latitud | coordenada geográfica |
Importamos los datos
#install.packages("devtools") # solo la primera vez
devtools::install_github("dgonxalex80/paqueteMODELOS", force =TRUE)
library(paqueteMODELOS)
data("vivienda")
Se verifica la clase correspondiente a cada una de las variables que contiene el set de datos.
attach(vivienda)
str(vivienda)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8322] 1147 1169 1350 5992 1212 ...
## $ zona : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8322] NA NA NA "02" ...
## $ estrato : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
## - 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>
# Detección del número de datos NA por variable
data(vivienda)
apply(X = is.na(vivienda), MARGIN = 2, FUN = sum)
## id zona piso estrato preciom areaconst
## 3 3 2638 3 2 3
## parqueaderos banios habitaciones tipo barrio longitud
## 1605 3 3 3 3 3
## latitud
## 3
Las variables con el mayor número de valores ausentes son Piso (2638) y Parqueaderos (1605). Se realizará un análisis detallado de estas variables para aplicar las medidas adecuadas.
En primer lugar, la variable Piso no aporta información relevante a las solicitudes, ya que no se especificó un número de pisos requerido para las casas ni una ubicación específica en un piso para los apartamentos. Por lo tanto, se procede a eliminarla del conjunto de datos.
vivienda = subset(vivienda, select = -piso)
head(vivienda,5)
## # A tibble: 5 × 12
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 1147 Zona O… 3 250 70 1 3 6 Casa
## 2 1169 Zona O… 3 320 120 1 2 3 Casa
## 3 1350 Zona O… 3 350 220 2 2 4 Casa
## 4 5992 Zona S… 4 400 280 3 5 3 Casa
## 5 1212 Zona N… 5 260 90 1 2 3 Apar…
## # ℹ 3 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>
En relación con la variable “parqueaderos”, se examinó la frecuencia de sus datos para determinar la viabilidad de imputar valores a las observaciones faltantes.
summarytools::freq(vivienda$parqueaderos)
## Frequencies
## vivienda$parqueaderos
## Type: Numeric
##
## Freq % Valid % Valid Cum. % Total % Total Cum.
## ----------- ------ --------- -------------- --------- --------------
## 1 3155 46.970 46.970 37.912 37.912
## 2 2475 36.847 83.817 29.740 67.652
## 3 520 7.742 91.559 6.248 73.901
## 4 384 5.717 97.276 4.614 78.515
## 5 68 1.012 98.288 0.817 79.332
## 6 68 1.012 99.300 0.817 80.149
## 7 18 0.268 99.568 0.216 80.365
## 8 17 0.253 99.821 0.204 80.570
## 9 4 0.060 99.881 0.048 80.618
## 10 8 0.119 100.000 0.096 80.714
## <NA> 1605 19.286 100.000
## Total 8322 100.000 100.000 100.000 100.000
Con el objetivo de optimizar este conjunto de datos para la predicción de modelos, según las solicitudes planteadas, se imputará el valor 0 a las observaciones con valores faltantes en la variable “parqueaderos”.
vivienda$parqueaderos = ifelse(is.na(vivienda$parqueaderos), 0, vivienda$parqueaderos)
summarytools::freq(vivienda$parqueaderos)
## Frequencies
## vivienda$parqueaderos
## Type: Numeric
##
## Freq % Valid % Valid Cum. % Total % Total Cum.
## ----------- ------ --------- -------------- --------- --------------
## 0 1605 19.286 19.286 19.286 19.286
## 1 3155 37.912 57.198 37.912 57.198
## 2 2475 29.740 86.938 29.740 86.938
## 3 520 6.248 93.187 6.248 93.187
## 4 384 4.614 97.801 4.614 97.801
## 5 68 0.817 98.618 0.817 98.618
## 6 68 0.817 99.435 0.817 99.435
## 7 18 0.216 99.652 0.216 99.652
## 8 17 0.204 99.856 0.204 99.856
## 9 4 0.048 99.904 0.048 99.904
## 10 8 0.096 100.000 0.096 100.000
## <NA> 0 0.000 100.000
## Total 8322 100.000 100.000 100.000 100.000
Se eliminan los valores nulos restantes ya que son pocos y no limitaran la capacidad de predicción del conjunto de datos.
vivienda = na.omit(vivienda)
apply(X= is.na(vivienda), MARGIN = 2, FUN = sum)
## id zona estrato preciom areaconst parqueaderos
## 0 0 0 0 0 0
## banios habitaciones tipo barrio longitud latitud
## 0 0 0 0 0 0
dim(vivienda)
## [1] 8319 12
Se introduce una nueva variable categórica para asignar a cada registro, ya sea de casa o apartamento, la base correspondiente en función de la zona en la que se encuentre ubicado.
#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 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 1147 Zona O… 3 250 70 1 3 6 Casa
## 2 1169 Zona O… 3 320 120 1 2 3 Casa
## 3 1350 Zona O… 3 350 220 2 2 4 Casa
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
Base 1
base1 <- filter(vivienda, zona == "Zona Norte" & tipo == "Casa")
head(base1, 3)
## # A tibble: 3 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 1209 Zona N… 5 320 150 2 4 6 Casa
## 2 1592 Zona N… 5 780 380 2 3 3 Casa
## 3 4057 Zona N… 6 750 445 0 7 6 Casa
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
mapa
library(leaflet)
# Se filtra el total de viviendas por la categoría Casas
vivienda_casasNorte <- subset(vivienda, tipo == "Casa" & zona == "Zona Norte")
# Se convierte la variable Base en un tipo de carácter
vivienda_casasNorte$base <- as.character(vivienda_casasNorte$base)
# se crea el mapa con las Casas según su latitud y longitud según el color marcado en el paso anterior.
mapaNorte <- leaflet(vivienda_casasNorte) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "purple", radius = 2)
mapaNorte
Como observamos en el mapa, existen puntos que no están ubicados al norte de la ciudad de Cali. Este podría deberse a posibles errores en la introducción de datos, donde el valor de la variable “zona” se ingresó de manera incorrecta, lo que resulta en ubicaciones distintas. Verifiquemos si este problema se presenta de la misma manera en las demás viviendas en cada una de las zonas.
Si observamos el mapa de todas la zonas se obtiene lo siguiente.
library(leaflet)
vivienda_casas <- subset(vivienda, tipo == "Casa")
vivienda_casas$base <- as.character(vivienda_casas$base)
colores <- colorFactor(palette = c("purple","red","blue","brown","orange"), domain = vivienda_casas$base)
mapa <- leaflet(vivienda_casas) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(base), radius = 4)
mapa
Como se evidencia en el mapa anterior, la base de datos presenta una dificultad, ya que varias viviendas que indican su ubicación en una zona específica, geográficamente se reflejan en otra. Por ejemplo, las casas de la Zona Sur se representan con el color naranja, y en el mapa se observa que muchos registros con este color aparecen en otras zonas de la ciudad.
Ahora se analizaran los indicadores descriptivos de las variables cuantitativas.
library(summarytools)
summarytools::descr(vivienda[,4:8])
## Descriptive Statistics
## vivienda
## N: 8319
##
## areaconst banios habitaciones parqueaderos preciom
## ----------------- ----------- --------- -------------- -------------- ---------
## Mean 174.93 3.11 3.61 1.48 433.90
## Std.Dev 142.96 1.43 1.46 1.24 328.67
## Min 30.00 0.00 0.00 0.00 58.00
## Q1 80.00 2.00 3.00 1.00 220.00
## Median 123.00 3.00 3.00 1.00 330.00
## Q3 229.00 4.00 4.00 2.00 540.00
## Max 1745.00 10.00 10.00 10.00 1999.00
## MAD 84.51 1.48 1.48 1.48 207.56
## IQR 149.00 2.00 1.00 1.00 320.00
## CV 0.82 0.46 0.40 0.84 0.76
## Skewness 2.69 0.93 1.63 1.65 1.85
## SE.Skewness 0.03 0.03 0.03 0.03 0.03
## Kurtosis 12.91 1.13 3.98 5.42 3.67
## N.Valid 8319.00 8319.00 8319.00 8319.00 8319.00
## Pct.Valid 100.00 100.00 100.00 100.00 100.00
Las viviendas en el conjunto de datos tienen áreas construidas que varían ampliamente, desde un mínimo de 30 metros cuadrados hasta un máximo de 1745 metros cuadrados.
La distribución de baños, habitaciones y parqueaderos también muestra variabilidad, con algunas viviendas sin baños, habitaciones o parqueaderos, y otras con cantidades significativas.
Los precios de las viviendas presentan una gran variación, con una media de 433.90 y un rango que va desde 58 hasta 1999.
Las medidas de asimetría y curtosis indican que las distribuciones de área construida y precio no son perfectamente simétricas ni tienen colas normales, mostrando cierta asimetría positiva y colas más pesadas.
library(ggplot2)
ggplot(vivienda, aes(x = areaconst, y = preciom))+ geom_point(color = "green")
El gráfico anterior ilustra la relación entre el precio de la vivienda y el área construida, sugiriendo una correlación positiva. Sin embargo, también se observa un fenómeno notable: mientras algunas viviendas tienen un área reducida y un precio elevado, también se evidencia lo contrario, con viviendas que tienen un precio inferior a 1000 millones pero áreas superiores a 500 \(m²\).
A continuación se analiza la frecuencia de las variables Zona, Estrato Socioeconómico y Número de baños.
summarytools::freq(vivienda$zona, plain.ascii = FALSE, style = "rmarkdown")
## ### Frequencies
## #### vivienda$zona
## **Type:** Character
##
## | | Freq | % Valid | % Valid Cum. | % Total | % Total Cum. |
## |-----------------:|-----:|--------:|-------------:|--------:|-------------:|
## | **Zona Centro** | 124 | 1.49 | 1.49 | 1.49 | 1.49 |
## | **Zona Norte** | 1920 | 23.08 | 24.57 | 23.08 | 24.57 |
## | **Zona Oeste** | 1198 | 14.40 | 38.97 | 14.40 | 38.97 |
## | **Zona Oriente** | 351 | 4.22 | 43.19 | 4.22 | 43.19 |
## | **Zona Sur** | 4726 | 56.81 | 100.00 | 56.81 | 100.00 |
## | **\<NA\>** | 0 | | | 0.00 | 100.00 |
## | **Total** | 8319 | 100.00 | 100.00 | 100.00 | 100.00 |
Podemosn notar que la mayoría de las viviendas se encuentran en la Zona Sur, representando aproximadamente el 56.81% del total de registros. Por otro lado, la Zona Norte y Zona Oeste también tienen una presencia significativa con el 23.08% y 14.40%, respectivamente. La Zona Centro y Zona Oriente tienen proporciones menores, con 1.49% y 4.22%, respectivamente.
summarytools::freq(vivienda$estrato, plain.ascii = FALSE, style = "rmarkdown")
## ### Frequencies
## #### vivienda$estrato
## **Type:** Numeric
##
## | | Freq | % Valid | % Valid Cum. | % Total | % Total Cum. |
## |-----------:|-----:|--------:|-------------:|--------:|-------------:|
## | **3** | 1453 | 17.47 | 17.47 | 17.47 | 17.47 |
## | **4** | 2129 | 25.59 | 43.06 | 25.59 | 43.06 |
## | **5** | 2750 | 33.06 | 76.11 | 33.06 | 76.11 |
## | **6** | 1987 | 23.89 | 100.00 | 23.89 | 100.00 |
## | **\<NA\>** | 0 | | | 0.00 | 100.00 |
## | **Total** | 8319 | 100.00 | 100.00 | 100.00 | 100.00 |
La distribución indica que la mayoría de las viviendas se encuentran en estratos 5 y 4, representando el 33.06% y el 25.59%, respectivamente. Los estratos 3 y 6 tienen participaciones menores, con el 17.47% y el 23.89%, respectivamente.
summarytools::freq(vivienda$banios,
plain.ascii = FALSE, style = "rmarkdown")
## ### Frequencies
## #### vivienda$banios
## **Type:** Numeric
##
## | | Freq | % Valid | % Valid Cum. | % Total | % Total Cum. |
## |-----------:|-----:|--------:|-------------:|--------:|-------------:|
## | **0** | 45 | 0.54 | 0.54 | 0.54 | 0.54 |
## | **1** | 496 | 5.96 | 6.50 | 5.96 | 6.50 |
## | **2** | 2946 | 35.41 | 41.92 | 35.41 | 41.92 |
## | **3** | 1993 | 23.96 | 65.87 | 23.96 | 65.87 |
## | **4** | 1456 | 17.50 | 83.38 | 17.50 | 83.38 |
## | **5** | 890 | 10.70 | 94.07 | 10.70 | 94.07 |
## | **6** | 314 | 3.77 | 97.85 | 3.77 | 97.85 |
## | **7** | 107 | 1.29 | 99.13 | 1.29 | 99.13 |
## | **8** | 48 | 0.58 | 99.71 | 0.58 | 99.71 |
## | **9** | 15 | 0.18 | 99.89 | 0.18 | 99.89 |
## | **10** | 9 | 0.11 | 100.00 | 0.11 | 100.00 |
## | **\<NA\>** | 0 | | | 0.00 | 100.00 |
## | **Total** | 8319 | 100.00 | 100.00 | 100.00 | 100.00 |
La mayoría de las viviendas tienen entre 2 y 3 baños, representando el 35.41% y el 23.96% respectivamente. La distribución muestra una disminución en la frecuencia a medida que aumenta el número de baños, siendo viviendas con 10 baños las menos comunes.
histograma_precio <- plot_ly(vivienda_casas, x = ~preciom, type = "histogram", marker = list(color = "lightgreen")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "Precios"), yaxis = list(title = "Frecuencia"))
histograma_precio
Se evidencia es la presencia de casas con un valor inferior a 900 millones de pesos, lo cual provoca un desplazamiento del histograma hacia la izquierda.
library(plotly)
histograma_baños <- plot_ly(vivienda_casas, x = ~banios, type = "histogram", marker = list(color = "lightpink")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "baños"), yaxis = list(title = "Frecuencia"))
histograma_baños
Podemos observar que la mayoría de las casas cuentan con 2 o hasta 4 baños. No obstante, el gráfico puede inducir a confusión al presentar valores de 0 baños. Para verificar la veracidad de estos datos, aplicamos la función de filtro. Al seleccionar viviendas con 0 baños, obtenemos una tabla vacía, corroborando así que todas las casas cuentan con al menos 1 baño.
viviendasinbanos <- filter(vivienda_casas, banios == 0)
viviendasinbanos
## # A tibble: 31 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 243 Zona … 3 190 435 0 0 0 Casa
## 2 3273 Zona … 3 400 324 0 0 0 Casa
## 3 7245 Zona … 4 1200 752 0 0 0 Casa
## 4 4995 Zona … 3 420 235 0 0 0 Casa
## 5 1816 Zona … 3 750 183 2 0 0 Casa
## 6 7509 Zona … 5 1200 660 0 0 0 Casa
## 7 4393 Zona … 3 380 264 0 0 0 Casa
## 8 1425 Zona … 5 395 220 1 0 0 Casa
## 9 3703 Zona … 6 395 140 2 0 3 Casa
## 10 3347 Zona … 4 950 444 1 0 0 Casa
## # ℹ 21 more rows
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
library(plotly)
histograma_hab <- plot_ly(vivienda_casas, x = ~habitaciones, type = "histogram", marker = list(color = "lightblue")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "habitaciones"), yaxis = list(title = "Frecuencia"))
histograma_hab
Al analizar los datos, se destaca que la mayoría de las casas posee entre 2 y 4 habitaciones. No obstante, el gráfico puede inducir a confusión al presentar valores de 0 habitaciones. Para verificar la veracidad de estos datos, empleamos la función de filtro. Al seleccionar viviendas con 0 habitaciones, obtenemos una tabla con 31 registros sin habitaciones, lo que sugiere que es necesario eliminar estas casas para realizar una correlación adecuada.
viviendasinhabi <- filter(vivienda_casas, habitaciones == 0)
viviendasinhabi
## # A tibble: 45 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 243 Zona … 3 190 435 0 0 0 Casa
## 2 2013 Zona … 3 270 330 0 3 0 Casa
## 3 2014 Zona … 3 270 330 0 3 0 Casa
## 4 2741 Zona … 4 485 320 0 4 0 Casa
## 5 3273 Zona … 3 400 324 0 0 0 Casa
## 6 4095 Zona … 4 700 550 0 6 0 Casa
## 7 4118 Zona … 5 620 450 0 3 0 Casa
## 8 4329 Zona … 4 790 540 0 6 0 Casa
## 9 4512 Zona … 4 620 300 0 8 0 Casa
## 10 7245 Zona … 4 1200 752 0 0 0 Casa
## # ℹ 35 more rows
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
histograma_zona <- plot_ly(vivienda_casas, x = ~zona, type = "histogram", marker = list(color = "lightyellow")) %>%
layout(title = "Histograma de zona", xaxis = list(title = "zona"), yaxis = list(title = "Frecuencia"))
histograma_zona
Lo que se destaca es que la mayoría de las casas, están ubicadas en la zona sur de la ciudad. Sin embargo, dada la incertidumbre generada por las observaciones del punto 1, surge la duda acerca de la veracidad de esta información.
histograma_est<- plot_ly(vivienda_casas, x = ~estrato, type = "histogram", marker = list(color = "green")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "estrato"), yaxis = list(title = "Frecuencia"))
histograma_est
Se puede observar que la mayoría de las casas se encuentran en los estratos 3 y 5. No obstante, llama la atención la considerable cantidad de casas también presentes en los estratos 4 y 6.
histograma_area<- plot_ly(vivienda_casas, x = ~areaconst, type = "histogram", marker = list(color = "blue")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "area construida"), yaxis = list(title = "Frecuencia"))
histograma_area
summary(vivienda_casas)
## id zona estrato preciom
## Min. : 1 Length:3219 Min. :3.000 Min. : 77
## 1st Qu.:1856 Class :character 1st Qu.:3.000 1st Qu.: 300
## Median :4190 Mode :character Median :5.000 Median : 430
## Mean :3963 Mean :4.485 Mean : 540
## 3rd Qu.:5862 3rd Qu.:5.000 3rd Qu.: 670
## Max. :8319 Max. :6.000 Max. :1999
## areaconst parqueaderos banios habitaciones
## Min. : 30.0 Min. : 0.000 Min. : 0.000 Min. : 0.00
## 1st Qu.: 154.0 1st Qu.: 1.000 1st Qu.: 3.000 1st Qu.: 3.00
## Median : 240.0 Median : 2.000 Median : 4.000 Median : 4.00
## Mean : 273.4 Mean : 1.769 Mean : 3.894 Mean : 4.61
## 3rd Qu.: 350.0 3rd Qu.: 2.000 3rd Qu.: 5.000 3rd Qu.: 5.00
## Max. :1745.0 Max. :10.000 Max. :10.000 Max. :10.00
## tipo barrio longitud latitud
## Length:3219 Length:3219 Min. :-76.59 Min. :3.333
## Class :character Class :character 1st Qu.:-76.54 1st Qu.:3.383
## Mode :character Mode :character Median :-76.53 Median :3.413
## Mean :-76.53 Mean :3.415
## 3rd Qu.:-76.52 3rd Qu.:3.449
## Max. :-76.46 Max. :3.496
## base
## Length:3219
## Class :character
## Mode :character
##
##
##
str(vivienda_casas)
## spc_tbl_ [3,219 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:3219] 1147 1169 1350 5992 1209 ...
## $ zona : chr [1:3219] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ estrato : num [1:3219] 3 3 3 4 5 5 6 4 5 4 ...
## $ preciom : num [1:3219] 250 320 350 400 320 780 750 625 750 600 ...
## $ areaconst : num [1:3219] 70 120 220 280 150 380 445 355 237 160 ...
## $ parqueaderos: num [1:3219] 1 1 2 3 2 2 0 3 2 1 ...
## $ banios : num [1:3219] 3 2 2 5 4 3 7 5 6 4 ...
## $ habitaciones: num [1:3219] 6 3 4 3 6 3 6 5 6 5 ...
## $ tipo : chr [1:3219] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:3219] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:3219] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:3219] 3.43 3.43 3.44 3.44 3.48 ...
## $ base : chr [1:3219] "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>
## - attr(*, "na.action")= 'omit' Named int [1:3] 8320 8321 8322
## ..- attr(*, "names")= chr [1:3] "8320" "8321" "8322"
Analisis:
Zona: La mayoría de las casas se encuentran ubicadas en la Zona Sur de la ciudad.
Estrato: La distribución de las casas se concentra principalmente en los estratos 3 y 4, pero también hay una presencia considerable en los estratos 5 y 6.
Precio: Los precios de las casas varían significativamente, con un mínimo de 77 millones de pesos y un máximo de 1999 millones de pesos.
Área Construida: La superficie construida de las casas varía desde 30 hasta 1745 metros cuadrados, con una media de aproximadamente 273 metros cuadrados.
Parqueaderos, Baños y Habitaciones: En promedio, las casas tienen alrededor de 1.77 parqueaderos, 3.89 baños y 4.61 habitaciones.
library(GGally)
corr = vivienda_casas[, c("preciom", "areaconst", "estrato", "banios", "habitaciones")]
ggpairs(corr, title="GGally")
modelo_multi_vivi = lm(preciom ~ areaconst + estrato + parqueaderos + banios, data = vivienda_casas )
summary(modelo_multi_vivi)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + parqueaderos + banios,
## data = vivienda_casas)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1244.11 -114.91 -23.99 70.67 1206.55
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -409.53880 16.41653 -24.95 <2e-16 ***
## areaconst 0.78647 0.02509 31.34 <2e-16 ***
## estrato 122.22857 4.09063 29.88 <2e-16 ***
## parqueaderos 40.90423 2.79476 14.64 <2e-16 ***
## banios 29.25394 2.83243 10.33 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 204.7 on 3214 degrees of freedom
## Multiple R-squared: 0.6737, Adjusted R-squared: 0.6733
## F-statistic: 1659 on 4 and 3214 DF, p-value: < 2.2e-16
Los coeficientes estimados para las variables predictoras, que incluyen el área construida, el estrato, la cantidad de parqueaderos y los baños, revelan su impacto significativo en la predicción del precio de la vivienda. El modelo muestra una capacidad considerable para explicar la variabilidad en los precios, como se evidencia en el coeficiente de determinación \(R^2\) de 0.6737. La significancia estadística de los coeficientes, respaldada por bajos valores p en la prueba t, indica que estas variables son pertinentes y aportan de manera sustancial a la predicción.
par(mfrow = c(2, 2))
plot(modelo_multi_vivi)
Verificación de supuestos sobre el error.
summary(modelo_multi_vivi$residuals)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -1244.11 -114.92 -23.99 0.00 70.67 1206.55
t.test(modelo_multi_vivi$residuals, mu=0)
##
## One Sample t-test
##
## data: modelo_multi_vivi$residuals
## t = -3.8744e-15, df = 3218, p-value = 1
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -7.071191 7.071191
## sample estimates:
## mean of x
## -1.397288e-14
se observa que la mediana y la media son cercanas a cero, lo que respalda la idea de que no hay sesgo sistemático en las predicciones del modelo. Además, el resultado de la prueba t para la media de los residuos confirma estadísticamente que la media de los errores no es significativamente diferente de cero, con un valor p de 1.
lmtest::gqtest(modelo_multi_vivi)
##
## Goldfeld-Quandt test
##
## data: modelo_multi_vivi
## GQ = 1.2142, df1 = 1605, df2 = 1604, p-value = 5.142e-05
## alternative hypothesis: variance increases from segment 1 to 2
La prueba de Goldfeld-Quandt revela un valor p significativamente bajo (5.142e-05), quiere decir que rechaza la hipótesis nula de homocedasticidad. Por lo tanto, se puede concluir que hay indicios de heterocedasticidad en el modelo de regresión.
shapiro.test(modelo_multi_vivi$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo_multi_vivi$residuals
## W = 0.88197, p-value < 2.2e-16
La prueba de Shapiro-Wilk arroja un valor p extremadamente bajo (p-value < 2.2e-16), indicando que hay evidencia significativa en contra de la normalidad de los errores. Por lo tanto, se rechaza la hipótesis nula de que los errores se distribuyen normalmente. Este incumplimiento del supuesto de normalidad podría afectar la validez de algunas inferencias estadísticas basadas en el modelo.
lmtest::dwtest(modelo_multi_vivi)
##
## Durbin-Watson test
##
## data: modelo_multi_vivi
## DW = 1.5032, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
La prueba de Durbin-Watson (DW) arroja un valor DW de 1.5032 con un p-valor extremadamente bajo (< 2.2e-16). Este resultado indica que hay evidencia significativa en contra de la hipótesis nula de que no hay autocorrelación en los errores. En otras palabras, existe autocorrelación positiva en los residuos del modelo.
predict(modelo_multi_vivi,list(areaconst=200,parqueaderos=1,estrato=4,habitaciones=4, banios=2))
## 1
## 336.0823
Según el modelo identificado, la predicción del precio de la vivienda para la primera solicitud, con las características proporcionadas (área construida: 200, parqueaderos: 1, estrato: 4, habitaciones: 4, baños: 2), es de aproximadamente $336.08 millones.
Casa = vivienda_casas %>%
dplyr::filter(areaconst >= 200, parqueaderos >= 1, banios >= 2, habitaciones >= 4, zona == "Zona Norte", estrato >= 4, estrato <= 5, preciom <= 350)
Casa
## # A tibble: 34 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 4210 Zona … 5 350 200 3 3 4 Casa
## 2 4267 Zona … 5 335 202 1 4 5 Casa
## 3 4800 Zona … 5 340 250 2 4 4 Casa
## 4 4209 Zona … 5 350 300 3 5 6 Casa
## 5 4422 Zona … 5 350 240 2 3 6 Casa
## 6 4458 Zona … 4 315 270 2 4 4 Casa
## 7 4483 Zona … 5 342 250 1 4 6 Casa
## 8 1009 Zona … 5 250 243 1 4 5 Casa
## 9 1270 Zona … 5 350 203 2 2 5 Casa
## 10 3352 Zona … 4 335 300 3 4 4 Casa
## # ℹ 24 more rows
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
library(leaflet)
mapaCasas <- leaflet(Casa) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(base), radius = 4)
mapaCasas
Base 2
base2 <- filter(vivienda, zona == "Zona Sur" & tipo == "Apartamento")
head(base2, 3)
## # A tibble: 3 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 5098 Zona S… 4 290 96 1 2 3 Apar…
## 2 698 Zona S… 3 78 40 1 1 2 Apar…
## 3 8199 Zona S… 6 875 194 2 5 3 Apar…
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
mapa
library(leaflet)
# Se filtra el total de viviendas por la categoría Casas
vivienda_casassur<- subset(vivienda, tipo == "Apartamento" & zona == "Zona Sur")
# Se convierte la variable Base en un tipo de carácter
vivienda_casassur$base <- as.character(vivienda_casassur$base)
# se crea el mapa con las Casas según su latitud y longitud según el color marcado en el paso anterior.
mapasur <- leaflet(vivienda_casassur) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = "orange", radius = 2)
mapasur
Como observamos en el mapa, existen puntos que no están ubicados al sur de la ciudad de Cali. Este podría deberse a posibles errores en la introducción de datos, donde el valor de la variable “zona” se ingresó de manera incorrecta, lo que resulta en ubicaciones distintas. Verifiquemos si este problema se presenta de la misma manera en las demás viviendas en cada una de las zonas.
vivienda_aprt<- subset(vivienda, tipo == "Apartamento")
vivienda_aprt$base <- as.character(vivienda_aprt$base)
histograma_precio <- plot_ly(vivienda_aprt, x = ~preciom, type = "histogram", marker = list(color = "lightgreen")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "Precios"), yaxis = list(title = "Frecuencia"))
histograma_precio
Se evidencia es la presencia de viviendas con un valor inferior a 700 millones de pesos, lo cual provoca un desplazamiento del histograma hacia la izquierda.
library(plotly)
histograma_baños <- plot_ly(vivienda_aprt, x = ~banios, type = "histogram", marker = list(color = "lightpink")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "baños"), yaxis = list(title = "Frecuencia"))
histograma_baños
Podemos observar que la mayoría de los apartamentos cuentan con 2 o 3 baños. No obstante, el gráfico puede inducir a confusión al presentar valores de 0 baños. Para verificar la veracidad de estos datos, aplicamos la función de filtro. Al seleccionar viviendas con 0 baños, obtenemos una tabla vacía, corroborando así que todas las casas cuentan con al menos 1 baño.
viviendasinbanos <- filter(vivienda_aprt, banios == 0)
viviendasinbanos
## # A tibble: 14 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 6839 Zona … 6 900 250 2 0 0 Apar…
## 2 1898 Zona … 4 220 68 0 0 3 Apar…
## 3 6173 Zona … 5 380 120 2 0 0 Apar…
## 4 3553 Zona … 5 320 92 0 0 3 Apar…
## 5 5908 Zona … 5 950 280 10 0 0 Apar…
## 6 7011 Zona … 4 160 76 0 0 0 Apar…
## 7 7132 Zona … 5 310 80 1 0 1 Apar…
## 8 7884 Zona … 5 380 108 0 0 0 Apar…
## 9 7522 Zona … 3 148 87 0 0 0 Apar…
## 10 6513 Zona … 5 640 167 2 0 3 Apar…
## 11 4526 Zona … 6 1000 520 0 0 5 Apar…
## 12 4915 Zona … 4 160 84 1 0 0 Apar…
## 13 1356 Zona … 3 320 310 0 0 0 Apar…
## 14 8007 Zona … 6 410 129 0 0 0 Apar…
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
library(plotly)
histograma_hab <- plot_ly(vivienda_aprt, x = ~habitaciones, type = "histogram", marker = list(color = "lightblue")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "habitaciones"), yaxis = list(title = "Frecuencia"))
histograma_hab
Al analizar los datos, se destaca que la mayoría de las casas posee entre 3 habitaciones. No obstante, el gráfico puede inducir a confusión al presentar valores de 0 habitaciones. Para verificar la veracidad de estos datos, empleamos la función de filtro. Al seleccionar viviendas con 0 habitaciones, obtenemos una tabla con 21 registros sin habitaciones, lo que sugiere que es necesario eliminar estos apartamentos para realizar una correlación adecuada.
viviendasinhabi <- filter(vivienda_aprt, habitaciones == 0)
viviendasinhabi
## # A tibble: 21 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 6839 Zona … 6 900 250 2 0 0 Apar…
## 2 1523 Zona … 5 195 35 0 1 0 Apar…
## 3 3062 Zona … 4 285 90 0 4 0 Apar…
## 4 1524 Zona … 5 330 91 0 3 0 Apar…
## 5 5392 Zona … 4 650 270 0 4 0 Apar…
## 6 3458 Zona … 5 415 118 2 5 0 Apar…
## 7 6173 Zona … 5 380 120 2 0 0 Apar…
## 8 2532 Zona … 4 275 96 2 2 0 Apar…
## 9 3997 Zona … 4 240 73 1 2 0 Apar…
## 10 1594 Zona … 4 152 60 1 2 0 Apar…
## # ℹ 11 more rows
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
histograma_zona <- plot_ly(vivienda_aprt, x = ~zona, type = "histogram", marker = list(color = "lightyellow")) %>%
layout(title = "Histograma de zona", xaxis = list(title = "zona"), yaxis = list(title = "Frecuencia"))
histograma_zona
Lo que se destaca es que la mayoría de apartamentos, están ubicadas en la zona sur de la ciudad.
histograma_est<- plot_ly(vivienda_aprt, x = ~estrato, type = "histogram", marker = list(color = "green")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "estrato"), yaxis = list(title = "Frecuencia"))
histograma_est
Se puede observar que la mayoría de los apartamentos se encuentran en los estratos 4 y 5. No obstante, llama la atención la considerable cantidad de viviendas también presentes en estrato 3.
histograma_area<- plot_ly(vivienda_aprt, x = ~areaconst, type = "histogram", marker = list(color = "blue")) %>%
layout(title = "Histograma de precios", xaxis = list(title = "area construida"), yaxis = list(title = "Frecuencia"))
histograma_area
summary(vivienda_aprt)
## id zona estrato preciom
## Min. : 3 Length:5100 Min. :3.000 Min. : 58.0
## 1st Qu.:2180 Class :character 1st Qu.:4.000 1st Qu.: 175.0
## Median :4158 Mode :character Median :5.000 Median : 279.0
## Mean :4284 Mean :4.727 Mean : 366.9
## 3rd Qu.:6556 3rd Qu.:6.000 3rd Qu.: 430.0
## Max. :8317 Max. :6.000 Max. :1950.0
## areaconst parqueaderos banios habitaciones
## Min. : 35.0 Min. : 0.000 Min. :0.000 Min. :0.000
## 1st Qu.: 68.0 1st Qu.: 1.000 1st Qu.:2.000 1st Qu.:3.000
## Median : 90.0 Median : 1.000 Median :2.000 Median :3.000
## Mean :112.8 Mean : 1.301 Mean :2.617 Mean :2.971
## 3rd Qu.:130.0 3rd Qu.: 2.000 3rd Qu.:3.000 3rd Qu.:3.000
## Max. :932.0 Max. :10.000 Max. :8.000 Max. :9.000
## tipo barrio longitud latitud
## Length:5100 Length:5100 Min. :-76.59 Min. :3.334
## Class :character Class :character 1st Qu.:-76.54 1st Qu.:3.380
## Mode :character Mode :character Median :-76.53 Median :3.419
## Mean :-76.53 Mean :3.419
## 3rd Qu.:-76.52 3rd Qu.:3.453
## Max. :-76.46 Max. :3.498
## base
## Length:5100
## Class :character
## Mode :character
##
##
##
str(vivienda_aprt)
## spc_tbl_ [5,100 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:5100] 1212 1724 2326 4386 7497 ...
## $ zona : chr [1:5100] "Zona Norte" "Zona Norte" "Zona Norte" "Zona Norte" ...
## $ estrato : num [1:5100] 5 5 4 5 6 4 5 3 3 6 ...
## $ preciom : num [1:5100] 260 240 220 310 520 320 385 100 175 820 ...
## $ areaconst : num [1:5100] 90 87 52 137 98 108 103 49 80 377 ...
## $ parqueaderos: num [1:5100] 1 1 2 2 2 2 2 0 1 1 ...
## $ banios : num [1:5100] 2 3 2 3 2 3 2 1 2 4 ...
## $ habitaciones: num [1:5100] 3 3 3 4 2 3 3 2 3 4 ...
## $ tipo : chr [1:5100] "Apartamento" "Apartamento" "Apartamento" "Apartamento" ...
## $ barrio : chr [1:5100] "acopi" "acopi" "acopi" "acopi" ...
## $ longitud : num [1:5100] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:5100] 3.46 3.37 3.43 3.38 3.44 ...
## $ base : chr [1:5100] "NA" "NA" "NA" "NA" ...
## - 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>
## - attr(*, "na.action")= 'omit' Named int [1:3] 8320 8321 8322
## ..- attr(*, "names")= chr [1:3] "8320" "8321" "8322"
Analisis:
Zona: La mayoría de los apartamentos se encuentran ubicadas en la Zona Sur de la ciudad.
Estrato: tiene una media de alrededor de 4.7, indicando una distribución relativamente equitativa entre los estratos.
Precio: El precio medio es de aproximadamente 366.9, con un rango significativo que sugiere una variabilidad en los precios de las propiedades-
Área Construida: La superficie construida de los apartamentos varía desde 35 hasta 932 metros cuadrados, con una media de aproximadamente 90 metros cuadrados.
Parqueaderos, Baños y Habitaciones: tiene un rango de valores entre 0 y 10, con una media de aproximadamente 1.3 parqueaderos por propiedad.La mayoría de las propiedades tienen 1 o 2 parqueaderos, representando alrededor del 84% de las observaciones.
library(GGally)
corr = vivienda_aprt[, c("preciom", "areaconst", "estrato", "banios", "habitaciones")]
ggpairs(corr, title="GGally")
modelo_multi_vivi = lm(preciom ~ areaconst + estrato + parqueaderos + banios, data = vivienda_aprt )
summary(modelo_multi_vivi)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + parqueaderos + banios,
## data = vivienda_aprt)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1835.76 -54.33 -3.54 44.03 1059.22
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -318.78294 10.11363 -31.52 <2e-16 ***
## areaconst 2.14115 0.04219 50.75 <2e-16 ***
## estrato 57.57512 2.66194 21.63 <2e-16 ***
## parqueaderos 55.27265 3.00364 18.40 <2e-16 ***
## banios 38.28105 2.85610 13.40 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 136 on 5095 degrees of freedom
## Multiple R-squared: 0.7789, Adjusted R-squared: 0.7787
## F-statistic: 4487 on 4 and 5095 DF, p-value: < 2.2e-16
Los coeficientes estimados para las variables predictoras, que incluyen el área construida, el estrato, la cantidad de parqueaderos y los baños, revelan su impacto significativo en la predicción del precio de la vivienda. El modelo muestra una capacidad considerable para explicar la variabilidad en los precios, como se evidencia en el coeficiente de determinación \(R^2\) de 0.7787. La significancia estadística de los coeficientes, respaldada por bajos valores p en la prueba t, indica que estas variables son pertinentes y aportan de manera sustancial a la predicción.
par(mfrow = c(2, 2))
plot(modelo_multi_vivi)
Verificación de supuestos sobre el error.
summary(modelo_multi_vivi$residuals)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -1835.764 -54.329 -3.541 0.000 44.035 1059.222
t.test(modelo_multi_vivi$residuals, mu=0)
##
## One Sample t-test
##
## data: modelo_multi_vivi$residuals
## t = -4.2011e-16, df = 5099, p-value = 1
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -3.733197 3.733197
## sample estimates:
## mean of x
## -8.000137e-16
Dado que el valor p es 1, no hay suficiente evidencia para rechazar la hipótesis nula de que la media de los residuos es igual a cero. En otras palabras, los residuos parecen seguir una distribución que no difiere significativamente de una distribución normal con media cero.
lmtest::gqtest(modelo_multi_vivi)
##
## Goldfeld-Quandt test
##
## data: modelo_multi_vivi
## GQ = 1.5605, df1 = 2545, df2 = 2545, p-value < 2.2e-16
## alternative hypothesis: variance increases from segment 1 to 2
La prueba de Goldfeld-Quandt revela un valor p significativamente bajo (2.2e-16), quiere decir que rechaza la hipótesis nula de homocedasticidad. Por lo tanto, se puede concluir que hay indicios de heterocedasticidad en el modelo de regresión.
# Seleccionar una muestra aleatoria de tamaño 5000 de los residuos
residuos_muestra <- sample(modelo_multi_vivi$residuals, 5000)
# Realizar el test de Shapiro-Wilk en la muestra aleatoria
shapiro_test_result <- shapiro.test(residuos_muestra)
# Imprimir los resultados del test
print(shapiro_test_result)
##
## Shapiro-Wilk normality test
##
## data: residuos_muestra
## W = 0.81749, p-value < 2.2e-16
La prueba de Shapiro-Wilk arroja un valor p extremadamente bajo (p-value < 2.2e-16), indicando que hay evidencia significativa en contra de la normalidad de los errores. Por lo tanto, se rechaza la hipótesis nula de que los errores se distribuyen normalmente. Este incumplimiento del supuesto de normalidad podría afectar la validez de algunas inferencias estadísticas basadas en el modelo.
lmtest::dwtest(modelo_multi_vivi)
##
## Durbin-Watson test
##
## data: modelo_multi_vivi
## DW = 1.5818, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
La prueba de Durbin-Watson (DW) arroja un valor DW de 1.5032 con un p-valor extremadamente bajo (< 2.2e-16). Este resultado indica que hay evidencia significativa en contra de la hipótesis nula de que no hay autocorrelación en los errores. En otras palabras, existe autocorrelación positiva en los residuos del modelo.
predict(modelo_multi_vivi,list(areaconst=300,parqueaderos=3,estrato=5,habitaciones=5, banios=3))
## 1
## 892.1
Según el modelo identificado, la predicción del precio de la vivienda para la primera solicitud, con las características proporcionadas (área construida: 300, parqueaderos: 3, estrato: 5, habitaciones: 5, baños: 3), es de aproximadamente $892.1 millones.
Aprt = vivienda_aprt %>%
dplyr::filter(areaconst >= 300, parqueaderos >= 3, banios >= 3, habitaciones >= 5, zona == "Zona Sur", estrato >= 5, estrato <= 6, preciom <= 850)
Aprt
## # A tibble: 2 × 13
## id zona estrato preciom areaconst parqueaderos banios habitaciones tipo
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 7182 Zona S… 5 730 573 3 8 5 Apar…
## 2 7512 Zona S… 5 670 300 3 5 6 Apar…
## # ℹ 4 more variables: barrio <chr>, longitud <dbl>, latitud <dbl>, base <chr>
library(leaflet)
mapaaprt <- leaflet(Aprt) %>%
addTiles() %>%
addCircleMarkers(lng = ~longitud, lat = ~latitud, color = ~colores(base), radius = 4)
mapaaprt