1. Problema
Realizar un modelo que permita estimar el precio de una vivienda dados sus atributos
Descripción variables base de datos
Zona: Registra la zona donde esta ubicada el inmueble esta puede ser: Zona Centro,Zona Norte,Zona Oeste,Zona Oriente,Zona Sur
Piso: Registra el piso ene l cual se ubica la vivienda
Estrato: Variable con escala de medición ordinal,los estrato de las viviendas son 3,4,5,6
Preciom: Precio de la vivienda
areaconstu: Area Construida
parqueaderos: Numero de parqueaeros de la vivienda
banios: Número de baños de la propiedad
Habitaciones: Número de habitaciones que posee la vivienda
Tipo: Tipo de la vivienda, casa o apartamento
Número total de registros iniciales 8320
Analisis de la base
summary(base_viviendas)
## 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
Analisis de datos faltantes.
Porcentaje de datos faltantes y patrones
porce<-apply(base_viviendas, 2, function(x) c(sum(is.na(x)), sum(is.na(x))/length(x)*100))
pander(porce[-1,])
| id | zona | piso | estrato | preciom | areaconst | parqueaderos |
|---|---|---|---|---|---|---|
| 0.03605 | 0.03605 | 31.7 | 0.03605 | 0.02403 | 0.03605 | 19.29 |
| banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|
| 0.03605 | 0.03605 | 0.03605 | 0.03605 | 0.03605 | 0.03605 |
Se evidencia que hay presencia de valores faltantes en todos los atributos sin embargo este es mas notorio en la variable piso y parqueaderos. Debemos tomar una medida con estas variables, analizando podemos determinar que los valores ausentes en la variable parqueader puede ser causados a partir de que el inmueble no posee ningun parqueadero por lo que su valor seria 0, sin embargo para piso no es valor que se permita determinar con base en otro atributo, por lo que lo marcaremos como null
#Medidas de tendencia central precio
base_viviendas <- base_viviendas %>%
mutate(
parqueaderos = ifelse(is.na(parqueaderos), 0, parqueaderos),
piso = ifelse(is.na(piso), "null", piso)
)
1.Realice un filtro a la base de datos e incluya sólo las ofertas de apartamentos.Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta.
Base1
Base1 <- base_viviendas %>%
filter(tipo == "Apartamento")
print(head(Base1, 3), width = Inf)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1212 Zona Norte 01 5 260 90 1 2
## 2 1724 Zona Norte 01 5 240 87 1 3
## 3 2326 Zona Norte 01 4 220 52 2 2
## habitaciones tipo barrio longitud latitud
## <dbl> <chr> <chr> <dbl> <dbl>
## 1 3 Apartamento acopi -76.5 3.46
## 2 3 Apartamento acopi -76.5 3.37
## 3 3 Apartamento acopi -76.5 3.43
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..
fig_area <- plot_ly(Base1, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = 'rgba(255, 182, 193, .9)', line = list(color = 'rgba(152, 0, 0, .8)', width = 2)))
fig_area <- fig_area %>%
layout(
title = "Precio vs. Área Construida",
xaxis = list(title = "Área Construida"),
yaxis = list(title = "Precio")
)
fig_area
library(plotly)
library(dplyr)
fig_area <- plot_ly(Base1, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers',
marker = list(size = 10, color = 'rgba(255, 182, 193, .9)', line = list(color = 'rgba(152, 0, 0, .8)', width = 2)))
fig_area <- fig_area %>%
layout(
title = "Precio vs. Área Construida",
xaxis = list(title = "Área Construida"),
yaxis = list(title = "Precio")
)
fig_area
numerical_data <- Base1 %>% select(preciom, areaconst, estrato, banios, habitaciones,parqueaderos)
# Calcular la matriz de correlación
cor_matrix <- cor(numerical_data, use = "complete.obs")
# Mostrar la matriz de correlación
print(cor_matrix)
## preciom areaconst estrato banios habitaciones parqueaderos
## preciom 1.0000000 0.8287437 0.6672717 0.7404732 0.2974940 0.6928227
## areaconst 0.8287437 1.0000000 0.5492273 0.7267377 0.4092708 0.6159072
## estrato 0.6672717 0.5492273 1.0000000 0.6155148 0.1778522 0.6043018
## banios 0.7404732 0.7267377 0.6155148 1.0000000 0.5006605 0.6187860
## habitaciones 0.2974940 0.4092708 0.1778522 0.5006605 1.0000000 0.2838982
## parqueaderos 0.6928227 0.6159072 0.6043018 0.6187860 0.2838982 1.0000000
ggpairs_plot <- ggpairs(Base1[, c("preciom", "areaconst", "estrato","parqueaderos", "banios", "habitaciones")],
title = "Matriz de Gráficos de Pares")
print(ggpairs_plot)
preciomLa matriz de correlación presentada muestra la relación entre el
precio de la vivienda (preciom) y varias otras
características como el área construida (areaconst), el
estrato (estrato), el número de baños
(banios), el número de habitaciones
(habitaciones) y el número de parqueaderos
(parqueaderos). A continuación, se detallan las principales
conclusiones:
areaconst) y Precio de la
Vivienda (preciom):estrato) y Precio de la Vivienda
(preciom):banios) y Precio de la
Vivienda (preciom):habitaciones) y
Precio de la Vivienda (preciom):parqueaderos) y
Precio de la Vivienda (preciom):3. Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = Base1)
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = Base1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1884.66 -53.65 -3.61 45.30 1028.85
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -211.02021 13.32957 -15.83 <2e-16 ***
## areaconst 2.19809 0.04186 52.52 <2e-16 ***
## estrato 51.05448 2.67830 19.06 <2e-16 ***
## habitaciones -40.10636 3.29257 -12.18 <2e-16 ***
## parqueaderos 55.39086 2.96114 18.71 <2e-16 ***
## banios 51.90627 3.02972 17.13 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 134.1 on 5094 degrees of freedom
## Multiple R-squared: 0.7852, Adjusted R-squared: 0.785
## F-statistic: 3723 on 5 and 5094 DF, p-value: < 2.2e-16
Modelo estimado: \[ \text{preciom} = -211.02021 + 2.19809 \times \text{areaconst} + 51.05448 \times \text{estrato} + -40.10636 \times \text{habitaciones} + 55.39086 \times \text{parqueaderos} + 51.90627 \times \text{banios} \]
4. Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).
par(mfrow=c(2, 2))
plot(modelo)
library(car)
## Loading required package: carData
##
## Attaching package: 'car'
## The following object is masked from 'package:purrr':
##
## some
## The following object is masked from 'package:dplyr':
##
## recode
## The following object is masked from 'package:boot':
##
## logit
qqPlot(modelo, main = "Q-Q Plot - Modelo 1")
## [1] 1563 4567
Test de Shapiro - Wilk
shapiro.test(sample(modelo$residuals, 5000))
##
## Shapiro-Wilk normality test
##
## data: sample(modelo$residuals, 5000)
## W = 0.815, p-value < 2.2e-16
La prueba de Shapiro-Wilk para la normalidad de los residuos arrojó un valor de prueba estadística (W) de 0.81452 y un valor p extremadamente pequeño (< 2.2e-16), lo que indica una fuerte evidencia en contra de la hipótesis nula de que los residuos siguen una distribución normal.
Varianza contante
lmtest::bptest(modelo)
##
## studentized Breusch-Pagan test
##
## data: modelo
## BP = 1418.5, df = 5, p-value < 2.2e-16
Dado que el valor p es menor que cualquier nivel de significancia comúnmente utilizado (como 0.05), podemos concluir que hay evidencia suficiente para rechazar la hipótesis nula de que la varianza de los residuos es constante (homocedasticidad).
No autocorrelación de errores
lmtest::dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.6004, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
La prueba de Durbin-Watson para la autocorrelación arrojó un estadístico de prueba (DW) de 1.6004 y un valor p extremadamente pequeño (p-value = 3.068e-07). Este valor p indica que hay evidencia significativa para rechazar la hipótesis nula de que no hay autocorrelación en los residuos.
Dado que el valor p es menor que cualquier nivel de significancia comúnmente utilizado (como 0.05), podemos concluir que hay evidencia suficiente para rechazar la hipótesis nula y aceptar la hipótesis alternativa de que existe autocorrelación positiva en los residuos.
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = Base1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1884.66 -53.65 -3.61 45.30 1028.85
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -211.02021 13.32957 -15.83 <2e-16 ***
## areaconst 2.19809 0.04186 52.52 <2e-16 ***
## estrato 51.05448 2.67830 19.06 <2e-16 ***
## habitaciones -40.10636 3.29257 -12.18 <2e-16 ***
## parqueaderos 55.39086 2.96114 18.71 <2e-16 ***
## banios 51.90627 3.02972 17.13 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 134.1 on 5094 degrees of freedom
## Multiple R-squared: 0.7852, Adjusted R-squared: 0.785
## F-statistic: 3723 on 5 and 5094 DF, p-value: < 2.2e-16
summary_modelo <- summary(modelo)
intercepto <- coef(modelo)["(Intercept)"]
diametro <- coef(modelo)["areaconst"]
altura <- ifelse("altura" %in% names(coef(modelo)), coef(modelo)["altura"], NA)
D2 <- ifelse("D2" %in% names(coef(modelo)), coef(modelo)["D2"], NA)
D3 <- ifelse("D3" %in% names(coef(modelo)), coef(modelo)["D3"], NA)
num_obs <- length(modelo$residuals)
r_squared <- summary_modelo$r.squared
r_squared_adj <- summary_modelo$adj.r.squared
aic <- AIC(modelo)
bic <- BIC(modelo)
log_lik <- logLik(modelo)
f_stat <- summary_modelo$fstatistic[1]
rmse <- sqrt(mean(residuals(modelo)^2))
resultados_modelo <- data.frame(
Coeficiente = c("Intercepto", "Diametro", "Altura","r_squared","aic","bic","r_squared_adj","rmse"),
Valor = c(intercepto, diametro,r_squared,aic,bic, altura,r_squared_adj,rmse)
)
resultados_modelo
## Coeficiente Valor
## 1 Intercepto -211.0202128
## 2 Diametro 2.1980884
## 3 Altura 0.7851646
## 4 r_squared 64448.2613757
## 5 aic 64494.0203464
## 6 bic NA
## 7 r_squared_adj 0.7849537
## 8 rmse 134.0410257
Diametro indica que, manteniendo constantes las demás
variables, un incremento de una unidad en el diámetro se asocia con un
incremento de 2.1980884 en el precio de la casa. Este coeficiente
positivo sugiere que el diámetro tiene un impacto positivo en el
precio.Altura sugiere que, manteniendo constantes las demás
variables, un incremento de una unidad en la altura está asociado con un
incremento de 0.7851646 en el precio de la casa. Este también es un
coeficiente positivo, indicando que la altura tiene un efecto positivo
en el precio.5.Realice una partición en los datos de forma aleatoria donde 70% sea un set para entrenar el modelo y 30% para prueba. Estime el modelo con la muestra del 70%. Muestre los resultados
set.seed(123)
train_indices <- sample(1:nrow(Base1), size = 0.7 * nrow(Base1))
# Crear sets de entrenamiento y prueba
train_set <- Base1[train_indices, ]
test_set <- Base1[-train_indices, ]
modelo_Train <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = train_set)
summary(modelo_Train)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = train_set)
##
## Residuals:
## Min 1Q Median 3Q Max
## -928.85 -49.18 -1.04 45.00 1007.19
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -186.1087 15.1043 -12.32 <2e-16 ***
## areaconst 2.4394 0.0505 48.31 <2e-16 ***
## estrato 46.1157 3.0715 15.01 <2e-16 ***
## habitaciones -43.1906 3.7814 -11.42 <2e-16 ***
## parqueaderos 48.8857 3.3333 14.67 <2e-16 ***
## banios 47.2279 3.4845 13.55 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 127.4 on 3564 degrees of freedom
## Multiple R-squared: 0.7995, Adjusted R-squared: 0.7992
## F-statistic: 2842 on 5 and 3564 DF, p-value: < 2.2e-16
6. Realice predicciones con el modelo anterior usando los datos de prueba (30%).
predicciones <- predict(modelo_Train, newdata = test_set)
resultados <- data.frame(Real = test_set$preciom, Prediccion = predicciones)
head(resultados)
## Real Prediccion
## 1 310 445.36252
## 2 320 371.69437
## 3 100 32.61646
## 4 175 161.16140
## 5 430 312.72031
## 6 130 151.30632
7. Calcule el error cuadrático medio, el error absoluto medio y el R2, interprete.
mse <- mean((resultados$Real - resultados$Prediccion)^2)
mae <- mean(abs(resultados$Real - resultados$Prediccion))
rss <- sum((resultados$Real - resultados$Prediccion)^2)
tss <- sum((resultados$Real - mean(resultados$Real))^2)
r2 <- 1 - (rss/tss)
mse
## [1] 22492.54
mae
## [1] 82.05853
r2
## [1] 0.7502097
-El MSE sugiere que algunos errores pueden ser grandes, lo cual podría estar influyendo negativamente en la precisión del modelo. - El MAE, siendo más interpretable y menos sensible a los valores atípicos, también muestra que, en promedio, el error es moderado pero podría ser relevante dependiendo de la escala de los precios de las viviendas.