Maria comenzó como agente de bienes raíces en Cali hace 10 años. Después de laborar dos años para una empresa nacional, se traslado a Bogotá y trabajó para otra agencia de bienes raíces. Sus amigos y familiares la convencieron de que con su experiencia y conocimientos del negocio debía abrir su propia agencia. Terminó por adquirir la licencia de intermediario y al poco tiempo fundó su propia compañía, C&A (Casas y Apartamentos) en Cali. Santiago y Lina, dos vendedores de la empresa anterior aceptaron trabajar en la nueva compaña. En la actualidad ocho agentes de bienes raíces colaboran con ella en C&A.
Actualmente las ventas de bienes raíces en Cali se han visto disminuidas de manera significativa en lo corrido del año. Durante este periodo muchas instituciones bancarias de ahorro y vivienda están prestando grandes sumas de dinero para la industria y la construcción comercial y residencial. Cuando el efecto producto de las tensiones políticas y sociales disminuya, se espera que la actividad económica de este sector se reactive.
Hace dos días, María recibió una carta solicitando asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad. Las solicitudes incluyen las siguientes condiciones:
| Características | Vivienda 1 | Vivienda 2 |
|---|---|---|
| Tipo | Casa | Apartamento |
| área construida | 200 | 300 |
| parqueaderos | 1 | 3 |
| baños | 2 | 3 |
| habitaciones | 4 | 5 |
| estrato | 4 o 5 | 5 o 6 |
| zona | Norte | Sur |
| crédito preaprobado | 350 millones | 850 millones |
Ayude a María a responder la solicitud, mediante técnicas modelación que usted conoce. Ella requiere le envíe un informe ejecutivo donde analice los dos casos y sus recomendaciones (Informe). Como soporte del informe debe anexar las estimaciones, validaciones y comparación de modelos requeridos (Anexos) .
library(paqueteMODELOS)
data("vivienda")
summary(vivienda)
## id zona piso estrato
## Min. : 1 Length:8322 Length:8322 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## NA's :3 NA's :3
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1605 NA's :3
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8322 Length:8322 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## NA's :3 NA's :3
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
## NA's :3
Se procede a crear la variable base para poder realizar el filtro de las caracteristicas de la oferta de vivienda 1
attach(vivienda)
vivienda$base <- ifelse(vivienda$zona =="Zona Norte" & vivienda$tipo =="Casa", "Base 1",
ifelse(vivienda$zona =="Zona Centro" & vivienda$tipo =="Casa", "Base 2",
ifelse(vivienda$zona =="Zona Oeste" & vivienda$tipo =="Casa", "Base 3",
ifelse(vivienda$zona =="Zona Oriente" & vivienda$tipo =="Casa", "Base 4",
ifelse(vivienda$zona == "Zona Sur" & vivienda$tipo == "Casa", "Base 5", "NA")))))
head(vivienda, 5)
## id zona piso estrato preciom areaconst parqueaderos banios
## 1 1147 Zona Oriente <NA> 3 250 70 1 3
## 2 1169 Zona Oriente <NA> 3 320 120 1 2
## 3 1350 Zona Oriente <NA> 3 350 220 2 2
## 4 5992 Zona Sur 02 4 400 280 3 5
## 5 1212 Zona Norte 01 5 260 90 1 2
## habitaciones tipo barrio longitud latitud base
## 1 6 Casa 20 de julio -76.51168 3.43382 Base 4
## 2 3 Casa 20 de julio -76.51237 3.43369 Base 4
## 3 4 Casa 20 de julio -76.51537 3.43566 Base 4
## 4 3 Casa 3 de julio -76.54000 3.43500 Base 5
## 5 3 Apartamento acopi -76.51350 3.45891 NA
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
base1 <- filter(vivienda, zona == "Zona Norte" & tipo == "Casa")
head(base1, 3)
## # A tibble: 3 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4057 Zona N… 02 6 750 445 NA 7 6
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # base <chr>
(Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).
##install.packages("leaflet")
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.3.1
Casas_zona_norte <- subset(vivienda, tipo == "Casa" & zona == "Zona Norte")
Casas_zona_norte$base <- as.character(Casas_zona_norte$base)
map_casas_norte <- leaflet(Casas_zona_norte) %>%
addTiles() %>%
addCircleMarkers(
lng = Casas_zona_norte$longitud ,
lat = Casas_zona_norte$latitud,
radius = 2,
color = "violet"
)
map_casas_norte # Muestra el mapa
library(leaflet)
Casas_zona_sur <- subset(vivienda, tipo == "Casa" & zona == "Zona Sur")
Casas_zona_sur$base <- as.character(Casas_zona_sur$base)
map_casas_sur <- leaflet(Casas_zona_sur) %>%
addTiles() %>%
addCircleMarkers(
lng = Casas_zona_sur$longitud ,
lat = Casas_zona_sur$latitud,
radius = 2,
color = "red"
)
map_casas_sur # Muestra el mapa
library(leaflet)
Casas_zona_centro <- subset(vivienda, tipo == "Casa" & zona == "Zona Centro")
Casas_zona_centro$base <- as.character(Casas_zona_centro$base)
map_casas_centro <- leaflet(Casas_zona_centro) %>%
addTiles() %>%
addCircleMarkers(
lng = Casas_zona_centro$longitud ,
lat = Casas_zona_centro$latitud,
radius = 2,
color = "brown"
)
map_casas_centro # Muestra el mapa
library(leaflet)
Casas_zona_oeste <- subset(vivienda, tipo == "Casa" & zona == "Zona Oeste")
Casas_zona_oeste$base <- as.character(Casas_zona_oeste$base)
map_casas_oeste <- leaflet(Casas_zona_oeste) %>%
addTiles() %>%
addCircleMarkers(
lng = Casas_zona_oeste$longitud ,
lat = Casas_zona_oeste$latitud,
radius = 2,
color = "#389"
)
map_casas_oeste # Muestra el mapa
library(leaflet)
Casas_zona_oriente <- subset(vivienda, tipo == "Casa" & zona == "Zona Oriente")
Casas_zona_oriente$base <- as.character(Casas_zona_oriente$base)
map_casas_oriente <- leaflet(Casas_zona_oriente) %>%
addTiles() %>%
addCircleMarkers(
lng = Casas_zona_oriente$longitud ,
lat = Casas_zona_oriente$latitud,
radius = 2,
color = "purple"
)
map_casas_oriente # Muestra el mapa
De acuerdo a los graficos obtenidos se puede evidenciar que en las zonas norte, sur y oriente presentan mayor dispersión respecto a la zona asociada en la base de datos, por lo que se podria concluir que los datos ingresados de longitud y latitud no son los correspondientes a las propiedades o que las zonas asociadas estan mal diligenciadas en la base de datos.
2. Realice un análisis exploratorio de datos
enfocado en la correlación entre la variable respuesta (precio de la
casa) en función del área construida, estrato, numero de baños, numero
de habitaciones y zona donde se ubica la vivienda. Use gráficos
interactivos con el paquete plotly e interprete los
resultados.
Se realiza el filtro correspondiente a la base necesaria con variables númericas para poder realizar el analisis de correlación entre variables
vivienda_casas <- vivienda[vivienda$tipo == 'Casa', c("zona", "estrato", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones"
)]
# Crear un mapeo numérico
Zona_n <- c("Zona Norte" = 1, "Zona Sur" = 2, "Zona Centro" = 3, "Zona Oriente" = 4, "Zona Oeste" = 5)
# Aplicar el mapeo a la columna categórica
vivienda_casas$zona <- Zona_n[vivienda_casas$zona]
# Ver el dataframe resultante
print(vivienda_casas)
## # A tibble: 3,222 × 7
## zona estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4 3 250 70 1 3 6
## 2 4 3 320 120 1 2 3
## 3 4 3 350 220 2 2 4
## 4 2 4 400 280 3 5 3
## 5 1 5 320 150 2 4 6
## 6 1 5 780 380 2 3 3
## 7 1 6 750 445 NA 7 6
## 8 1 4 625 355 3 5 5
## 9 1 5 750 237 2 6 6
## 10 1 4 600 160 1 4 5
## # ℹ 3,212 more rows
Posteriormente se procede a realizar diferentes graficos para poder visualizar las relaciones entre la variables observadas
# Cargar la librería necesaria para la visualización de correlaciones
library(corrplot)
## corrplot 0.92 loaded
pairs(vivienda_casas[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])
# Calcular la matriz de correlación
correlation_matrix <- cor(na.omit(vivienda_casas)[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])
print(correlation_matrix)
## preciom areaconst parqueaderos banios zona
## preciom 1.00000000 0.644537409 0.63914644 0.55967924 0.018559595
## areaconst 0.64453741 1.000000000 0.47055482 0.50061837 0.007838765
## parqueaderos 0.63914644 0.470554816 1.00000000 0.44725811 -0.070536196
## banios 0.55967924 0.500618368 0.44725811 1.00000000 -0.012355872
## zona 0.01855960 0.007838765 -0.07053620 -0.01235587 1.000000000
## habitaciones 0.08650974 0.297409809 0.09509244 0.45285126 0.062928637
## estrato 0.64175109 0.339767570 0.46302582 0.43300465 -0.133865875
## habitaciones estrato
## preciom 0.08650974 0.6417511
## areaconst 0.29740981 0.3397676
## parqueaderos 0.09509244 0.4630258
## banios 0.45285126 0.4330046
## zona 0.06292864 -0.1338659
## habitaciones 1.00000000 -0.1481480
## estrato -0.14814801 1.0000000
De acuerdo a los datos obtenidos y el grafico de de correlacion se puede observar que las variables que presentan mayor correlación respecto al precio de la vivienda corresponde a: el area construida, el número de parqueaderos, el estrato y el número de baños de la vivienda.
# Crear un mapa de calor de correlación
heatmap(correlation_matrix,
main = "Mapa de Calor de Correlación")
# Estimar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda_casas)
# Resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda_casas)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1190.80 -114.52 -25.94 74.59 986.16
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -413.87536 25.58852 -16.174 < 2e-16 ***
## areaconst 0.74227 0.02941 25.235 < 2e-16 ***
## estrato 116.07109 5.26618 22.041 < 2e-16 ***
## habitaciones -14.74995 3.18137 -4.636 3.73e-06 ***
## parqueaderos 64.29943 3.47719 18.492 < 2e-16 ***
## banios 39.03498 4.05083 9.636 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 205.2 on 2480 degrees of freedom
## (736 observations deleted due to missingness)
## Multiple R-squared: 0.6834, Adjusted R-squared: 0.6828
## F-statistic: 1071 on 5 and 2480 DF, p-value: < 2.2e-16
De acuerdo con los resultados obtenidos del modelo se puede concluir que todas las variables explicativas son significativas y explican en un 68,34% la variabilidad en el precio de la vivienda.
El coeficiente para el área construida es 0.74227. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el área construida se asocia con un aumento estimado de 0.74227 unidades en el precio de la vivienda.
El coeficiente para el estrato es 116.07109. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el estrato se asocia con un aumento estimado de 116.07109 unidades en el precio de la vivienda.
El coeficiente para las habitaciones es -14.74995. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de habitaciones se asocia con una disminución estimada de 14.74995 unidades en el precio de la vivienda. (parece que esta varible no es del todo logica, aunque si la calidad de la data es buena podría ser un hallazgo interesante)
El coeficiente para “parqueaderos” es 64.29943. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de parqueaderos se asocia con un aumento estimado de 64.29943 unidades en el precio de la vivienda.
El coeficiente para “baños” es 39.03498. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de baños se asocia con un aumento estimado de 39.03498 unidades en el precio de la vivienda.
El modelo podría mejorarse al tratar datos atipicos o validar los supuestos y de acuerdo a los resultados generar las tranformaciones que requieran para mejorar el R^2
##Supuesto 1 - Linealidad
El modelo asume que la relación entre las variables independientes y la variable dependiente es lineal.
# Gráfico de residuos vs. valores ajustados
plot(modelo, which = 1)
Se puede observar que los residuos se distribuyen cerca al cero, lo cual indica no tener problemas de linealidad por lo cual el modelo cumpliria con este supuesto
##Supuesto 2 - Homocedasticidad
Este supuesto implica que la varianza de los residuos debe ser constante en todos los niveles de las variables independientes.
# Gráfico de dispersión de residuos vs. valores ajustados
plot(modelo, which = 3)
De acuerdo al grafico anterior se puede observar que la dispersión de los residuos es constante a lo largo de los valores ajustados.
##Supuesto 3 - Normalidad de los Residuos
Este supuesto indica que los residuos deben seguir una distribución normal
# Gráfico Q-Q para normalidad de residuos
qqnorm(modelo$residuals)
qqline(modelo$residuals)
# Prueba de normalidad de Shapiro-Wilk
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.89699, p-value < 2.2e-16
De acuerdo con los resultados obtenidos del grafico y la prueba de shapiro se puede concluir que los residuos no siguen una distribución normal ya que se plantean las siquientes hipotesis para la lectura del test y se evidencia que los residuos no siguen completamente la linea diagonal
Ho: Normalidad en los residuos Ha: No normalidad en los residuos
Criterio de decisión es P > alpha = Acepta Ho Criterio de decisión es P > alpha = Rechaza Ho
##Supuesto 4 - No Autocorrelación
Los residuos deben ser independientes unos de otros. Esto significa que no debe haber patrones temporales ni autocorrelación en los residuos.
# Gráfico de residuos vs. tiempo
plot(modelo, which = 5)
#install.packages("lmtest")
library(lmtest)
## Warning: package 'lmtest' was built under R version 4.3.1
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
# Prueba de Durbin Watson
resultado_dw <- dwtest(modelo)
print(resultado_dw)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.5759, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
De acuerdo con los resultados obtenidos se puede concluir que los valores residuales estan correlacionados entre si, lo que que indica que el modelo no cumple con el supuesto de independencia en los residuos o tambien llamado supuesto de No autocorrelación
##Supuesto 5 - No multicolinealidad
Las variables independientes no deben estar altamente correlacionadas entre sí.
# Matriz de correlación
Corr_x <-cor(na.omit(vivienda_casas)[, c("areaconst", "estrato", "habitaciones", "parqueaderos", "banios")])
Corr_x
## areaconst estrato habitaciones parqueaderos banios
## areaconst 1.0000000 0.3397676 0.29740981 0.47055482 0.5006184
## estrato 0.3397676 1.0000000 -0.14814801 0.46302582 0.4330046
## habitaciones 0.2974098 -0.1481480 1.00000000 0.09509244 0.4528513
## parqueaderos 0.4705548 0.4630258 0.09509244 1.00000000 0.4472581
## banios 0.5006184 0.4330046 0.45285126 0.44725811 1.0000000
heatmap(Corr_x,
main = "Mapa de Calor de Correlación")
#install.packages("car")
library(car)
## Warning: package 'car' was built under R version 4.3.1
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.3.1
##
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
vif_values <- vif(modelo)
vif_values
## areaconst estrato habitaciones parqueaderos banios
## 1.541765 1.694080 1.594265 1.535105 2.059733
De acuerdo con la prueba de VIF (Factor de Inflación de la Varianza) se puede concluir que no existe problemas de multicolinealidad en el modelo ya que todos los valores son < a 5
# Crear un nuevo marco de datos con los valores de la nueva solicitud
solicitud_1 <- data.frame(areaconst = 200,
parqueaderos = 1,
estrato = 4,
habitaciones = 4,
estrato = c(4,5),
banios = 2,
zona = 1)
predicciones <- predict(modelo, newdata = solicitud_1)
solicitud_1$prediccion_precio <- predicciones
# Mostrar el marco de datos con las características y las predicciones
print(solicitud_1)
## areaconst parqueaderos estrato habitaciones estrato.1 banios zona
## 1 200 1 4 4 4 2 1
## 2 200 1 4 4 5 2 1
## prediccion_precio
## 1 282.2318
## 2 282.2318
La prediccion del modelo indica que el valor aproximado de la vivienda de la solicitud 1 es de 282.2 millones de pesos
pos <- which(vivienda$areaconst>= 200 & vivienda$parqueaderos>=1 & vivienda$banios>=2 & vivienda$habitaciones>=4 & vivienda$estrato>=4 & vivienda$estrato<=5 & vivienda$preciom<=350 & vivienda$zona == "Zona Norte" & vivienda$tipo =="Casa")
Ofertas_casas <- vivienda[pos,]
Ofertas_casas_5 = Ofertas_casas[order(Ofertas_casas$areaconst, decreasing = TRUE), ]
ofertac5 <- head(Ofertas_casas_5, 5)
knitr::kable(head(Ofertas_casas_5, 5), caption = "5 Ofertas que cumple las caracterisiticas de la solicitud")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3101 | Zona Norte | 02 | 5 | 340 | 355 | 2 | 5 | 8 | Casa | san vicente | -76.52377 | 3.46384 | Base 1 |
| 5031 | Zona Norte | 03 | 4 | 350 | 350 | 1 | 4 | 5 | Casa | salomia | -76.53464 | 3.44987 | Base 1 |
| 1943 | Zona Norte | NA | 5 | 350 | 346 | 1 | 2 | 4 | Casa | vipasa | -76.51847 | 3.47503 | Base 1 |
| 4209 | Zona Norte | 02 | 5 | 350 | 300 | 3 | 5 | 6 | Casa | el bosque | -76.53010 | 3.48577 | Base 1 |
| 3352 | Zona Norte | NA | 4 | 335 | 300 | 3 | 4 | 4 | Casa | el bosque | -76.52600 | 3.43400 | Base 1 |
library(leaflet)
map_casas_oferta <- leaflet(ofertac5) %>%
addTiles() %>%
addCircleMarkers(
lng = ofertac5$longitud ,
lat = ofertac5$latitud,
radius = 2,
color = "purple"
)
map_casas_oferta # Muestra el mapa
7.1. Realice un filtro a la base de datos e incluya solo las ofertas de : base2: Apartamentos, de la zona sur de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta.
library(dplyr)
base2 <- filter(vivienda, zona == "Zona Sur" & tipo == "Apartamento")
head(base2, 3)
## # A tibble: 3 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 5098 Zona S… 05 4 290 96 1 2 3
## 2 698 Zona S… 02 3 78 40 1 1 2
## 3 8199 Zona S… <NA> 6 875 194 2 5 3
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # base <chr>
(Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).
##install.packages("leaflet")
library(leaflet)
Apartamentos_zona_sur <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Sur")
map_Apartamentos_zona_sur <- leaflet(Apartamentos_zona_sur) %>%
addTiles() %>%
addCircleMarkers(
lng = Apartamentos_zona_sur$longitud ,
lat = Apartamentos_zona_sur$latitud,
radius = 2,
color = "violet"
)
map_Apartamentos_zona_sur # Muestra el mapa
library(leaflet)
Apartamentos_zona_norte <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Norte")
map_Apartamentos_zona_norte <- leaflet(Apartamentos_zona_norte) %>%
addTiles() %>%
addCircleMarkers(
lng = Apartamentos_zona_norte$longitud ,
lat = Apartamentos_zona_norte$latitud,
radius = 2,
color = "red"
)
map_Apartamentos_zona_norte # Muestra el mapa
library(leaflet)
Apartamentos_zona_centro <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Centro")
map_Apartamentos_zona_centro <- leaflet(Apartamentos_zona_centro) %>%
addTiles() %>%
addCircleMarkers(
lng = Apartamentos_zona_centro$longitud ,
lat = Apartamentos_zona_centro$latitud,
radius = 2,
color = "brown"
)
map_Apartamentos_zona_centro # Muestra el mapa
library(leaflet)
Apartamentos_zona_oeste <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Oeste")
map_Apartamentos_zona_oeste <- leaflet(Apartamentos_zona_oeste) %>%
addTiles() %>%
addCircleMarkers(
lng = Apartamentos_zona_oeste$longitud ,
lat = Apartamentos_zona_oeste$latitud,
radius = 2,
color = "#389"
)
map_Apartamentos_zona_oeste # Muestra el mapa
library(leaflet)
Apartamentos_zona_oriente <- subset(vivienda, tipo == "Apartamento" & zona == "Zona Oriente")
map_Apartamentos_zona_oriente <- leaflet(Apartamentos_zona_oriente) %>%
addTiles() %>%
addCircleMarkers(
lng = Apartamentos_zona_oriente$longitud ,
lat = Apartamentos_zona_oriente$latitud,
radius = 2,
color = "purple"
)
map_Apartamentos_zona_oriente # Muestra el mapa
De acuerdo con los graficos obtenidos se evidencia tambien que para el tipo de vivienda apartamentos existe bastante dispersión en la localización de las viviendas respecto a la zona asociada en la base de datos.
2. Realice un análisis exploratorio de datos
enfocado en la correlación entre la variable respuesta (precio del
apartamento) en función del área construida, estrato, numero de baños,
numero de habitaciones y zona donde se ubica la vivienda. Use gráficos
interactivos con el paquete plotly e interprete los
resultados.
Se realiza el filtro correspondiente a la base necesaria con variables númericas para poder realizar el analisis de correlación entre variables
vivienda_apartamentos <- vivienda[vivienda$tipo == 'Apartamento', c("zona", "estrato", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones"
)]
# Crear un mapeo numérico
Zona_n <- c("Zona Norte" = 1, "Zona Sur" = 2, "Zona Centro" = 3, "Zona Oriente" = 4, "Zona Oeste" = 5)
# Aplicar el mapeo a la columna categórica
vivienda_apartamentos$zona <- Zona_n[vivienda_apartamentos$zona]
# Ver el dataframe resultante
print(vivienda_apartamentos)
## # A tibble: 5,103 × 7
## zona estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 5 260 90 1 2 3
## 2 1 5 240 87 1 3 3
## 3 1 4 220 52 2 2 3
## 4 1 5 310 137 2 3 4
## 5 1 6 520 98 2 2 2
## 6 1 4 320 108 2 3 3
## 7 1 5 385 103 2 2 3
## 8 1 3 100 49 NA 1 2
## 9 1 3 175 80 1 2 3
## 10 1 6 820 377 1 4 4
## # ℹ 5,093 more rows
Posteriormente se procede a realizar diferentes graficos para poder visualizar las relaciones entre la variables observadas
# Cargar la librería necesaria para la visualización de correlaciones
library(corrplot)
pairs(vivienda_apartamentos[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])
# Calcular la matriz de correlación
correlation_matrix_a <- cor(na.omit(vivienda_apartamentos)[, c("preciom", "areaconst", "parqueaderos", "banios", "zona", "habitaciones", "estrato")])
print(correlation_matrix_a)
## preciom areaconst parqueaderos banios zona habitaciones
## preciom 1.0000000 0.8231511 0.7385659 0.7297750 0.50157066 0.28286691
## areaconst 0.8231511 1.0000000 0.6779314 0.7246837 0.41476646 0.39818320
## parqueaderos 0.7385659 0.6779314 1.0000000 0.6211913 0.39601873 0.26717503
## banios 0.7297750 0.7246837 0.6211913 1.0000000 0.35628160 0.51573577
## zona 0.5015707 0.4147665 0.3960187 0.3562816 1.00000000 0.08573757
## habitaciones 0.2828669 0.3981832 0.2671750 0.5157358 0.08573757 1.00000000
## estrato 0.6383956 0.5210063 0.5437474 0.5695362 0.44201409 0.15939452
## estrato
## preciom 0.6383956
## areaconst 0.5210063
## parqueaderos 0.5437474
## banios 0.5695362
## zona 0.4420141
## habitaciones 0.1593945
## estrato 1.0000000
De acuerdo a los datos obtenidos y el grafico de de correlacion se puede observar que las variables que presentan mayor correlación respecto al precio de la vivienda corresponde a: el area construida, el número de parqueaderos, el número de baños y el estrato de la vivienda.
# Crear un mapa de calor de correlación
heatmap(correlation_matrix_a,
main = "Mapa de Calor de Correlación")
# Estimar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda_apartamentos)
# Resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda_apartamentos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1699.03 -57.72 -0.67 48.59 1005.44
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -278.47706 15.86822 -17.55 <2e-16 ***
## areaconst 2.00464 0.04839 41.42 <2e-16 ***
## estrato 56.24218 3.05907 18.39 <2e-16 ***
## habitaciones -42.66447 3.80700 -11.21 <2e-16 ***
## parqueaderos 90.42324 4.14278 21.83 <2e-16 ***
## banios 54.84690 3.41824 16.05 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 137.7 on 4225 degrees of freedom
## (872 observations deleted due to missingness)
## Multiple R-squared: 0.7845, Adjusted R-squared: 0.7843
## F-statistic: 3077 on 5 and 4225 DF, p-value: < 2.2e-16
De acuerdo con los resultados obtenidos del modelo se puede concluir que todas las variables explicativas son significativas y explican en un 68,34% la variabilidad en el precio de la vivienda.
El coeficiente para el área construida es 2.00464. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el área construida se asocia con un aumento estimado de 2.00464 unidades en el precio de la vivienda.
El coeficiente para el estrato es 56.24218. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el estrato se asocia con un aumento estimado de 56.24218 unidades en el precio de la vivienda.
El coeficiente para las habitaciones es -42.66447. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de habitaciones se asocia con una disminución estimada de 42.66447 unidades en el precio de la vivienda. (parece que esta varible no es del todo logica, aunque si la calidad de la data es buena podría ser un hallazgo interesante)
El coeficiente para “parqueaderos” es 90.42324. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de parqueaderos se asocia con un aumento estimado de 90.42324 unidades en el precio de la vivienda.
El coeficiente para “baños” es 54.84690. Esto significa que, manteniendo todas las demás variables constantes, un aumento de una unidad en el número de baños se asocia con un aumento estimado de 54.84690 unidades en el precio de la vivienda.
El modelo podría mejorarse al tratar datos atipicos o validar los supuestos y de acuerdo a los resultados generar las tranformaciones que requieran para mejorar el R^2
##Supuesto 1 - Linealidad
El modelo asume que la relación entre las variables independientes y la variable dependiente es lineal.
# Gráfico de residuos vs. valores ajustados
plot(modelo, which = 1)
Se puede observar que los residuos se distribuyen cerca al cero, lo cual indica no tener problemas de linealidad por lo cual el modelo cumpliria con este supuesto
##Supuesto 2 - Homocedasticidad
Este supuesto implica que la varianza de los residuos debe ser constante en todos los niveles de las variables independientes.
# Gráfico de dispersión de residuos vs. valores ajustados
plot(modelo, which = 3)
De acuerdo al grafico anterior se puede observar que la dispersión de los residuos es parece seguir una tendencia en diagonal, lo que puede sugerir tener problemas de heterocedasticidad.
##Supuesto 3 - Normalidad de los Residuos
Este supuesto indica que los residuos deben seguir una distribución normal
# Gráfico Q-Q para normalidad de residuos
qqnorm(modelo$residuals)
qqline(modelo$residuals)
# Prueba de normalidad de Shapiro-Wilk
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.83758, p-value < 2.2e-16
De acuerdo con los resultados obtenidos del grafico y la prueba de shapiro se puede concluir que los residuos no siguen una distribución normal ya que se plantean las siquientes hipotesis para la lectura del test y se evidencia que los residuos no siguen completamente la linea diagonal
Ho: Normalidad en los residuos Ha: No normalidad en los residuos
Criterio de decisión es P > alpha = Acepta Ho Criterio de decisión es P > alpha = Rechaza Ho
##Supuesto 4 - No Autocorrelación
Los residuos deben ser independientes unos de otros. Esto significa que no debe haber patrones temporales ni autocorrelación en los residuos.
# Gráfico de residuos vs. tiempo
plot(modelo, which = 5)
#install.packages("lmtest")
library(lmtest)
# Prueba de Durbin Watson
resultado_dw <- dwtest(modelo)
print(resultado_dw)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.6551, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
De acuerdo con los resultados obtenidos se puede concluir que los valores residuales estan correlacionados entre si, lo que que indica que el modelo no cumple con el supuesto de independencia en los residuos o tambien llamado supuesto de No autocorrelación
##Supuesto 5 - No multicolinealidad
Las variables independientes no deben estar altamente correlacionadas entre sí.
# Matriz de correlación
Corr_x <-cor(na.omit(vivienda_apartamentos)[, c("areaconst", "estrato", "habitaciones", "parqueaderos", "banios")])
Corr_x
## areaconst estrato habitaciones parqueaderos banios
## areaconst 1.0000000 0.5210063 0.3981832 0.6779314 0.7246837
## estrato 0.5210063 1.0000000 0.1593945 0.5437474 0.5695362
## habitaciones 0.3981832 0.1593945 1.0000000 0.2671750 0.5157358
## parqueaderos 0.6779314 0.5437474 0.2671750 1.0000000 0.6211913
## banios 0.7246837 0.5695362 0.5157358 0.6211913 1.0000000
heatmap(Corr_x,
main = "Mapa de Calor de Correlación")
#install.packages("car")
library(car)
vif_values <- vif(modelo)
vif_values
## areaconst estrato habitaciones parqueaderos banios
## 2.602099 1.687459 1.428418 2.110436 2.910597
De acuerdo con la prueba de VIF (Factor de Inflación de la Varianza) se puede concluir que no existe problemas de multicolinealidad en el modelo ya que todos los valores son < a 5
# Crear un nuevo marco de datos con los valores de la nueva solicitud
solicitud_2 <- data.frame(areaconst = 300,
parqueaderos = 3,
habitaciones = 5,
estrato = c(5,6),
banios = 3,
zona = 2)
predicciones <- predict(modelo, newdata = solicitud_2)
solicitud_2$prediccion_precio <- predicciones
# Mostrar el marco de datos con las características y las predicciones
print(solicitud_2)
## areaconst parqueaderos habitaciones estrato banios zona prediccion_precio
## 1 300 3 5 5 3 2 826.6149
## 2 300 3 5 6 3 2 882.8570
La prediccion del modelo indica que el valor aproximado de la vivienda de la solicitud 2 se encuentra entre 827 y 883 millones de pesos.
pos_a <- which(vivienda$areaconst>= 300 & vivienda$parqueaderos>=3 & vivienda$banios>=3 & vivienda$habitaciones>=5 & vivienda$estrato>=5 & vivienda$estrato<=6 & vivienda$preciom<=850 & vivienda$zona == "Zona Sur" & vivienda$tipo == "Apartamento")
Ofertas_apartamentos <- vivienda[pos_a,]
Ofertas_apartamentos_5 = Ofertas_apartamentos[order(Ofertas_apartamentos$areaconst, decreasing = TRUE), ]
oferta2 <- head(Ofertas_apartamentos_5, 5)
knitr::kable(head(Ofertas_apartamentos_5, 5), caption = "5 Ofertas que cumple las caracterisiticas de la solicitud")
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 7182 | Zona Sur | NA | 5 | 730 | 573 | 3 | 8 | 5 | Apartamento | guadalupe | -76.548 | 3.408 | NA |
| 7512 | Zona Sur | NA | 5 | 670 | 300 | 3 | 5 | 6 | Apartamento | seminario | -76.550 | 3.409 | NA |
library(leaflet)
map_Apartamentos_oferta <- leaflet(oferta2) %>%
addTiles() %>%
addCircleMarkers(
lng = oferta2$longitud ,
lat = oferta2$latitud,
radius = 2,
color = "purple"
)
map_Apartamentos_oferta # Muestra el mapa