Este informe presenta el análisis de dos modelos predictivos enfocados en la estimación del precio de los apartamentos en función de sus características clave: área construida, estrato, número de cuartos, número de baños, parqueaderos, y la ubicación. Se utilizó una regresión lineal múltiple para realizar las predicciones, complementada con gráficos interactivos para explorar las relaciones entre las variables.
Las recomendaciones para mejorar el modelo se basan en los resultados del análisis de correlación, validación de los supuestos del modelo y la partición de los datos en conjunto de entrenamiento y prueba.
Se realizó un análisis exploratorio de datos utilizando gráficos interactivos. Se observó una correlación positiva significativa entre el área construida y el precio de los apartamentos. Sin embargo, el estrato y el número de cuartos no mostraron una relación tan fuerte. Los gráficos de dispersión y de correlación permiten visualizar estas relaciones y ayudan a guiar la selección de variables para el modelo predictivo.
library(dplyr)
library(plotly)
library(caret)
A continuación, se filtra la base de datos para incluir solo apartamentos:
apartments <- vivienda %>% filter(tipo == "Apartamento")
head(apartments, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst
## <dbl> <chr> <chr> <dbl> <dbl> <dbl>
## 1 1212 Zona N… 01 5 260 90
## 2 1724 Zona N… 01 5 240 87
## 3 2326 Zona N… 01 4 220 52
## # ℹ 7 more variables: parqueaderos <dbl>,
## # banios <dbl>, habitaciones <dbl>,
## # tipo <chr>, barrio <chr>, longitud <dbl>,
## # latitud <dbl>
table(apartments$tipo)
##
## Apartamento
## 5100
table(apartments$zona)
##
## Zona Centro Zona Norte Zona Oeste
## 24 1198 1029
## Zona Oriente Zona Sur
## 62 2787
Se realiza un análisis exploratorio de datos (EDA), donde se enfoca en la correlación entre las variables predictoras (área construida, estrato, baños, habitaciones y zona) y la variable de respuesta (precio por metro cuadrado).
plot_ly(apartments, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers', name = 'Area') %>%
add_trace(x = ~estrato, y = ~preciom, mode = 'markers', name = 'Estrato') %>%
add_trace(x = ~banios, y = ~preciom, mode = 'markers', name = 'Baños') %>%
add_trace(x = ~habitaciones, y = ~preciom, mode = 'markers', name = 'Habitaciones') %>%
add_trace(x = ~zona, y = ~preciom, mode = 'markers', name = 'Zona')
El grafico anterior, muestra la variación del precio según las diferentes variables predictoras. Las relaciones más directas pueden observarse entre el área construida y el precio, mientras que otras variables como el estrato o los baños podrían tener menor influencia.
cor(apartments %>% select(preciom, areaconst, estrato, banios, habitaciones))
## preciom areaconst estrato
## preciom 1.0000000 0.8287437 0.6672717
## areaconst 0.8287437 1.0000000 0.5492273
## estrato 0.6672717 0.5492273 1.0000000
## banios 0.7404732 0.7267377 0.6155148
## habitaciones 0.2974940 0.4092708 0.1778522
## banios habitaciones
## preciom 0.7404732 0.2974940
## areaconst 0.7267377 0.4092708
## estrato 0.6155148 0.1778522
## banios 1.0000000 0.5006605
## habitaciones 0.5006605 1.0000000
La matriz de correlación proporciona los coeficionetes de correlación lineal, que indican que tan fuertemente estám relacionadas las variables predictoras con el precio.
Se estimó un modelo de regresión lineal para predecir el precio en función de las variables seleccionadas.
model <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = apartments)
summary(model)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = apartments)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1699.03 -57.72 -0.67 48.59 1005.44
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) -278.47706 15.86822 -17.55
## areaconst 2.00464 0.04839 41.42
## estrato 56.24218 3.05907 18.39
## habitaciones -42.66447 3.80700 -11.21
## parqueaderos 90.42324 4.14278 21.83
## banios 54.84690 3.41824 16.05
## Pr(>|t|)
## (Intercept) <2e-16 ***
## areaconst <2e-16 ***
## estrato <2e-16 ***
## habitaciones <2e-16 ***
## parqueaderos <2e-16 ***
## banios <2e-16 ***
## ---
## Signif. codes:
## 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 137.7 on 4225 degrees of freedom
## (869 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
El modelo de regresión lineal múltiple muestra que las variables área construida, estrato, parqueaderos, baños y habitaciones son estadísticamente significativas para predecir el precio por metro cuadrado de los apartamentos, explicando un 78.45% de la variabilidad en los precios. Las interpretaciones de los coeficientes indican que, a mayor área, estrato, parqueaderos y baños, el precio aumenta, mientras que un mayor número de habitaciones sorprendentemente disminuye el precio. Cabe resaltar que, el modelo es robusto, aunque presenta un error estándar residual de 137.7.
par(mfrow = c(2, 2))
plot(model)
Se realizó transformaciones polinomiales en las variables predictoras para mejorar los supuestos del modelo.
apartments$parqueaderos[is.na(apartments$parqueaderos)] <- mean(apartments$parqueaderos, na.rm = TRUE)
apartments$habitaciones[is.na(apartments$habitaciones)] <- mean(apartments$habitaciones, na.rm = TRUE)
poly_model <- lm(preciom ~ poly(areaconst, 2) + poly(estrato, 2) +
poly(habitaciones, 2) + poly(parqueaderos, 2) +
poly(banios, 2), data = apartments)
summary(poly_model)
##
## Call:
## lm(formula = preciom ~ poly(areaconst, 2) + poly(estrato, 2) +
## poly(habitaciones, 2) + poly(parqueaderos, 2) + poly(banios,
## 2), data = apartments)
##
## Residuals:
## Min 1Q Median 3Q Max
## -861.96 -46.54 1.81 42.45 941.43
##
## Coefficients:
## Estimate Std. Error
## (Intercept) 366.944 1.726
## poly(areaconst, 2)1 11075.027 221.967
## poly(areaconst, 2)2 -2347.452 149.654
## poly(estrato, 2)1 4182.296 178.161
## poly(estrato, 2)2 1380.148 136.879
## poly(habitaciones, 2)1 -2060.427 148.455
## poly(habitaciones, 2)2 -1692.126 131.660
## poly(parqueaderos, 2)1 3071.457 172.094
## poly(parqueaderos, 2)2 401.182 129.092
## poly(banios, 2)1 3411.861 218.830
## poly(banios, 2)2 1759.143 143.278
## t value Pr(>|t|)
## (Intercept) 212.595 <2e-16 ***
## poly(areaconst, 2)1 49.895 <2e-16 ***
## poly(areaconst, 2)2 -15.686 <2e-16 ***
## poly(estrato, 2)1 23.475 <2e-16 ***
## poly(estrato, 2)2 10.083 <2e-16 ***
## poly(habitaciones, 2)1 -13.879 <2e-16 ***
## poly(habitaciones, 2)2 -12.852 <2e-16 ***
## poly(parqueaderos, 2)1 17.848 <2e-16 ***
## poly(parqueaderos, 2)2 3.108 0.0019 **
## poly(banios, 2)1 15.591 <2e-16 ***
## poly(banios, 2)2 12.278 <2e-16 ***
## ---
## Signif. codes:
## 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 123.3 on 5089 degrees of freedom
## Multiple R-squared: 0.8187, Adjusted R-squared: 0.8184
## F-statistic: 2298 on 10 and 5089 DF, p-value: < 2.2e-16
Este modelo tiene un buen ajuste, ya que el R-cuadrado es alto y todas las variables son estadísticamente significativas para predecir el precio del apartamento. Las relaciones entre las variables y el precio son no lineales, como lo indican los términos polinomiales de segundo grado.
Para evaluar el modelo de manera más robusta, se dividieron los datos en un conjunto de entrenamiento (70%) y uno de prueba (30%) para evaluar la capacidad predictiva del modelo.
Se ajustó un modelo de regresión lineal múltiple en el conjunto de entrenamiento usando las mismas variables predictoras, pero sin transformaciones polinomiales.
set.seed(123)
index <- createDataPartition(apartments$preciom, p = 0.7, list = FALSE)
train_set <- apartments[index, ]
test_set <- apartments[-index, ]
train_model <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = train_set)
summary(train_model)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = train_set)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1658.78 -54.08 -2.79 46.31 984.76
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) -331.43014 15.37368 -21.558
## areaconst 1.96282 0.05088 38.574
## estrato 65.24366 2.99065 21.816
## habitaciones -31.07287 3.83114 -8.111
## parqueaderos 88.61246 4.37727 20.244
## banios 46.08445 3.54114 13.014
## Pr(>|t|)
## (Intercept) < 2e-16 ***
## areaconst < 2e-16 ***
## estrato < 2e-16 ***
## habitaciones 6.86e-16 ***
## parqueaderos < 2e-16 ***
## banios < 2e-16 ***
## ---
## Signif. codes:
## 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 131.9 on 3566 degrees of freedom
## Multiple R-squared: 0.7851, Adjusted R-squared: 0.7848
## F-statistic: 2605 on 5 and 3566 DF, p-value: < 2.2e-16
El R-cuadrado del modelo lineal ajustado es 0.7851, lo que indica que el 78.51% de la variabilidad en el precio es explicada por las variables seleccionadas.
El error estándar residual es 131.9, lo que indica que, en promedio, las predicciones del modelo difieren en 131.9 unidades monetarias del valor real.
Todas las variables también resultaron significativas con p < 0.001, lo que muestra que tienen un impacto considerable en la predicción del precio.
Se realizaron predicciones utilizando el conjunto de prueba para evaluar la precisión del modelo.
predictions <- predict(train_model, newdata = test_set)
Para medir la calidad de las predicciones, se calcularon tres métricas clave de desempeño:
actuals <- test_set$preciom
mse <- mean((actuals - predictions)^2)
mae <- mean(abs(actuals - predictions))
rsq <- cor(actuals, predictions)^2
list(
MSE = mse,
MAE = mae,
R_squared = rsq
)
## $MSE
## [1] 16714.34
##
## $MAE
## [1] 79.60597
##
## $R_squared
## [1] 0.8161029
El modelo tiene un buen desempeño, con un R² alto y errores aceptables según el MSE y MAE. Si bien hay margen de mejora, las predicciones son razonablemente precisas, y el modelo captura gran parte de la variabilidad en el precio de los apartamentos.