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:
knitr::include_graphics("D:/Usuarios/Chris/Escritorio/EjercicioActividad2.png", dpi = 100)
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).
Para alcanzar los objetivos del informe, el trabajo se desarrollará en varias etapas. Primero, se realizará un tratamiento general de los datos, con el fin de identificar sus limitaciones. A continuación, se procederá con un análisis descriptivo, seguido de la modelación, validación de supuestos y la formulación de sugerencias de ofertas. Todo lo anterior será documentado en el presente informe, junto con los códigos empleados en el programa R para ejecutar los análisis.
Las variables se renombran para identificarlas con mayor facilidad.
vf <- vivienda
renombrar_variables <- function(df, nuevas_variables) {
df %>%
rename_with(~nuevas_variables, everything())
}
vf <- renombrar_variables(vf, c("Id", "Zona", "Piso", "Estrato", "Precio", "Área", "Parqueaderos", "Baños", "Habitaciones", "Tipo", "Barrio", "Longitud", "Latitud"))
print(names(vf))
## [1] "Id" "Zona" "Piso" "Estrato" "Precio"
## [6] "Área" "Parqueaderos" "Baños" "Habitaciones" "Tipo"
## [11] "Barrio" "Longitud" "Latitud"
Se verifican los datos faltantes.
vf %>%
summarise_all(list(~ sum(is.na(.))))
## # A tibble: 1 × 13
## Id Zona Piso Estrato Precio Área Parqueaderos Baños Habitaciones Tipo
## <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 3 3 2638 3 2 3 1605 3 3 3
## # ℹ 3 more variables: Barrio <int>, Longitud <int>, Latitud <int>
Se encuentra que la variable Piso contiene una alta cantidad de datos faltantes, seguido de la variable parqueaderos, sin embargo, como para el presente ejercicio no se requiere de la intervención del atributo Piso, se procede a su eliminación. Asimismo, para el resto de filas que sólo tienen 3 datos faltantes, por no ser representativos, se eliminan.
vf <- vf[, !(names(vf) %in% c('Piso'))]
columnas_sin_parqueaderos <- vf[, !names(vf) %in% "Parqueaderos"]
vf <- vf[complete.cases(columnas_sin_parqueaderos), ]
head(vf)
## # A tibble: 6 × 12
## Id Zona Estrato Precio Área Parqueaderos Baños Habitaciones Tipo Barrio
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
## 1 1147 Zona … 3 250 70 1 3 6 Casa 20 de…
## 2 1169 Zona … 3 320 120 1 2 3 Casa 20 de…
## 3 1350 Zona … 3 350 220 2 2 4 Casa 20 de…
## 4 5992 Zona … 4 400 280 3 5 3 Casa 3 de …
## 5 1212 Zona … 5 260 90 1 2 3 Apar… acopi
## 6 1724 Zona … 5 240 87 1 3 3 Apar… acopi
## # ℹ 2 more variables: Longitud <dbl>, Latitud <dbl>
Por su parte, para el atributo Parqueaderos, que también cuenta con una considerable cantidad de datos faltantes, se procede a verificar si son influyentes en la variable de interés (Precio), para determinar si se pueden eliminar o mejor se deben imputar.
vf$Parqueaderos_missing <- as.numeric(is.na(vf$Parqueaderos))
aggregate(Precio ~ Parqueaderos_missing, data = vf, FUN = mean, na.rm = TRUE)
## Parqueaderos_missing Precio
## 1 0 468.8806
## 2 1 287.2534
Se encuentra que la media del atributo Precio cambia significativamente ante la presencia de datos faltantes en la variable Parqueaderos, por lo que no se elimina. A continuación se calcula la moda del atributo Parqueaderos en función de la Zona y Estrato de interés.
moda <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
df_grouped <- vf %>%
filter((Zona == "Zona Norte" & Tipo == "Casa") | (Zona == "Zona Sur" & Tipo == "Apartamento")) %>%
filter(Estrato %in% c(4, 5, 6)) %>%
group_by(Zona, Estrato) %>%
summarise(Moda_Parqueaderos = moda(Parqueaderos[!is.na(Parqueaderos)]),
Count = n(),
.groups = "drop") %>%
filter(Count > 1)
print(df_grouped)
## # A tibble: 6 × 4
## Zona Estrato Moda_Parqueaderos Count
## <chr> <dbl> <dbl> <int>
## 1 Zona Norte 4 2 161
## 2 Zona Norte 5 2 271
## 3 Zona Norte 6 3 55
## 4 Zona Sur 4 1 1091
## 5 Zona Sur 5 1 1033
## 6 Zona Sur 6 2 462
Se observa que la moda de Parqueaderos para una casa ubicada en la zona norte en estrato 4 y 5 es de dos y para un apartamento ubicado en la zona Sur en estrato 5 y 6 es de uno y dos, por lo que se decide imputar los datos faltantes del atributo Parqueaderos por el número dos para ambos tipos de vivienda.
vf$Parqueaderos[is.na(vf$Parqueaderos)] <- 2
vf <- vf[, !(names(vf) %in% c('Parqueaderos_missing'))]
Finalmente se verifica el tipo de dato para cada atributo.
Tipo <- sapply(vf, class)
numero_columnas <- ncol(vf)
numero_filas <- nrow(vf)
Tipo
## Id Zona Estrato Precio Área Parqueaderos
## "numeric" "character" "numeric" "numeric" "numeric" "numeric"
## Baños Habitaciones Tipo Barrio Longitud Latitud
## "numeric" "numeric" "character" "character" "numeric" "numeric"
numero_columnas
## [1] 12
numero_filas
## [1] 8319
Se verifica que la base da datos final está compuesta por 8.319 registros y 12 atributos,los cuales se distribuyen de la siguiente manera:
Variables categóricas: Zona, Tipo y Barrio
Variables numéricas: Estrato, Precio, Área, Parqueaderos, Baños, Habitaciones, Longitud y Latitud
La variable Id no se tiene en cuenta para el análisis, pero si para ubicar o referenciar a una determinada vivienda.
Una vez verificada la data, se aplica un filtro a la base, seleccionando el tipo de vivienda casas de la zona norte de la ciudad, mostrando como ejemplo los tres primeros registros.
basecasas <- vf[vf$Zona == "Zona Norte" & vf$Tipo == "Casa", ]
head(basecasas, 3)
## # A tibble: 3 × 12
## Id Zona Estrato Precio Área Parqueaderos Baños Habitaciones Tipo Barrio
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
## 1 1209 Zona … 5 320 150 2 4 6 Casa acopi
## 2 1592 Zona … 5 780 380 2 3 3 Casa acopi
## 3 4057 Zona … 6 750 445 2 7 6 Casa acopi
## # ℹ 2 more variables: Longitud <dbl>, Latitud <dbl>
Se valida la cantidad de viviendas tipo Casas que se encuentran ubicadas en la zona norte de la ciudad.
cantidad_zona <- table(basecasas$Zona)
print(cantidad_zona)
##
## Zona Norte
## 722
Se observa que la cantidad de Casas que se encuentran clasificadas como pertenecientes a la zona norte son 722.
Ahora, se verifica la distribución de las casas en la zona norte de la ciudad, para corroborar si se encuentran correctamente clasificadas. Para esto se genera un cuadrado en el mapa que busca representar la zona norte de la ciudad.
coordenadas <- data.frame(
lng = c(-76.55718, -76.55718, -76.47487, -76.47487, -76.55718),
lat = c(3.446409, 3.505871, 3.505871, 3.446409, 3.446409)
)
colores <- colorFactor(
palette = c("#00008B", "#FF4500", "#32CD32", "#FFD700"),
domain = basecasas$Estrato
)
mapa <- leaflet(basecasas) %>%
addTiles() %>%
addCircleMarkers(
lng = ~Longitud,
lat = ~Latitud,
color = ~colores(Estrato),
radius = 4,
popup = ~paste0(
"Precio: ", Precio, "<br>",
"Estrato: ", Estrato, "<br>",
"Área: ", Área, " m²<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Baños: ", Baños, "<br>",
"Habitaciones: ", Habitaciones
)
) %>%
addPolylines(
lng = coordenadas$lng,
lat = coordenadas$lat,
color = "black",
weight = 2
) %>%
addLegend("bottomright", pal = colores, values = ~Estrato, title = "Estratos", opacity = 1)
mapa
Se observa que, aunque la mayoría de las casas se encuentran ubicadas en la zona norte de la ciudad, algunas están clasificadas en otras zonas. Esto podría deberse a posibles errores en la georreferenciación de las viviendas, fallos en la codificación de las zonas o errores en la captura de los datos y su posterior incorporación a la base de datos. Esta observación se refuerza al encontrar que algunas casas contiguas presentan diferentes estratos socioeconómicos, cuando generalmente los estratos se definen en función de la zona o ubicación. Por lo tanto, se esperaba una homogeneidad en los estratos para un mismo punto geográfico.
Ahora se procede a calcular la cantidad de casas que si están correctamente clasificadas en la zona norte de la ciudad.
basecasas_sf <- st_as_sf(basecasas, coords = c("Longitud", "Latitud"), crs = 4326)
polygon_coords <- matrix(c(-76.55718, 3.446409,
-76.55718, 3.505871,
-76.47487, 3.505871,
-76.47487, 3.446409,
-76.55718, 3.446409), ncol = 2, byrow = TRUE)
polygon_sf <- st_polygon(list(polygon_coords)) %>% st_sfc(crs = 4326)
casas_dentro <- st_within(basecasas_sf, polygon_sf, sparse = FALSE)
num_casas_dentro <- sum(casas_dentro)
cat("Cantidad de casas correctamente ubicadas en la zona norte: ", num_casas_dentro, "\n")
## Cantidad de casas correctamente ubicadas en la zona norte: 591
En vista de lo anterior, se obtiene que el 81,85% de las casas se encuentran verdaderamente ubicadas en la zona norte, situación que conlleva a pensar en la posibilidad de dejar por fuera del estudio a las otras 131 viviendas, sin embargo, como se desconoce si las coordendas de estas últimas casas están o no correctamente registradas, dado que de lo contrario no estarían en la base inicial como de zona norte, se opta por continuar con el análisis sobre la base inicial filtrada, en otras palabras, pueda que las 131 casas si pertenezcan a la zona norte, pero que sus coordenadas no están registras correctamente, o pueda que si estén correctas y realmente no se encuentren en la zona norte, sino que haya sido posible un error de digitación de la información.
En otras palabras, se privilegia mantener la integridad del análisis al no excluir datos que, podrían ser relevantes, aunque también dudosos. Por lo anterior, se busca realizar un análisis más inclusivo que disminuya el riesgo de descartar información potencialmente relevante, para que se pueda contar con una muestra más representativa de la población de viviendas.
Con el objetivo de realizar una aproximación a inicial al comportamiento de la variable dependiente que en este caso es el Precio, en función de las variables explicativas como área, estrato, número de baños, número de habitaciones y zona, se realiza el siguiente análisis gráfico.
fig_area <- plot_ly(basecasas, x = ~Área, y = ~Precio, type = 'scatter', mode = 'markers',
text = ~paste("Estrato:", Estrato, "<br>Baños:", Baños, "<br>Habitaciones:", Habitaciones, "<br>Parqueaderos:", Parqueaderos, "<br>Zona:", Zona),
marker = list(size = 10, color = 'rgba(152, 0, 0, .8)')) %>%
layout(title = "Relación entre Precio y Área Construida en Casas",
xaxis = list(title = "Área Construida (m²)"),
yaxis = list(title = "Precio (COP)"))
fig_area
Se observa una tendencia creciente, lo que indica una correlación positiva entre el área construida de una casa y su precio para las viviendas de la zona norte, en otras palabras, las casas con mayor área tienden a presentar un mayor precio de venta. Cabe resaltar que también se evidencia algunos casos extremos cuando las viviendas superan 800 mt2 de área, dado que no presentan el patrón de incremento en el precio de venta.
fig_estrato <- plot_ly(basecasas, y = ~Precio, x = ~Estrato, type = "box", name = "Precio por Estrato")
fig_estrato <- fig_estrato %>% layout(title = "Boxplot de Precio por Estrato",
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio (COP)"))
fig_estrato
Se encuentra que a medida que aumenta el estrato socioeconómico, el precio de las casas tiende a incrementarse. También se destaca que, para el Estrato 3, los precios son los más bajos y la dispersión es menor, lo que se traduce en homogeneidad de precios, por su parte en el resto de estratos, hay un rango más amplio de precios, presentando además algunos valores atípicos, con casas con precios superiores a los 1.000 millones, sin embargo, esta situación puede deberse a la errónea clasificación de algunas de las casas en la zona norte de la ciudad, que a la vez conlleve a la asignación incorrecta del estrato, o a que los propietarios consideran otras variables para darle un mayor valor a la vivienda, como por ejemplo un valor sentimental o a que le hayan realizado remodelaciones interiores, entre otros factores no presentes en la base de datos.
fig_banos <- plot_ly(
basecasas,
x = ~Baños,
y = ~Precio,
type = 'scatter',
mode = 'markers',
text = ~paste(
"Área: ", Área, " m²<br>",
"Estrato: ", Estrato, "<br>",
"Habitaciones: ", Habitaciones, "<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Zona: ", Zona, "<br>",
"Precio: ", Precio, " COP"
),
marker = list(size = 10, color = 'rgba(50, 171, 96, .8)')
) %>%
layout(
title = "Relación entre Precio y Número de Baños",
xaxis = list(title = "Número de Baños"),
yaxis = list(title = "Precio (COP)")
)
fig_banos
Se contempla que hay una tendencia general a que los precios se incrementen con el número de baños, sin embargo, no se establece una relación lineal fuerte, dado que hay mucha variabilidad de Precios para casas con la misma cantidad de baños. Adicional, auque son muy pocas, hay casas que no cuentan con baños, por lo que podría tratarse de datos erróneos o que en efecto no cuenten con baños, lo cual es poco usual. Por otra parte, también se observa la presencia de algunos datos atípicos, cuando el precio es superior a 1.000 millones, dado que a partir de esta cifra se pierde la homogeneidad en el precio.
fig_habitaciones <- plot_ly(
basecasas,
x = ~Habitaciones,
y = ~Precio,
type = 'scatter',
mode = 'markers',
text = ~paste(
"Área: ", Área, " m²<br>",
"Estrato: ", Estrato, "<br>",
"Baños: ", Baños, "<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Zona: ", Zona, "<br>",
"Precio: ", Precio, " COP"
),
marker = list(size = 10, color = 'rgba(128, 0, 128, .8)')
) %>%
layout(
title = "Relación entre Precio y Número de Habitaciones",
xaxis = list(title = "Número de Habitaciones"),
yaxis = list(title = "Precio (COP)")
)
fig_habitaciones
Se encuentra que para cada número de habitaciones hay una considerable dispersión en el precio, lo que indica que la cantidad de habitaciones si bien es relevante para explicar el precio de la vivienda, no se debe considerar como una factor determinante, puesto que la relación con el precio en este caso no es fuertemente lineal. Asimismo, se observan unas casas sin habitaciones, lo que podría explicarse por un mal registro de la data o porque en realidad corresponden a casas adecuadas como locales comerciales o son casas que no están terminadas. En esta ocasión, también se observa la presencia de algunos datos atípicos, cuando el precio es superior a 1.000 millones, dado que a partir de esta cifra se pierde la homogeneidad en el precio.
fig_parqueaderos <- plot_ly(
basecasas,
x = ~Parqueaderos,
y = ~Precio,
type = 'scatter',
mode = 'markers',
text = ~paste(
"Área: ", Área, " m²<br>",
"Estrato: ", Estrato, "<br>",
"Baños: ", Baños, "<br>",
"Habitaciones: ", Habitaciones, "<br>",
"Zona: ", Zona, "<br>",
"Precio: ", Precio, " COP"
),
marker = list(size = 10, color = 'rgba(255, 255, 0, .9)')
) %>%
layout(
title = "Relación entre Precio y Número de Parqueaderos",
xaxis = list(title = "Número de Parqueaderos"),
yaxis = list(title = "Precio (COP)")
)
fig_parqueaderos
Se encuentra que, no hay una clara relación lineal entre el número de parqueaderos y el precio de las casas, dado que para una misma cantidad de parqueaderos hay mucha dispersión de precios, especialmente en casas con 1 hasta 4 parqueaderos. Para esta variable, la homogeneidad se pierde mayoritariamente cuando el Precio de la casa supera los 1.500 millones.
fig_zona <- plot_ly(basecasas, y = ~Precio, x = ~Zona, type = "box", name = "Precio Zona Norte")
fig_zona <- fig_zona %>% layout(title = "Boxplot de Precio por Zona",
xaxis = list(title = "Zona"),
yaxis = list(title = "Precio (COP)"))
fig_zona
Se analiza que la mediana de precios de las casas de la zona norte es de alrededor de 390 millones y en general el rango de precio de las viviendas va desde los 89 millones hasta los 950 millones, aunque también se presentan algunos datos atípicos con valores superiores a los $1.000 millones, que pueden deberse a problemas con la clasificación de las viviendas en la zona incorrecta.
Ahora, se calcula la correlación entre todas las variables que se consideran pueden influir en el precio de las casas.
correlacion1 <- basecasas %>% select(Precio=Precio, Área=Área, Estra=Estrato, Baños=Baños, Hab=Habitaciones, Parq=Parqueaderos)
g <- ggpairs(
correlacion1,
title = " ",
upper = list(continuous = wrap("cor", color = "red")),
lower = list(continuous = wrap("smooth", color = "green")),
diag = list(continuous = wrap("densityDiag", fill = "blue"))
)
p <- ggplotly(g)
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
p
Se observa que todas las variables presenten una correlación positiva frente al Precio de las casas, especialmente el área que presenta la correlación más fuerte, seguido del estrato y número de baños cuya correlación es moderada. Por su parte, la correlación con número de habitaciones y parqueaderos aunque es positiva es débil. Lo anterior significa que entre mayor cantidad de unidad de atributo adicional tengan las casas, mayor será su precio de venta.
El modelo de regresión lineal múltiple es una extensión de la regresión lineal simple, el cual facilita la modelación de la relación entre una variable dependiente y varias variables independientes, asumiendo una relación lineal entre variables. Para estimar el Precio de las casas se genera el modelo en la siguiente ecuación:
Precio_casas = β0 + β1xÁrea + β2xEstrato4 + β3xEstrato5 + β4xEstrato6 + β5xHabitaciones + β6xParqueaderos + β7xBaños + ε
Antes de correr el modelo, se procede a convertir el atributo Estrato de numérico a categórico para que opere como factor, dado que en realidad no es una variable cuantitativa, sino cualitativa ordinal debido a que representa categorías con un orden inherente.
Adicional, teniendo en cuenta la dispersión en el precio y debido a la disyuntiva de la clasificación correcta en la zona o en la coordenda, que conllevó a mantener toda la base de datos inicial, se han evidenciado algunos datos atípicos en la variable de interés, por lo que se opta por filtrar la base de casas con precio menores a 1.500 millones, para tampoco perder información significativa en la data.
Finalmente, los datos se dividen en 70% entrenamiento y 30% prueba.
basecasas$Estrato <- as.factor(basecasas$Estrato)
basecasasf <- basecasas %>% dplyr::filter(Precio < 1500)
set.seed(123)
trainIndex <- createDataPartition(basecasasf$Precio, p = 0.7, list = FALSE)
trainData <- basecasasf[trainIndex, ]
testData <- basecasasf[-trainIndex, ]
modelocasas <- lm(Precio ~ Área + Estrato + Habitaciones + Parqueaderos + Baños, data = trainData)
summary(modelocasas)
##
## Call:
## lm(formula = Precio ~ Área + Estrato + Habitaciones + Parqueaderos +
## Baños, data = trainData)
##
## Residuals:
## Min 1Q Median 3Q Max
## -626.88 -67.95 -17.34 45.40 792.79
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 50.71085 19.58439 2.589 0.009899 **
## Área 0.76506 0.04522 16.917 < 2e-16 ***
## Estrato4 65.53736 17.06231 3.841 0.000138 ***
## Estrato5 140.78766 16.09170 8.749 < 2e-16 ***
## Estrato6 339.70654 26.56763 12.786 < 2e-16 ***
## Habitaciones -4.61728 4.05022 -1.140 0.254835
## Parqueaderos 17.39775 6.28767 2.767 0.005870 **
## Baños 22.43455 5.16347 4.345 1.69e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 130.2 on 494 degrees of freedom
## Multiple R-squared: 0.7155, Adjusted R-squared: 0.7115
## F-statistic: 177.5 on 7 and 494 DF, p-value: < 2.2e-16
predicciones <- predict(modelocasas, newdata = testData)
MSE <- mean((testData$Precio - predicciones)^2)
cat("Error Cuadrático Medio en el conjunto de prueba: ", MSE, "\n")
## Error Cuadrático Medio en el conjunto de prueba: 19539.32
MAE <- mean(abs(testData$Precio - predicciones))
cat("Error Absoluto Medio en el conjunto de prueba: ", MAE, "\n")
## Error Absoluto Medio en el conjunto de prueba: 96.45203
RMSE <- sqrt(MSE)
cat("Raíz del error cuadrático medio en el conjunto de prueba: ", RMSE, "\n")
## Raíz del error cuadrático medio en el conjunto de prueba: 139.7831
Sobre los coeficientes del modelo se puede apreciar que:
El intercepto cuyo valor es de 50.71 no es interpretable, dado que indicaría que ante ausencia de las variables regresoras, el Precio de la vivienda sería en promedio de 50.71 millones COP, lo cual no tiene sentido con la realidad, dado que es como si se tratara del precio de venta del lote.
β1 que es el coeficient del área, arrojó un valor de 0.76, este coeficiente representa el cambio esperado en la variable (y) por cada unidad de incremento en la variable (Área) mt2, manteniendo constante las demás variables predictoras. Así, por cada metro cuadrado adicional de área construida, el precio promedio de la vivienda aumentará en 0.76 millones COP. Esta variable es estadísticamente significativa para cualquier nivel de alfa, en otras palabras, la relación entre el área y el precio es sólida y confiable en términos estadísticos, y es poco probable que sea producto del azar.
β2, β3 y β4 que son los coeficientes de los estratos, arrojó un valor de 65.53, 140.78 y 339.70, lo que indica que, a medida que se aumenta el estrato de la casa, manteniendo constante las demás variables predictoras, se incrementa el precio de la vivienda. Así, por cada cambio adicional en una unidad de estrato, el precio promedio de la vivienda aumentará en 65.53, 140.78 ó 339.70 millones COP. Esta variable también es estadísticamente significativa para cualquier nivel de alfa.
β5 que es el coeficiente del número de habitaciones, arrojó un valor de -4.61, lo que indica que, a medida que se aumenta la cantidad de habitaciones en una unidad y manteniendo las demás variables constantes, disminuye el precio promedio de la casa en 4.61 millones COP, lo cual no tiene sentido, razón por la cual también el error estándar fue relativamente grande en comparación con el coeficiente, lo que indica una menor precisión en la estimación, esto sumado a que la variable resultó no ser significativa para ningún valor de alfa, dan argumentos para que no sea considerada en el modelo, dado que no es apta para explicar la variabilidad en el Precio de las casas.
β6 que es el coeficiente del número de parqueaderos, arrojó un valor de 17.39 lo que indica que, a medida que se aumenta la cantidad de parqueaderos en una unidad, aumenta en promedio el precio de la casa en 17.39 millones COP, manteniendo todo lo demás constante, lo cual es correcto, dado que los compradores buscan adquirir viviendas que tengan parqueadero propio. Esta variable también es estadísticamente significativa pero para alfa mayores al 1%.
β7 que es el coeficiente del número de baños, arrojó un valor de 22.43 lo que indica que, a medida que se aumenta la cantidad de baños en una unidad, aumenta en promedio el precio de la casa en 22.43 millones COP, manteniendo todo lo demás constante, lo cual también es correcto, dado que los compradores buscan adquirir viviendas que tengan suficientes baños para los habitantes o en relación con el número de habitaciones. Esta variable también es estadísticamente significativa para cualquier nivel de alfa.
Sobre el ajuste del modelo se puede observar que:
Al verificar el coeficiente de bondad del modelo, se encuentra que, este es de 0.7155, indicando que las variables independientes del modelo, explican en conjunto un 71.55% de la variabilidad en el precio de la vivienda en millones COP. Así, si bien este coeficiente de determinación no es cercano a uno, si refleja que las variables explicativas tienen una considerable influencia en la variable explicada, dado que explica más de la mitad de su porcentaje de variación.
El error estándar residual fue de 130.2, lo que indica que en promedio los valores observados del Precio de la vivienda se desvían de los valores predichos por el modelo en 130.2 millones COP.
El estadístico F fue de 177.5 con 7 grados de libertad para los predictores y 494 grados de libertad para los residuales, establece que el modelo en general es altamente significativo. Un valor F alto indica que la variabilidad explicada por el modelo es mucho mayor que la variabilidad no explicada, lo que complementa el argumento de que el modelo es útil para explicar la variable dependiente.
El valor p del modelo es inferior al alfa del 0.05, lo que indica que es muy poco probable que el modelo no explique la variabilidad en los precios de las casas de la zona norte de la ciudad, es decir, las variables predictoras en conjunto tienen un impacto significativo en la variable dependiente.
Los residuos que van de -626.88 a 792.79, indican que hay presencia de valores atípicos y que son significativos, por lo que se puede afectar la predicción del modelo.
La media de los cuadrados de los errores, MSE, fue de 19539.32, indica que, en promedio, el cuadrado de la diferencia entre los valores predichos y los observados es relativamente alto, sin embargo, esto puede presentarse por temas de la escala de la variable de respueta.
La media de los errores absolutos entre las predicciones y los valores observados fue de 96.45, lo que establece que, en promedio, las predicciones del modelo se desvían de los valores observados en aproximadamente 96.45 millones COP.
La raíz del error cuadrático medio, que mide la magnitud promedio de los errores en las predicciones del modelo fue de 139.78 millones COP, como es un número bajo indica un buen ajuste del modelo a los datos.
Sobre opciones de mejora del modelo se puede encontrar que:
Si bien el modelo no logra capturar toda la varianza del Precio de las casas, se sugiere establecer pasos adicionales, para lograr mejorarlo, como por ejemplo, explorar la posibilidad de incluir otras variables que expliquen mejor la variación del Precio, por ejemplo la antigüedad del bien, dado que a medida que aumenta el tiempo, la vivienda tiende a valorizarse más.
Otro factor a tener en cuenta es evaluar la presencia de multicolinealidad, dado que de presentarse, afectará el redimiento del modelo.
Adicional, se podría pensar en establecer modelos diferentes en función del estrato, dado que se observa que a medida que se incrementa el estrato, el Precio tiende a subir significativamente, por lo que resulta necesario descubrir otros mecanismos que influyen en el precio para cada estrato.
Finalmente, resulta relevante realizar un mejor tratamiento a los datos atípicos, de manera que no generen ruido en el modelo y así se puedan producir estimaciones más precisas.
Los supuestos se proceden a corroborar por medio de gráficos y test.
par(mfrow=c(2,2))
plot(modelocasas, col="blue", main="Modelo para Casas")
Linealidad
Al observar la gráfica Residuals Vs Fitted, se encuentra que,la línea roja aunque no es muy precisa, se comporta como una recta a lo largo de los datos, sin embargo, al final parece convertirse en curva, por lo que se podría apreciar que el modelo no está capturando bien la relación entre las variables, en otras palabras, no se cumpliría con el supuesto, sin embargo, esto se corrobora con el test de Ramsey.
resettest(modelocasas)
##
## RESET test
##
## data: modelocasas
## RESET = 17.629, df1 = 2, df2 = 492, p-value = 4.034e-08
El test de Ramsey, indica que el valor p es muy inferior al nivel de significancia del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, por tanto, la relación entre las variables no es lineal.
Para corregir la no linealidad, se debe contemplar la falta de otras variables no lineales que puedan interar en el modelo. También se pueden realizar transformaciones de variables o en definitiva correr un modelo no lineal.
Normalidad
Al observar la gráfica Q-Q Residuals, se encuentra que hay muchos datos que no se ajustan a la linea de normalidad, lo que demuestra que no se cumple con el supuesto. Asimismo, se presentan asimetrías por la ubicación lejana de los puntos respecto de la recta en las colas de la distribución. Para corroborar lo anterior, se procede a realizar el Test de Shapiro y Anderson-Darling.
pruebat <- shapiro.test(modelocasas$residuals)
pruebat
##
## Shapiro-Wilk normality test
##
## data: modelocasas$residuals
## W = 0.882, p-value < 2.2e-16
andersont <- ad.test(modelocasas$residuals)
print(andersont)
##
## Anderson-Darling normality test
##
## data: modelocasas$residuals
## A = 13.521, p-value < 2.2e-16
El test de Shapiro y el test de Anderson-Darling, indican que el valor p es muy inferior al nivel de significancia del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, por tanto, la distribución de los errores no es normal.
Teniendo en cuenta que no se cumple con el supuesto de normalidad, para corregir esto se podría considerar la transformación de la variable Precio, de manera que se aproxime a la distribución normal. También se podría pensar en correr un modelo más robusto, de manera que no requiera del cumplimiento de la normalidad.
Homocedasticidad
Al observar la gráfica Scale-Location, se encuentra que los residuos no se distribuyen aleatoriamente a lo largo de la recta roja, puesto que se presenta una tendencia creciente a medida que aumentan las observaciones. En otras palabras, no se cumple con el supuesto. Para soportar lo anterior, se realiza el Test de Breusch-Pagan.
lmtest::bptest(modelocasas)
##
## studentized Breusch-Pagan test
##
## data: modelocasas
## BP = 65.299, df = 7, p-value = 1.309e-11
El test de Breusch-Pagan, establece que el valor p es menor al alfa del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, y de esta manera concluir que la varianza de los errores no es constante.
Independencia
Para validar este supuesto se realiza el test de Durbin-Watson.
lmtest::dwtest(modelocasas)
##
## Durbin-Watson test
##
## data: modelocasas
## DW = 1.6869, p-value = 0.0001647
## alternative hypothesis: true autocorrelation is greater than 0
Al observar el test de Durbin-Watson, se encuentra que el valor p es menor al alfa del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, y de esta manera concluir que los errores no son independientes. Así, no se cumple con el supuesto.
Para poder corregir el incumplimiento de este supuesto, es viable optar por utilizar métodos de bootstrap o permutación, que sirven para hacer inferencias sin depender de la independencia. También se podría optar por incluir términos autorregresivos en el modelo para capturar la dependencia.
No Colinealidad
La multicolinealidad ocurre cuando dos o más variables independientes en un modelo de regresión se encuentran altamente correlacionadas, lo que genera inconvenientes en la estimación de los coeficientes del modelo. Para verificar la no presencia de multicolinealidad, se realiza la prueba del factor de inflación de varianza.
vif(modelocasas)
## GVIF Df GVIF^(1/(2*Df))
## Área 1.520907 1 1.233251
## Estrato 1.515680 3 1.071769
## Habitaciones 1.608645 1 1.268324
## Parqueaderos 1.109251 1 1.053210
## Baños 1.871697 1 1.368100
Se observa que en todas las variables explicativas el VIF es menor a 5, lo que indica que no hay problemas de multicolinealidad, en otras palabras, los coeficientes del modelo no deberían estar inflados debido a la correlación entre las variables independientes.
Para complementar lo anterior, se calcula el índice de condición.
ols_eigen_cindex(modelocasas)
## Eigenvalue Condition Index intercept Área Estrato4 Estrato5
## 1 5.29018655 1.000000 2.912102e-03 5.494088e-03 4.241292e-03 0.005799809
## 2 1.00876868 2.290022 2.975163e-04 1.070794e-03 2.688062e-01 0.008695147
## 3 1.00062055 2.299327 2.224935e-07 8.122451e-06 1.139783e-01 0.139551979
## 4 0.27294178 4.402511 2.025672e-02 3.615221e-02 4.185132e-01 0.482490280
## 5 0.16557306 5.652501 8.523019e-03 2.273494e-01 6.854106e-03 0.035011559
## 6 0.13833734 6.183947 1.094161e-02 7.162716e-01 7.874365e-02 0.213193977
## 7 0.07202163 8.570458 7.134183e-01 3.955292e-03 4.908912e-05 0.009064692
## 8 0.05155040 10.130234 2.436505e-01 9.698467e-03 1.088142e-01 0.106192557
## Estrato6 Habitaciones Parqueaderos Baños
## 1 0.002603019 2.833356e-03 5.176992e-03 2.829150e-03
## 2 0.289752826 3.214357e-05 4.880733e-05 1.426098e-05
## 3 0.247426205 1.444176e-05 2.683619e-06 3.726228e-05
## 4 0.176113120 5.153142e-02 2.417977e-02 6.275664e-03
## 5 0.035415123 5.717966e-02 5.816814e-01 2.973741e-02
## 6 0.132001662 3.901154e-02 1.377358e-01 7.141957e-02
## 7 0.028596277 5.102740e-06 2.026260e-01 3.814454e-01
## 8 0.088091769 8.493923e-01 4.854859e-02 5.082413e-01
Se observa que el índice de condición es menor a 10 para casi todos los valores propios, con excepción del último, por lo que en general no hay problemas graves de multicolinealidad, aunque el valor de la última fila se puede interpretar como una señal de colinealidad moderada.
Finalmente, para descartar el incumplimiento del supuesto, se procede a realizar el análisis de descomposición de la varianza.
ols_vif_tol(modelocasas)
## Variables Tolerance VIF
## 1 Área 0.6575024 1.520907
## 2 Estrato4 0.6874090 1.454738
## 3 Estrato5 0.5595085 1.787283
## 4 Estrato6 0.6842321 1.461492
## 5 Habitaciones 0.6216413 1.608645
## 6 Parqueaderos 0.9015092 1.109251
## 7 Baños 0.5342746 1.871697
Los resultados indican que ninguna de las variables presenta problemas graves de multicolinealidad. Los VIF están por debajo de 2, lo que significa que las varianzas de los coeficientes no están infladas por la presencia de colinealidad. Por su parte, las tolerancias se ubican por encima de 0.5, lo que establece que cada variable tiene una cantidad razonable de varianza que no está explicada por las otras variables.
Partiendo de una vivienda tipo casa, ubicada en el norte de la ciudad de Cali, que cuente con un área construida de 200 mt2, tenga 1 parqueadero, 2 baños, 4 habitaciones y pertenezca al estrato 4 ó 5, los precios de las casas en promedio serán de:
(predict(modelocasas, list(Área = c(200, 200),
Parqueaderos = c(1, 1),
Baños = c(2, 2),
Habitaciones = c(4, 4),
Estrato = factor(c("4", "5"), levels = c("3", "4", "5", "6")) ), interval = "confidence", level = 0.95))
## fit lwr upr
## 1 313.0575 282.0674 344.0476
## 2 388.3078 359.4468 417.1687
Se establece que para las características de la casa, si se encuentran en estrato 4, el precio promedio sería de 313 millones COP, mientras que si se encuentran en estrato 5, el precio promedio sería de 388 millones COP. La diferencia entre el precio promedio de la casa para ambos es estratos es de 75 millones COP, que equivale a la diferencia entre los coeficientes de los estratos estimados en el modelo.
Ahora, al evaluar el precio mediante un intervalo de confianza del 95%, se encuentra que para la casa de estrato 4, el precio promedio oscila entre 282 y 344 millones COP, mientras que para el estrato 5, oscila en promedio entre 359 y 417 millones COP.
Teniendo en cuenta el crédito preaprobado de 350 millones COP, se plantean las siguientes viviendas como alternativa de compra.
oferta_casas <- basecasas %>%
dplyr::filter(Precio == 350, Área >= 200, Parqueaderos >=1, Baños >= 2, Habitaciones >= 4, Estrato %in% c("4", "5")) %>%
head(5)
print(oferta_casas)
## # A tibble: 5 × 12
## Id Zona Estrato Precio Área Parqueaderos Baños Habitaciones Tipo Barrio
## <dbl> <chr> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
## 1 4210 Zona … 5 350 200 3 3 4 Casa el bo…
## 2 4209 Zona … 5 350 300 3 5 6 Casa el bo…
## 3 4422 Zona … 5 350 240 2 3 6 Casa el bo…
## 4 1270 Zona … 5 350 203 2 2 5 Casa el bo…
## 5 819 Zona … 5 350 264 2 3 4 Casa la fl…
## # ℹ 2 more variables: Longitud <dbl>, Latitud <dbl>
De las 5 viviendas ofertadas, se destaca la identificada con los Id 4209 y 819, dado que son las de mayor área, cuentan con 3 y 2 parqueaderos respectivamente, al igual que 5 y 3 baños, y 6 y 4 habitaciones. Una casa se encuentra ubicada en el barrio el bosque y la otra en el barrio la flora, zonas de alta valorización por el crecimiento de la ciudad y que pertenecen al estrato 5. Por otra parte, se destaca que ambas viviendas se acoplan al presupuesto de 350 millones COP.
La oferta total de viviendas que mejor se ajustan al presupuesto estipulado se puede encontrar en el siguiente mapa.
coordenadas <- data.frame(
lng = c(-76.55718, -76.55718, -76.47487, -76.47487, -76.55718),
lat = c(3.446409, 3.505871, 3.505871, 3.446409, 3.446409)
)
mapa2 <- leaflet(oferta_casas) %>%
addTiles() %>%
addCircleMarkers(
lng = ~Longitud,
lat = ~Latitud,
radius = 4,
popup = ~paste0(
"Precio: ", Precio, "<br>",
"Estrato: ", Estrato, "<br>",
"Área: ", Área, " m²<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Baños: ", Baños, "<br>",
"Habitaciones: ", Habitaciones
)
) %>%
addPolylines(
lng = coordenadas$lng,
lat = coordenadas$lat,
color = "black",
weight = 2
) %>%
addLegend("bottomright", pal = colores, values = ~Zona, opacity = 1)
## Warning in pal(v): Some values were outside the color scale and will be treated
## as NA
mapa2
Una vez verificada la data, se aplica un filtro a la base, seleccionando el tipo de vivienda apartamentos de la zona sur de la ciudad, mostrando como ejemplo los tres primeros registros.
baseapartamentos <- vf[vf$Zona == "Zona Sur" & vf$Tipo == "Apartamento", ]
head(baseapartamentos, 3)
## # A tibble: 3 × 12
## Id Zona Estrato Precio Área Parqueaderos Baños Habitaciones Tipo Barrio
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
## 1 5098 Zona … 4 290 96 1 2 3 Apar… acopi
## 2 698 Zona … 3 78 40 1 1 2 Apar… aguab…
## 3 8199 Zona … 6 875 194 2 5 3 Apar… aguac…
## # ℹ 2 more variables: Longitud <dbl>, Latitud <dbl>
Se valida la cantidad de viviendas tipo Apartamentos que se encuentran ubicadas en la zona sur de la ciudad.
cantidad_zona2 <- table(baseapartamentos$Zona)
print(cantidad_zona2)
##
## Zona Sur
## 2787
Se observa que la cantidad de apartamentos que se encuentran clasificadas como pertenecientes a la zona sur son 2.787.
Ahora, se verifica la distribución de los apartamentos en la zona sur de la ciudad, para corroborar si se encuentran correctamente ubicadas. Para esto se establece un cuadrado en el mapa que busca representar la zona sur.
coordenadas2 <- data.frame(
lng2 = c(-76.55083, -76.50444, -76.51600, -76.55999, -76.55083),
lat2 = c(3.42500, 3.40861, 3.32967, 3.33649, 3.42500)
)
colores <- colorFactor(
palette = c("#00008B", "#FF4500", "#32CD32", "#FFD700"),
domain = baseapartamentos$Estrato
)
mapa3 <- leaflet(baseapartamentos) %>%
addTiles() %>%
addCircleMarkers(
lng = ~Longitud,
lat = ~Latitud,
color = ~colores(Estrato),
radius = 4,
popup = ~paste0(
"Precio: ", Precio, "<br>",
"Estrato: ", Estrato, "<br>",
"Área: ", Área, " m²<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Baños: ", Baños, "<br>",
"Habitaciones: ", Habitaciones
)
) %>%
addPolylines(
lng = coordenadas2$lng,
lat = coordenadas2$lat,
color = "black",
weight = 2
) %>%
addLegend("bottomright", pal = colores, values = ~Estrato, title = "Estratos", opacity = 1)
mapa3
Se observa que, aunque la mayoría de los apartamentos se encuentran ubicados en la zona sur de la ciudad, algunos están clasificadas en otras zonas. Esto podría deberse a posibles errores en la georreferenciación de las viviendas, fallos en la codificación de las zonas o errores en la captura de los datos y su posterior incorporación a la base de datos, tal como ocurre con las casas. Esta observación se refuerza al encontrar que algunos apartamentos contiguos presentan diferentes estratos socioeconómicos, cuando generalmente los estratos se definen en función de la zona o ubicación. Por lo tanto, se esperaba una homogeneidad en los estratos para un mismo punto geográfico.
Ahora se procede a calcular la cantidad de apartamentos que si están adecuadamente clasificadas en la zona sur de la ciudad.
baseapartamentos_sf <- st_as_sf(baseapartamentos, coords = c("Longitud", "Latitud"), crs = 4326)
polygon_coords2 <- matrix(c(-76.55083, 3.42500,
-76.50444, 3.40861,
-76.51600, 3.32967,
-76.55999, 3.33649,
-76.55083, 3.42500), ncol = 2, byrow = TRUE)
polygon_sf <- st_polygon(list(polygon_coords2)) %>% st_sfc(crs = 4326)
apartamentos_dentro <- st_within(baseapartamentos_sf, polygon_sf, sparse = FALSE)
num_apartamentos_dentro <- sum(apartamentos_dentro)
cat("Cantidad de apartamentos correctamente ubicados en la zona sur: ", num_apartamentos_dentro, "\n")
## Cantidad de apartamentos correctamente ubicados en la zona sur: 2287
En vista de lo anterior, se obtiene que el 82,05% de los apartamentos se encuentran verdaderamente ubicados en la zona sur, situación que conlleva a pensar en la posibilidad de dejar por fuera del estudio a las otras 500 viviendas, sin embargo, como se desconoce si las coordendas de estos últimos apartamentos están o no correctamente registradas, dado que de lo contrario no estarían en la base inicial como de zona sur, se opta por continuar con el análisis sobre la base inicial filtrada, en otras palabras, pueda que los 500 apartamentos si pertenezcan a la zona sur, pero que sus coordenadas no esten registras correctamente, o pueda que si estén correctas y realmente no se encuentren en la zona sur, sino que haya sido posible un error de digitación de la información.
Con el objetivo de realizar una aproximación a inicial al comportamiento de la variable dependiente que en este caso es el Precio, en función de las variables explicativas como área, estrato, número de baños, número de habitaciones y zona, se realiza el siguiente análisis gráfico.
fig_area2 <- plot_ly(baseapartamentos, x = ~Área, y = ~Precio, type = 'scatter', mode = 'markers',
text = ~paste("Estrato:", Estrato, "<br>Baños:", Baños, "<br>Habitaciones:", Habitaciones, "<br>Parqueaderos:", Parqueaderos, "<br>Zona:", Zona),
marker = list(size = 10, color = 'rgba(152, 0, 0, .8)')) %>%
layout(title = "Relación entre Precio y Área Construida en Apartamentos",
xaxis = list(title = "Área Construida (m²)"),
yaxis = list(title = "Precio (COP)"))
fig_area2
Se observa una tendencia creciente, lo que indica una correlación positiva entre el área construida de un apartamento y su precio para las viviendas de la zona sur, en otras palabras, los apartamentos con mayor área tienden a presentar un mayor precio de venta, aunque en una menor magnitud como ocurre con las casas. Cabe resaltar que los apartamentos presentan unos casos atípicos cuando el área construida supera los 400 mt2, dado que apartir de esta área el precio tiende a disminuir, lo cual no es tan razonable, pero tampoco es común encontrar apartamentos tan grandes, lo que lleva a cuestionarse si en realidad son apartamentos o mejor casas que no están correctamente clasificadas en el tipo de vivienda.
fig_estrato2 <- plot_ly(baseapartamentos, y = ~Precio, x = ~Estrato, type = "box", name = "Precio por Estrato")
fig_estrato2 <- fig_estrato %>% layout(title = "Boxplot de Precio por Estrato",
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio (COP)"))
fig_estrato2
Se encuentra que a medida que aumenta el estrato socioeconómico, el precio de los aparramentos tiende a incrementarse. También se destaca que, para el Estrato 3, los precios son los más bajos y la dispersión es menor, lo que se traduce en homogeneidad de precios, por su parte en el resto de estratos, hay un rango más amplio de precios, presentando además algunos valores atípicos, más que todo en el estrato 5, puesto que aparecen apartamentos con precios superiores a los 1.000 millones, sin embargo, esta situación puede deberse a la errónea clasificación de algunos de los apartamentos en la zona sur de la ciudad, a que los propietarios consideran la antigüedad del bien para asignar el precio, a que consideran el número del piso en el que se ubica, o a que le hayan realizado remodelaciones interiores, entre otros factores no presentes en la base de datos que influyen en el precio.
fig_banos2 <- plot_ly(
baseapartamentos,
x = ~Baños,
y = ~Precio,
type = 'scatter',
mode = 'markers',
text = ~paste(
"Área: ", Área, " m²<br>",
"Estrato: ", Estrato, "<br>",
"Habitaciones: ", Habitaciones, "<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Zona: ", Zona, "<br>",
"Precio: ", Precio, " COP"
),
marker = list(size = 10, color = 'rgba(50, 171, 96, .8)')
) %>%
layout(
title = "Relación entre Precio y Número de Baños",
xaxis = list(title = "Número de Baños"),
yaxis = list(title = "Precio (COP)")
)
fig_banos2
Se contempla que hay una tendencia general a que los precios se incrementen con el número de baños, sin embargo, no se establece una relación lineal fuerte, dado que hay mucha variabilidad de Precios para apartamentos con la misma cantidad de baños. Adicional, auque son muy pocos, hay apartamentos que no cuentan con baños, por lo que podría tratarse de datos erróneos o que en efecto no cuenten con baños porque se encuentra en obra gris, lo cual es poco usual. Por otra parte, también se observa la presencia de algunos datos atípicos, cuando el precio es superior a 1.000 millones, dado que a partir de esta cifra se pierde la homogeneidad en el precio.
fig_habitaciones2 <- plot_ly(
baseapartamentos,
x = ~Habitaciones,
y = ~Precio,
type = 'scatter',
mode = 'markers',
text = ~paste(
"Área: ", Área, " m²<br>",
"Estrato: ", Estrato, "<br>",
"Baños: ", Baños, "<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Zona: ", Zona, "<br>",
"Precio: ", Precio, " COP"
),
marker = list(size = 10, color = 'rgba(128, 0, 128, .8)')
) %>%
layout(
title = "Relación entre Precio y Número de Habitaciones",
xaxis = list(title = "Número de Habitaciones"),
yaxis = list(title = "Precio (COP)")
)
fig_habitaciones2
Se encuentra que para cada número de habitaciones hay una considerable dispersión en el precio, lo que indica que la cantidad de habitaciones si bien es relevante para explicar el precio de la vivienda, no se debe considerar como una factor determinante, puesto que la relación con el precio en este caso no es fuertemente lineal. Asimismo, se observan unos apartamentos sin habitaciones, lo que podría explicarse por un mal registro de la data o porque en realidad corresponden a apartamentos adecuados para oficinas, o son apartamentos que no están terminados. En esta ocasión, se observa la presencia de algunos datos atípicos, cuando el precio es superior a 1.500 millones, dado que a partir de esta cifra se pierde la homogeneidad en el precio.
fig_parqueaderos2 <- plot_ly(
baseapartamentos,
x = ~Parqueaderos,
y = ~Precio,
type = 'scatter',
mode = 'markers',
text = ~paste(
"Área: ", Área, " m²<br>",
"Estrato: ", Estrato, "<br>",
"Baños: ", Baños, "<br>",
"Habitaciones: ", Habitaciones, "<br>",
"Zona: ", Zona, "<br>",
"Precio: ", Precio, " COP"
),
marker = list(size = 10, color = 'rgba(255, 255, 0, .9)')
) %>%
layout(
title = "Relación entre Precio y Número de Parqueaderos",
xaxis = list(title = "Número de Parqueaderos"),
yaxis = list(title = "Precio (COP)")
)
fig_parqueaderos2
Se encuentra que, no hay una clara relación lineal entre el número de parqueaderos y el precio de los apartamentos, dado que para una misma cantidad de parqueaderos hay mucha dispersión de precios, especialmente en apartamentos con 1 hasta 3 parqueaderos. Para esta variable, la homogeneidad se pierde mayoritariamente cuando el Precio del apartamento supera los 1.000 millones.
fig_zona2 <- plot_ly(baseapartamentos, y = ~Precio, x = ~Zona, type = "box", name = "Precio Zona Sur")
fig_zona <- fig_zona %>% layout(title = "Boxplot de Precio por Zona",
xaxis = list(title = "Zona"),
yaxis = list(title = "Precio (COP)"))
fig_zona2
Se analiza que la mediana de precios de los apartamentos de la zona sur es de alrededor de 245 millones y en general el rango de precio de las viviendas va desde los 75 millones hasta los 575 millones, aunque también se presentan algunos datos atípicos con valores superiores a los $600 millones, que pueden deberse a problemas con la clasificación de las viviendas en la zona correcta o a que son apartamentos que cuentan con otros atributos particulares que les asigna un mayor precio.
Ahora, se calcula la correlación entre todas las variables que se consideran pueden influir en el precio de los apartamentos.
correlacion2 <- baseapartamentos %>% select(Precio=Precio, Área=Área, Estra=Estrato, Baños=Baños, Hab=Habitaciones, Parq=Parqueaderos)
g <- ggpairs(
correlacion2,
title = " ",
upper = list(continuous = wrap("cor", color = "red")),
lower = list(continuous = wrap("smooth", color = "green")),
diag = list(continuous = wrap("densityDiag", fill = "blue"))
)
p <- ggplotly(g)
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
## Warning: Can only have one: highlight
p
Se observa que todas las variables presenten una correlación positiva frente al Precio de los apartamentos, especialmente el área y el número de baños que presentan la correlación más fuerte, seguido del estrato y número de parqueaderos cuya correlación es moderada. Por su parte, la correlación con número de habitaciones aunque es positiva es débil. Lo anterior significa que entre mayor cantidad de unidad de atributo adicional tengan los apartamentos, mayor será su precio de venta.
Para estimar el Precio de los apartamentos se genera el modelo en la siguiente ecuación:
Precio_aptos = β0 + β1xÁrea + β2xEstrato4 + β3xEstrato5 + β4xEstrato6 + β5xHabitaciones + β6xParqueaderos + β7xBaños + ε
Antes de correr el modelo, se procede a convertir el atributo Estrato de numérico a categórico para que opere como factor.
Adicional, teniendo en cuenta la dispersión en el precio y debido a la disyuntiva de la clasificación correcta en la zona o en la coordenda, que conllevó a mantener toda la base de datos inicial, se han evidenciado algunos datos atípicos en la variable de interés, por lo que se opta por filtrar la base de apartamentos con precio menores a 1.500 millones, para tampoco perder información significativa en la data.
Finalmente, se distribuyen los datos del modelo en 70% entrenamiento y 30% prueba.
baseapartamentos$Estrato <- as.factor(baseapartamentos$Estrato)
baseapartamentos_sf <- baseapartamentos %>% dplyr::filter(Precio < 1500)
set.seed(123)
trainIndex2 <- createDataPartition(baseapartamentos_sf$Precio, p = 0.7, list = FALSE)
trainData2 <- baseapartamentos_sf[trainIndex2, ]
testData2 <- baseapartamentos_sf[-trainIndex2, ]
modeloapartamentos <- lm(Precio ~ Área + Estrato + Habitaciones + Parqueaderos + Baños, data = trainData2)
summary(modeloapartamentos)
##
## Call:
## lm(formula = Precio ~ Área + Estrato + Habitaciones + Parqueaderos +
## Baños, data = trainData2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -878.34 -43.85 -1.20 38.00 595.63
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -55.92556 11.66314 -4.795 1.75e-06 ***
## Área 1.06006 0.04807 22.050 < 2e-16 ***
## Estrato4 34.26071 7.58366 4.518 6.63e-06 ***
## Estrato5 71.96680 7.86173 9.154 < 2e-16 ***
## Estrato6 231.38677 9.55062 24.227 < 2e-16 ***
## Habitaciones -0.07182 3.42641 -0.021 0.983
## Parqueaderos 35.70690 3.53125 10.112 < 2e-16 ***
## Baños 45.94322 3.02964 15.165 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 78.29 on 1938 degrees of freedom
## Multiple R-squared: 0.7914, Adjusted R-squared: 0.7907
## F-statistic: 1051 on 7 and 1938 DF, p-value: < 2.2e-16
predicciones2 <- predict(modeloapartamentos, newdata = testData2)
MSE2 <- mean((testData2$Precio - predicciones2)^2)
cat("Error Cuadrático Medio en el conjunto de prueba: ", MSE2, "\n")
## Error Cuadrático Medio en el conjunto de prueba: 6713.638
MAE2 <- mean(abs(testData2$Precio - predicciones2))
cat("Error Absoluto Medio en el conjunto de prueba: ", MAE2, "\n")
## Error Absoluto Medio en el conjunto de prueba: 54.75034
RMSE2 <- sqrt(MSE2)
cat("Raíz del error cuadrático medio en el conjunto de prueba: ", RMSE2, "\n")
## Raíz del error cuadrático medio en el conjunto de prueba: 81.93679
Sobre los coeficientes del modelo se puede apreciar que:
El intercepto cuyo valor es de -55.92 no es interpretable, dado que indicaría que ante ausencia de las variables regresoras, el Precio promedio de la vivienda sería de -55.92 millones, lo cual no tiene sentido con la realidad.
β1 arrojó un valor de 1.06, este coeficiente representa el cambio esperado en la variable (y) por cada unidad de incremento en la variable (Área) mt2, manteniendo constante las demás variables predictoras. Así, por cada metro cuadrado adicional de área construida, el precio promedio de la vivienda aumentará en 1.06 millones COP. Esta variable es estadísticamente significativa para cualquier nivel de alfa, en otras palabras, la relación entre el área y el precio es sólida y confiable en términos estadísticos, y es poco probable que sea producto del azar.
β2, β3 y β4 que son los coeficientes de los estratos, arrojó un valor de 34.26, 71.96 y 231.38, lo que indica que, a medida que se aumenta el estrato del apartamento, manteniendo constante las demás variables predictoras, se incrementa el precio de la vivienda. Así, por cada cambio adicional en una unidad de estrato, el precio de la vivienda aumentará en promedio en 34.26, 71.96 ó 231.38 millones COP. Esta variable también es estadísticamente significativa para cualquier nivel de alfa.
β5 que es el coeficiente del número de habitaciones, arrojó un valor de -0.07, lo que indica que, a medida que se aumenta la cantidad de habitaciones en una unidad y manteniendo las demás variables constantes, disminuye el precio del apartamento en 0.07 millones COP, lo cual no tiene sentido, razón por la cual también el error estándar fue relativamente grande en comparación con el coeficiente, lo que indica una menor precisión en la estimación, esto sumado a que la variable resultó no ser significativa para ningún valor de alfa, dan argumentos para que no sea considerada en el modelo, dado que no es apta para explicar la variabilidad en el Precio en los apartamentos
β6 que es el coeficiente del número de parqueaderos, arrojó un valor de 35.70 lo que indica que, a medida que se aumenta la cantidad de parqueaderos en una unidad, aumenta en promedio el precio del apartamento en 35.70 millones COP, manteniendo todo lo demás constante, lo cual es correcto, dado que los compradores buscan adquirir viviendas que tengan parqueadero propio y aún más cuando se trata de apartamentos, debido a que prefieren que los visitantes también tengan donde ubicar sus vehículos. Esta variable también es estadísticamente significativa para cualquier nivel de alfa.
β7 que es el coeficiente del número de baños, arrojó un valor de 45.94 lo que indica que, a medida que se aumenta la cantidad de baños en una unidad, aumenta en promedio el precio del apartamento en 45.94 millones COP, manteniendo todo lo demás constante, lo cual también es correcto, dado que los compradores buscan adquirir viviendas que tengan suficientes baños para los habitantes. Esta variable también es estadísticamente significativa para cualquier nivel de alfa.
Sobre el ajuste del modelo se puede observar que:
Al verificar el coeficiente de bondad del modelo, se encuentra que, este es de 0.7914, indicando que las variables independientes del modelo, explican en conjunto un 79.14% de la variabilidad en el precio de la vivienda en millones COP. Así, si bien este coeficiente de determinación no es cercano a uno, si refleja que las variables explicativas tienen una alta influencia en la variable explicada, dado que explica un alto porcentaje de variación.
El error estándar residual fue de 78.29, lo que indica que en promedio los valores observados del Precio de la vivienda se desvían de los valores predichos por el modelo en 78.29 millones COP.
El estadístico F fue de 1051 con 7 grados de libertad para los predictores y 1938 grados de libertad para los residuales, establece que el modelo en general es altamente significativo.
El valor p del modelo es inferior al alfa del 0.05, lo que indica que es muy poco probable que el modelo no explique la variabilidad en los precios de los apartamentos de la zona sur de la ciudad, es decir, las variables predictoras en conjunto tienen un impacto significativo en la variable dependiente.
Los residuos que van de -878.34 a 595.63, indican que hay presencia de valores atípicos y que son significativos, por lo que se puede afectar la predicción del modelo.
La media de los cuadrados de los errores, MSE, fue de 6713.63, indica que, en promedio, el cuadrado de la diferencia entre los valores predichos y los observados es relativamente moderado, por lo que hay una mayor concentración de precios estables en los apartamentos.
La media de los errores absolutos entre las predicciones y los valores observados fue de 54.75, lo que establece que, en promedio, las predicciones del modelo se desvían de los valores observados en aproximadamente 54.75 millones COP.
La raíz del error cuadrático medio fue de 81.93 millones COP, siendo menor que en el modelo de las casas, lo que indica que al evaluar este indicador de ajuste, se aprecia una mejor calibración para el modelo de los apartamentos.
Sobre opciones de mejora del modelo se puede encontrar que:
Si bien el modelo no logra capturar toda la varianza del Precio de los apartamentos, si lo realiza en un alto porcentaje, de todas formas, se sugiere establecer pasos adicionales, para lograr mejorarlo, como por ejemplo, explorar la posibilidad de incluir otras variables que expliquen mejor la variación del Precio, por ejemplo el número del piso donde se encuentra ubicado, dado que a medida que aumenta el número del piso, la vivienda tiende a valorizarse más por contar con una mejor vista de la ciudad.
Otro factor a tener en cuenta es evaluar la presencia de multicolinealidad, dado que de presentarse, afectará el redimiento del modelo.
Adicional, se podría pensar en establecer modelos diferentes en función del estrato, dado que se observa que a medida que se incrementa el estrato, el Precio tiende a subir significativamente, por lo que resulta necesario descubrir otros mecanismos que influyen en el precio para cada estrato.
Finalmente, resulta relevante realizar un mejor tratamiento a los datos atípicos, de manera que no generen ruido en el modelo y así se puedan producir estimaciones más precisas.
Los supuestos se proceden a corroborar por medio de gráficos y test.
par(mfrow=c(2,2))
plot(modeloapartamentos, col="green", main="Modelo para Apartamentos")
Linealidad
Al observar la gráfica Residuals Vs Fitted, se encuentra que,la línea roja aunque no es muy precisa, se comporta como una recta a lo largo de los datos, sin embargo, al final parece convertirse en curva, por lo que se podría apreciar que el modelo no está capturando bien la relación entre las variables, en otras palabras, no se cumpliría con el supuesto, sin embargo, esto se corrobora con el test de Ramsey.
resettest(modeloapartamentos)
##
## RESET test
##
## data: modeloapartamentos
## RESET = 103.72, df1 = 2, df2 = 1936, p-value < 2.2e-16
El test de Ramsey, indica que el valor p es muy inferior al nivel de significancia del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, por tanto, la relación entre las variables no es lineal.
Para corregir la no linealidad, se debe contemplar la falta de otras variables no lineales que puedan interar en el modelo. También se pueden realizar transformaciones de variables o en definitiva correr un modelo no lineal.
Normalidad
Al observar la gráfica Q-Q Residuals, se encuentra que hay muchos datos que no se ajustan a la linea de normalidad, lo que demuestra que no se cumple con el supuesto. Asimismo, se presentan asimetrías por la ubicación lejana de los puntos respecto de la recta en las colas de la distribución. Para corroborar lo anterior, se procede a realizar el test de Shapiro y test de Anderson-Darling.
pruebat2 <- shapiro.test(modeloapartamentos$residuals)
pruebat2
##
## Shapiro-Wilk normality test
##
## data: modeloapartamentos$residuals
## W = 0.89484, p-value < 2.2e-16
andersont2 <- ad.test(modeloapartamentos$residuals)
print(andersont2)
##
## Anderson-Darling normality test
##
## data: modeloapartamentos$residuals
## A = 24.47, p-value < 2.2e-16
El test de Shapiro y el test de Anderson-Darling, indican que el valor p es muy inferior al nivel de significancia del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, por tanto, la distribución de los errores no es normal.
Teniendo en cuenta que no se cumple con el supuesto de normalidad, para corregir estro se podría considerar la transformación de la variable Precio, de manera que se aproxime a la distribución normal. También se podría pensar en correr un modelo más robusto, de manera que no requiere del cumplimiento de normalidad.
Homocedasticidad
Al observar la gráfica Scale-Location, se encuentra que los residuos no se distribuyen aleatoriamente a lo largo de la recta roja, puesto que se presenta una tendencia creciente a medida que aumentan las observaciones. En otras palabras, no se cumple con el supuesto. Para soportar lo anterior, se realiza el test de Breusch-Pagan.
lmtest::bptest(modeloapartamentos)
##
## studentized Breusch-Pagan test
##
## data: modeloapartamentos
## BP = 761.13, df = 7, p-value < 2.2e-16
El test de Breusch-Pagan, establece que el valor p es menor al alpha del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, y de esta manera concluir que la varianza de los errores no es constante.
Independencia
Para validar este supuesto se realiza el test de Durbin-Watson.
lmtest::dwtest(modeloapartamentos)
##
## Durbin-Watson test
##
## data: modeloapartamentos
## DW = 1.7444, p-value = 6.457e-09
## alternative hypothesis: true autocorrelation is greater than 0
Al observar el test de Durbin-Watson, se encuentra que el valor p es menor al alpha del 5%, por lo que existe evidencia estadística significativa para rechazar la hipótesis nula, y de esta manera concluir que los errores no son independientes. Así, no se cumple con el supuesto.
Para poder corregir el incumplimiento de este supuesto, es viable optar por utrilizar métodos de bootstrap o permutación, que sirven para hacer inferencias sin depender de la independencia. También se podría optar por incluir términos autorregresivos en el modelo para capturar la dependencia.
No Colinealidad
Para verificar la no presencia de multicolinealidad, se realia la prueba del factor de inflación de varianza.
vif(modeloapartamentos)
## GVIF Df GVIF^(1/(2*Df))
## Área 1.949529 1 1.396255
## Estrato 1.769788 3 1.099816
## Habitaciones 1.451996 1 1.204988
## Parqueaderos 1.436760 1 1.198649
## Baños 2.448783 1 1.564859
Se observa que en todas las variables explicativas el VIF es menor a 5, lo que indica que no hay problemas de multicolinealidad, en otras palabras, los coeficientes del modelo no deberían estar inflados debido a la correlación entre las variables independientes.
Para corroborar lo anterior, se calcula el índice de condición.
ols_eigen_cindex(modeloapartamentos)
## Eigenvalue Condition Index intercept Área Estrato4 Estrato5
## 1 5.63666488 1.000000 6.965282e-04 0.0032048389 0.00136687 0.0016032657
## 2 1.04139673 2.326500 3.752035e-04 0.0014651324 0.04847588 0.0008444593
## 3 1.00336068 2.370187 7.890538e-08 0.0001041102 0.03947146 0.0797218259
## 4 0.11803739 6.910370 1.929620e-02 0.6640179284 0.01919684 0.0816269235
## 5 0.09492845 7.705715 1.244880e-04 0.0317860895 0.07198171 0.0510408536
## 6 0.04969407 10.650226 9.894187e-03 0.1111496417 0.52623623 0.5423215600
## 7 0.04176867 11.616781 8.469129e-02 0.1568379270 0.03150444 0.0124949941
## 8 0.01414912 19.959347 8.849220e-01 0.0314343318 0.26176656 0.2303461179
## Estrato6 Habitaciones Parqueaderos Baños
## 1 0.001727985 8.876412e-04 0.0028322442 1.486755e-03
## 2 0.122476006 1.968391e-04 0.0001865475 1.882143e-04
## 3 0.025538859 9.453287e-06 0.0002382929 3.741580e-07
## 4 0.194793474 3.254425e-03 0.0009934767 1.807025e-03
## 5 0.120105685 6.848554e-03 0.8073345415 1.564787e-02
## 6 0.362759964 1.955549e-01 0.0481452460 1.014981e-01
## 7 0.014987543 7.593997e-02 0.0127709309 7.774808e-01
## 8 0.157610485 7.173082e-01 0.1274987204 1.018908e-01
Se observa que el índice de condición es mayor a 10 para 3 valores propios, por lo que se puede mencionar la presencia de colinealidad moderada, lo que podría afectar la estabilidad del modelo.
Para descartar lo anterior, se procede a realizar un análisis más detallado a través del análisis de descomposición de la varianza.
ols_vif_tol(modeloapartamentos)
## Variables Tolerance VIF
## 1 Área 0.5129445 1.949529
## 2 Estrato4 0.2288471 4.369731
## 3 Estrato5 0.2169465 4.609432
## 4 Estrato6 0.2592152 3.857799
## 5 Habitaciones 0.6887072 1.451996
## 6 Parqueaderos 0.6960102 1.436760
## 7 Baños 0.4083662 2.448783
Los resultados indican que los estratos tienen VIF más altos en comparación con las otras variables, por lo que Estrato podría tener una colinealidad moderada. Si bien, ninguno de los valores de VIF supera 5, lo que indica que no hay colinealidad significativa en el modelo, resulta necesario estudiar a la variable estrato, para determinar si su colinealidad afecta la interpretación de los resultados.
Ahora, para corregir la multicolinealidad se puede optar por eliminar las variables altamente correlacionadas, combinar estas variables para que sean una sola, aumentar el tamaño de la muestra para que los coeficientes sean más precisos o realizar análisis de componente principales para disminuir la dimensionalidad de los datos, utilizando las componentes en lugar de las variables iniciales del modelo.
Partiendo de una vivienda tipo apartamento, ubicado en el sur de la ciudad de Cali, que cuente con un área construida de 300 mt2, tenga 3 parqueaderos, 3 baños, 5 habitaciones y pertenezca al estrato 5 ó 6, los precios de los apartamentos serán de:
(predict(modeloapartamentos, list(Área = c(300, 300),
Parqueaderos = c(3, 3),
Baños = c(3, 3),
Habitaciones = c(5, 5),
Estrato = factor(c("5", "6"), levels = c("3", "4", "5", "6")) ), interval = "confidence", level = 0.95))
## fit lwr upr
## 1 578.6513 557.5878 599.7148
## 2 738.0713 716.8216 759.3210
Se establece que para las características del apartamento, si se encuentran en estrato 5, el precio promedio sería de 578 millones COP, mientras que si se encuentran en estrato 6, el precio promedio sería de 738 millones COP. La diferencia entre el precio promedio del apartamento para ambos es estratos es de 160 millones COP, que equivale a la diferencia entre los coeficientes de los estratos estimados en el modelo.
Ahora, al evaluar el precio mediante un intervalo de confianza del 95%, se encuentra que para el apartamento de estrato 5, el precio promedio oscila entre 557 y 599 millones COP, mientras que para el estrato 6, oscila en promedio entre 716 y 759 millones COP.
Teniendo en cuenta el crédito preaprobado de 850 millones COP, se plantean las siguientes viviendas como alternativa de compra.
oferta_apartamentos <- baseapartamentos %>%
dplyr::filter(Precio <= 850, Área >= 300, Parqueaderos >=3, Baños >= 3, Habitaciones >= 5, Estrato %in% c("5", "6")) %>%
head(5)
print(oferta_apartamentos)
## # A tibble: 2 × 12
## Id Zona Estrato Precio Área Parqueaderos Baños Habitaciones Tipo Barrio
## <dbl> <chr> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
## 1 7182 Zona … 5 730 573 3 8 5 Apar… guada…
## 2 7512 Zona … 5 670 300 3 5 6 Apar… semin…
## # ℹ 2 more variables: Longitud <dbl>, Latitud <dbl>
Para el caso de apartamentos, sólo hay 2 disponibles que cumplen con las características seleccionadas, estos son los identificados con Id 7182 y 7512, los cuales pertenecen al estrato 5 y se encuentran ubicados en los barrios Guadalupe y Seminario. En este caso ambos inmuebles están por debajo del presupuesto de 850 millones COP.
La oferta total de apartamentos que mejor se ajustan al presupuesto estipulado se puede encontrar en el siguiente mapa.
coordenadas2 <- data.frame(
lng2 = c(-76.55083, -76.50444, -76.51600, -76.55999, -76.55083),
lat2 = c(3.42500, 3.40861, 3.32967, 3.33649, 3.42500)
)
colores <- colorFactor(
palette = c("#00008B", "#FF4500", "#32CD32", "#FFD700"),
domain = baseapartamentos$Estrato
)
mapa4 <- leaflet(oferta_apartamentos) %>%
addTiles() %>%
addCircleMarkers(
lng = ~Longitud,
lat = ~Latitud,
color = ~colores(Estrato),
radius = 4,
popup = ~paste0(
"Precio: ", Precio, "<br>",
"Estrato: ", Estrato, "<br>",
"Área: ", Área, " m²<br>",
"Parqueaderos: ", Parqueaderos, "<br>",
"Baños: ", Baños, "<br>",
"Habitaciones: ", Habitaciones
)
) %>%
addPolylines(
lng = coordenadas2$lng,
lat = coordenadas2$lat,
color = "black",
weight = 2
) %>%
addLegend("bottomright", pal = colores, values = ~Estrato, title = "Estratos", opacity = 1)
mapa4
De acuerdo con la data suministrada, se pudo establecer que la ubicación de las viviendas en las zonas de la ciudad de Cali no era del todo adecuada, dado que se presentaban inconsistencias entre los barrios, coordenadas y la zona. Esto conlleva a que al realizar estimaciones no sean muy precisas y se termine generando cierto sesgo, que incluso puede contribuir significativamente a que no se cumplan los supuestos del modelo de regresión lineal múltiple. Asimismo, teniendo en cuenta que la variable Piso arrojó una importante cantidad de datos faltantes y que no fue tenida en cuenta en los modelos, resulta necesario calibrar el instrumento de medición, de manera que en futuras muestras se pueda contar con este atributo, para poder analizar su impacto en el precio de las viviendas. Esto sumado a que se encontraron algunas viviendas sin baños ni habitaciones, conlleva a pensar que se presentaron problemas al recolectar o registrar la data.
Dentro del análisis exploratorio de datos, se lograron apreciar relaciones significativas entre el Precio de las viviendas y su área construida, que tanto para casas como para apartamentos presentaron la correlación más fuerte, lo cual como era de esperarse, indica que, a mayor área, mayor será el valor de la vivienda.
Al ejecutar modelos de regresión lineal múltiple se pudo entender la importancia de la modelación estadística, para conocer las relaciones entre variables, sin embargo, se debe precisar que las salidas del modelo dependen de la calidad de la data en las variables de entrada, razón por la cual, los modelos fueron de ayuda para analizar asociaciones de atributos que explican el Precio, más no para realizar predicciones puntuales.
Continuando con los modelos de regresión, se evidenció que, el estrato es el que mayor impacto tiene en el precio de los inmuebles, dado que al pasar de un estrato a otro el precio en promedio se incrementa considerablemente, seguido del número de baños y parqueaderos, mientras que para el caso de las habitaciones, el resultado no fue estadísticamente significativo, dado que indicaba que un aumento en el número de habitación tiende en promedio a disminuir el precio de la vivienda, lo cual no tiene sentido en la realidad.
Por el lado de las casas, el coeficiente de determinación fue del 71,55%, lo que indica que el modelo con sus variables independientes logra explicar el 71,55% de la variabilidad en el Precio de las viviendas, no obstante, cabe precisar que, al evaluar los supuestos del modelo, la mayoría no se cumplieron, por lo que las estimaciones no tienden a ser muy precisas, sin embargo, al realizar predicciones mediante intervalos de confianza, se logró obtener un rango razonable para evaluar los precios de las casas.
Para explicar mejor el impacto de las características de las viviendas en el Precio asignado por sus propietarios, resulta necesario explorar otras posibilidades de modelación, como modelos no lineales, puesto que hay muchas variables que empíricamente se conocen influyen en el Precio y que no fueron tenidas en cuenta en este análisis, como por ejemplo, la antigüedad de la vivienda, la presencia de jardines para las casas o balcones para los apartamentos, establecer si se encuentra en conjunto residencial, la seguridad, las vías de acceso y cercanías a puntos de interés, entre otros, esto en razón de que los modelos con las variables predictoras evaluadas no lograron explicar la totalidad de la variabilidad del Precio.
Por el lado de los apartamentos, el grado de bondad del modelo fue del 79,14%, lo que indica que las variables regresoras explican una mayor variabilidad en el precio de los apartamentos que frente a las casas, sin embargo, en este modelo tampoco se cumplieron con los supuestos, por lo que las estimaciones no son muy precisas.
Ahora, al analizar ambos modelos (casas y apartamentos), se encuentra que el área impacta más en el precio para los apartamentos que para las casas, pues al mantener constante las demás variables, un aumento en un metro cuadrado para los apartamentos, sube en promedio más el precio que el mismo aumento de área en las casas, lo mismo pasa para los baños y parqueaderos. En consecuencia, el mercado en general valora más la distribución interna de los apartamentos, dado que, al tener limitaciones en el área, los demás atributos son los que valorizan a las viviendas, mientras que en las casas estos atributos impactan en menor proporción al precio, por lo que se concluye que en las casas deben existir otras variables que mejor expliquen el Precio.
En vista de lo anterior, se comprobó que la distribución del área en las casas es más dispersa que en los apartamentos en función del precio, lo que indica que la relación entre precio y área es más directa en las casas, lo cual es lógico, dado que en el mercado se espera que las casas tengan un mayor área y por tanto, los clientes estarían dispuesto a pagar más, mientras que en los apartamentos la relación no es tan directa, pues el factor que más influye en el Precio es el Estrato socioeconómico, por lo que a medida que se aumenta el nivel de estrato se valoriza más la vivienda.
También es importante destacar que al realizar la comparación de ambos modelos, no se parte de un tamaño de muestra equitativo. Por lo tanto, el modelo con una muestra más grande generalmente tendría una mejor capacidad de generalización, dado que está basado en un conjunto de datos más representativo de la población. Este es el caso del modelo de los apartamentos. Sin embargo, a pesar de tener un tamaño de muestra mayor, si no se cumplen los supuestos fundamentales del modelo de regresión, el modelo no será apto para generalizar. Esto limita su aplicabilidad y puede llevar a interpretaciones erróneas, independientemente del tamaño de la muestra.
Aún con lo anterior, al comparar el error cuadrático medio y el error absoluto medio, se encuentra que ambos son menores para el modelo de los apartamentos respecto al modelo de las casas, lo que indica que el modelo de los apartamentos tiene un mejor ajuste y predice con mayor precisión el precio del bien.
Por otra parte, para responder a las solicitudes acerca de la oferta de casas y apartamentos, para ubicar a los empleados de la compañía y sus familias, se encontró que, para las casas en la zona norte, hay 5 ofertas potenciales que se ajustan al presupuesto establecido en el crédito preaprobado de 350 millones COP, y que además son viviendas que cuentan los mejores estándares requeridos de Estrato, Área, Parqueaderos, Baños y Habitaciones. Por su parte, para los apartamentos en la zona sur, sólo se lograron encontrar dos viviendas que cumplieran con los mejores requisitos de atributos, aunque sobresale que están ofertados a un precio de venta menor que el presupuestado de 850 millones COP, producto del crédito preaprobado.
Finalmente, teniendo en cuenta los intervalos de confianza del 95% para estimar los precios de las viviendas, se observa que para la casa deseada para los empleados, el precio promedio oscila entre 282 y 344 millones COP si la casa está ubicada en estrato 4, destacando que en estas se contaría con los estándares mínimos requeridos, mientras que para el estrato 5, el precio promedio oscila entre 359 y 417 millones COP, por lo que el presupuesto asignado de 350 millones COP es viable para encontrar la casa deseada en la zona norte. Por su parte, para el apartamento deseado, el precio promedio está entre 557 y 599 millones COP para estrato 5, mientras que para estrato 6 oscila en promedio entre 716 y 759 millones COP, razón por la cual, el presupuesto