1. Realice un filtro a la base de datos e incluya solo las ofertas de apartamentos. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta.
Solución:
El proceso comenzó con la carga de la base de datos vivienda utilizando la librería paqueteMODELOS. A continuación, se filtró la información para incluir únicamente los inmuebles de tipo apartamentos, según lo establecido en el enunciado previamente planteado.
#devtools::install_github("dgonxalex80/paqueteMODELOS", force = TRUE)
library(paqueteMODELOS)
data(vivenda)
vivienda = vivienda
vivienda = subset(vivienda, vivienda$tipo == "Apartamento")
kable(head(vivienda,3))
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1212 | Zona Norte | 01 | 5 | 260 | 90 | 1 | 2 | 3 | Apartamento | acopi | -76.51350 | 3.45891 |
| 1724 | Zona Norte | 01 | 5 | 240 | 87 | 1 | 3 | 3 | Apartamento | acopi | -76.51700 | 3.36971 |
| 2326 | Zona Norte | 01 | 4 | 220 | 52 | 2 | 2 | 3 | Apartamento | acopi | -76.51974 | 3.42627 |
Para comprobar la eficacia de la consulta, se realizó un análisis de frecuencia para la variable utilizada en el filtro (tipo), obteniéndo el siguiente resultado:
kable(summarytools::freq(vivienda$tipo))
| Freq | % Valid | % Valid Cum. | % Total | % Total Cum. | |
|---|---|---|---|---|---|
| Apartamento | 5100 | 100 | 100 | 100 | 100 |
| 0 | NA | NA | 0 | 100 | |
| Total | 5100 | 100 | 100 | 100 | 100 |
A partir de la tabla anterior, se confirma que las viviendas en el conjunto de datos son exclusivamente de tipo apartamento con 5100 registros, lo que valida la efectividad de la consulta.
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.
Solución:
La base de datos vivienda presenta la siguiente estructura:
vivienda$piso = as.numeric(vivienda$piso)
vivienda$estrato = as.character(vivienda$estrato)
st_options(
dfSummary.custom.2 =
expression(
paste(
"Q1 - Q3 :",
round(
quantile(column_data, probs = .25, type = 2,
names = FALSE, na.rm = TRUE), digits = 1
), " - ",
round(
quantile(column_data, probs = .75, type = 2,
names = FALSE, na.rm = TRUE), digits = 1
)
)
)
)
dfSummary(vivienda,
valid.col = FALSE,
style = "grid",
plain.ascii = FALSE,
headings = FALSE,
graph.magnif = 0.75,
tmp.img.dir = "/tmp"
)
| No | Variable | Stats / Values | Freqs (% of Valid) | Graph | Missing |
|---|---|---|---|---|---|
| 1 | id [numeric] |
Mean (sd) : 4284 (2449.8) min < med < max: 3 < 4158.5 < 8317 IQR (CV) : 4376.5 (0.6) Q1 - Q3 : 2179.5 - 6556.5 |
5100 distinct values | 0 (0.0%) |
|
| 2 | zona [character] |
1. Zona Centro 2. Zona Norte 3. Zona Oeste 4. Zona Oriente 5. Zona Sur |
24 ( 0.5%) 1198 (23.5%) 1029 (20.2%) 62 ( 1.2%) 2787 (54.6%) |
0 (0.0%) |
|
| 3 | piso [numeric] |
Mean (sd) : 4.6 (2.8) min < med < max: 1 < 4 < 12 IQR (CV) : 4 (0.6) Q1 - Q3 : 2 - 6 |
12 distinct values | 1381 (27.1%) |
|
| 4 | estrato [character] |
1. 3 2. 4 3. 5 4. 6 |
639 (12.5%) 1404 (27.5%) 1766 (34.6%) 1291 (25.3%) |
0 (0.0%) |
|
| 5 | preciom [numeric] |
Mean (sd) : 366.9 (289.2) min < med < max: 58 < 279 < 1950 IQR (CV) : 255 (0.8) Q1 - Q3 : 175 - 430 |
478 distinct values | 0 (0.0%) |
|
| 6 | areaconst [numeric] |
Mean (sd) : 112.8 (69.4) min < med < max: 35 < 90 < 932 IQR (CV) : 62 (0.6) Q1 - Q3 : 68 - 130 |
421 distinct values | 0 (0.0%) |
|
| 7 | parqueaderos [numeric] |
Mean (sd) : 1.6 (0.7) min < med < max: 1 < 1 < 10 IQR (CV) : 1 (0.5) Q1 - Q3 : 1 - 2 |
1 : 2298 (54.3%) 2 : 1584 (37.4%) 3 : 252 ( 6.0%) 4 : 88 ( 2.1%) 5 : 4 ( 0.1%) 6 : 2 ( 0.0%) 7 : 1 ( 0.0%) 10 : 2 ( 0.0%) |
869 (17.0%) |
|
| 8 | banios [numeric] |
Mean (sd) : 2.6 (1.1) min < med < max: 0 < 2 < 8 IQR (CV) : 1 (0.4) Q1 - Q3 : 2 - 3 |
0 : 14 ( 0.3%) 1 : 400 ( 7.8%) 2 : 2502 (49.1%) 3 : 1200 (23.5%) 4 : 635 (12.5%) 5 : 301 ( 5.9%) 6 : 39 ( 0.8%) 7 : 8 ( 0.2%) 8 : 1 ( 0.0%) |
0 (0.0%) |
|
| 9 | habitaciones [numeric] |
Mean (sd) : 3 (0.7) min < med < max: 0 < 3 < 9 IQR (CV) : 0 (0.2) Q1 - Q3 : 3 - 3 |
0 : 21 ( 0.4%) 1 : 49 ( 1.0%) 2 : 859 (16.8%) 3 : 3384 (66.4%) 4 : 714 (14.0%) 5 : 63 ( 1.2%) 6 : 8 ( 0.2%) 7 : 1 ( 0.0%) 9 : 1 ( 0.0%) |
0 (0.0%) |
|
| 10 | tipo [character] |
1. Apartamento | 5100 (100.0%) | 0 (0.0%) |
|
| 11 | barrio [character] |
1. valle del lili 2. la flora 3. santa teresita 4. ciudad jardín 5. pance 6. normandía 7. los cristales 8. el ingenio 9. el caney 10. la hacienda [ 279 others ] |
840 (16.5%) 267 ( 5.2%) 250 ( 4.9%) 221 ( 4.3%) 206 ( 4.0%) 150 ( 2.9%) 137 ( 2.7%) 128 ( 2.5%) 124 ( 2.4%) 108 ( 2.1%) 2669 (52.3%) |
0 (0.0%) |
|
| 12 | longitud [numeric] |
Mean (sd) : -76.5 (0) min < med < max: -76.6 < -76.5 < -76.5 IQR (CV) : 0 (0) Q1 - Q3 : -76.5 - -76.5 |
2018 distinct values | 0 (0.0%) |
|
| 13 | latitud [numeric] |
Mean (sd) : 3.4 (0) min < med < max: 3.3 < 3.4 < 3.5 IQR (CV) : 0.1 (0) Q1 - Q3 : 3.4 - 3.5 |
2449 distinct values | 0 (0.0%) |
De acuerdo con el resumen estadístico anterior, se observa que la base de datos contiene 722 registros (filas) y 13 variables (columnas). La caracterización de la base de datos es la siguiente:
a. Id: Variable de identificación.
b. Zona: Variable cualitativa nominal.
c. Piso: Variable cuantitativa discreta.
d. Estrato: Variable cualitativa ordinal.
e. Precio (millones): Variable cuantitativa continua.
f. Área construida: Variable cuantitativa continua.
g. Parqueaderos: Variable cuantitativa discreta.
h. Baños: Variable cuantitativa discreta.
i. Habitaciónes: Variable cuantitativa discreta.
j. Tipo: Variable cualitativa nominal.
k. Barrio: Variable cualitativa nominal.
l. Longitud y Latitud: Variables cuantitativas continuas.
Tambien, se verificó gráficamente la presencia de valores atípicos en las variables numericas. Esta evaluación visual permite identificar observaciones que se desvían significativamente del patrón general de los datos, lo que puede afectar la calidad del análisis general.
vivienda_num = vivienda[,c(3,5,6,7,8,9,12,13)]
par(mfrow = c(3, 3))
par(mar = c(1, 3, 2, 1))
for (i in seq_along(vivienda_num)) {
boxplot(vivienda_num[[i]], main = colnames(vivienda_num)[i],
col = "lightblue", las = 2, cex.axis = 0.8)
}
Se identificó que la mayoria de las variables numéricas presentan valores atípicos. Entre las variables, precio, área construida y longitud exhiben la mayor cantidad de valores atípicos, lo que sugiere que estos datos pueden tener una amplia variabilidad. En contraste, las variables piso, parqueaderos, baños, habitaciones y latitud presentan una menor cantidad de valores atípicos, indicando una distribución más homogénea en estas características.
Finalmente, se realizó un análisis exploratorio bivariado de datos para examinar la correlación entre el precio de la vivienda y las variables área construida, estrato, número de baños, número de habitaciones y zona de ubicación utilizando la libreria plotly. Los resultados obtenidos para la primera variable son los siguientes:
plot_ly(data = vivienda, x = ~areaconst, y = ~preciom, mode = "markers", type = "scatter")
round(cor(vivienda$areaconst, vivienda$preciom),4)
## [1] 0.8287
Al examinar la relación entre el precio de las viviendas y el área construida, se confirma la existencia de una asociación lineal positiva fuerte (82.87%), como se observa en el coeficiente de correlacion. Esto sugiere que, a medida que aumenta el área de las casas, también lo hace su precio. Se nota una mayor concentración de inmuebles con áreas inferiores a 250 \(m^{2}\) y precios por debajo de 1000 MM. Además, se identifican valores atípicos en propiedades con áreas superiores a 350 \(m^{2}\) y de otro lado cuando los precios son mayores a 1500 MM, lo cual podría atribuirse a factores no considerados en este análisis, como la antigüedad, la accesibilidad al transporte, el estado del inmueble, entre otros.
Para el análisis de la relación entre el precio y variables como el estrato, el número de baños, el número de habitaciones y la zona de ubicación, se desarrolló un gráfico interactivo. Este permite seleccionar la variable específica que se desea analizar, facilitando la visualización de los patrones en los datos. A continuación, se presenta dicho gráfico:
config_eje_x = function(var) {
if (is.numeric(vivienda[[var]])) {
list(title = var, tickmode = "linear", dtick = 1)
} else {
list(title = var)
}
}
fig = plot_ly(data = vivienda, x = ~estrato, y = ~preciom, type = 'box')
dropdown_buttons <- lapply(c('estrato', 'banios', 'habitaciones', 'zona'), function(var) {
list(
method = "update",
args = list(
list(x = list(vivienda[[var]])),
list(xaxis = config_eje_x(var))
),
label = var
)
})
fig = fig %>%
layout(
title = "Diagrama de Cajas y Bigotes - Variables Categoricas",
yaxis = list(title = "preciom"),
updatemenus = list(list(buttons = dropdown_buttons, x = 1.25, xanchor = "right", y = 1.25, yanchor = "top")),
margin = list(t = 120, b = 40, l = 60, r = 20)
)
fig
A partir del análisis anterior, se pueden extraer las siguientes conclusiones:
- Precio vs. Estrato: Existe una relación creciente entre el estrato y el precio de las viviendas. A medida que el estrato aumenta, también lo hace el precio. En los estratos 3, 4 y 5, esta relación se aproxima a ser lineal, con incrementos graduales en la media, mediana y rango intercuartílico (IQR). Sin embargo, en estos estratos se observa una mayor cantidad de valores atípicos altos, lo que genera una asimetría positiva y sugiere la existencia de muchas viviendas con precios más bajos. En el estrato 6, el precio es significativamente más alto, con una mediana de 610 MM y un IQR de 420 MM, y se presenta una menor cantidad de valores atípicos.
Para validar esta observación, se realizó un análisis de regresión simple donde el precio se consideró como la variable dependiente y el estrato como la variable independiente:
vivienda_e = vivienda[,c(4,5)]
vivienda_e$E4 = as.numeric(vivienda_e$estrato == 4)
vivienda_e$E5 = as.numeric(vivienda_e$estrato == 5)
vivienda_e$E6 = as.numeric(vivienda_e$estrato == 6)
modelo_e = lm(preciom ~ E4+E5+E6, data = vivienda_e)
summary(modelo_e)
##
## Call:
## lm(formula = preciom ~ E4 + E5 + E6, data = vivienda_e)
##
## Residuals:
## Min 1Q Median 3Q Max
## -574.41 -77.49 -23.98 38.06 1564.99
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 128.977 7.979 16.165 < 2e-16 ***
## E4 77.968 9.625 8.101 6.77e-16 ***
## E5 206.034 9.311 22.128 < 2e-16 ***
## E6 573.438 9.756 58.781 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 201.7 on 5096 degrees of freedom
## Multiple R-squared: 0.514, Adjusted R-squared: 0.5137
## F-statistic: 1796 on 3 and 5096 DF, p-value: < 2.2e-16
El p-value del estadístico F es < 2.2e-16, lo que indica una fuerte evidencia en contra de la hipótesis nula. Esto significa que al menos una de las variables independientes en el modelo tiene un efecto significativo sobre el precio de las viviendas, lo que valida la utilidad del modelo para predecir el precio en función del estrato socioeconómico.
- Precio vs. Número de Baños: Las viviendas sin baños muestran una sobrevaloración en comparación con el resto, con una mediana de 350 MM y un IQR de 420 MM. Para viviendas con entre 1 y 5 baños, se observa un aumento lineal en el precio, acompañado de una mayor dispersión debido a la presencia de valores atípicos. En el caso de viviendas con 6 a 8 baños, no se aprecia una relación clara, con medianas oscilando entre 750 MM y 1400 MM.
Para confirmar la asociación, se calculo la correlación de Pearson entre el número de baños y el precio de las viviendas, encontrando un valor de 0.7405, lo que sugiere una relación moderada entre estas variables.
round(cor(vivienda$banios, vivienda$preciom),4)
## [1] 0.7405
- Precio vs. Número de Habitaciones: El análisis mostró un patrón de incremento en los precios conforme aumenta el número de habitaciones, con algunas excepciones notables. Las viviendas sin habitaciones presentan un precio inusualmente alto, con una mediana de 330 MM y un IQR de 378 MM, lo que podría indicar la influencia de otras características no incluidas en el análisis. Para las viviendas con 2 a 4 habitaciones, se observa una alta cantidad de valores atípicos, lo que podría reflejar variaciones del mercado relacionadas con factores adicionales. Las viviendas con 5 a 6 habitaciones exhiben un rango de precios más amplio, sugiriendo una mayor diversidad en sus características o ubicaciones. Finalmente, las viviendas con 7 y 9 habitaciones, que aparecen como únicos registros en el gráfico, podrían señalar registros atípicos o menos comunes en el mercado.
Para confirmar la asociación, se calculo la correlación de Pearson entre el número de habitaciones y el precio de las viviendas, encontrando un valor de 0.2975, indicando una relación débil entre estas dos variables, por lo que podria excluirse del analisis de regresión lineal multiple.
round(cor(vivienda$habitaciones, vivienda$preciom),4)
## [1] 0.2975
- Precio vs. Zona: El análisis por zonas revela que la zona oeste ofrece las viviendas más costosas, con una mediana de 570 MM y un IQR de 515 MM. Las zonas norte y sur presentan un comportamiento similar, con una mediana de 250 MM y una alta presencia de valores atípicos. La zona centro, por su parte, muestra precios más bajos, con una mediana de 153 MM y un IQR de 120 MM, destacándose por la ausencia de valores atípicos, lo que sugiere una mayor homogeneidad en los precios. Finalmente, la zona oriente se caracteriza por tener los precios más bajos, con una mediana de 115 MM y un IQR de 51 MM, reflejando una menor variabilidad en comparación con las otras zonas.
Para corroborar estas observaciones, se realizó un análisis de regresión simple donde el precio fue considerado como la variable dependiente y la zona como la variable independiente:
vivienda_z = vivienda[,c(2,5)]
vivienda_z$Norte = as.numeric(vivienda_z$zona== "Zona Norte")
vivienda_z$Oeste = as.numeric(vivienda_z$zona == "Zona Oeste")
vivienda_z$Oriente = as.numeric(vivienda_z$zona == "Zona Oriente")
vivienda_z$Sur = as.numeric(vivienda_z$zona == "Zona Sur")
modelo_z = lm(preciom ~ Norte+Oeste+Oriente+Sur, data = vivienda_z)
summary(modelo_z)
##
## Call:
## lm(formula = preciom ~ Norte + Oeste + Oriente + Sur, data = vivienda_z)
##
## Residuals:
## Min 1Q Median 3Q Max
## -582.93 -141.29 -52.29 57.71 1452.71
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 186.58 50.20 3.717 0.000204 ***
## Norte 98.58 50.70 1.944 0.051906 .
## Oeste 481.34 50.78 9.479 < 2e-16 ***
## Oriente -33.99 59.12 -0.575 0.565415
## Sur 110.71 50.41 2.196 0.028140 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 245.9 on 5095 degrees of freedom
## Multiple R-squared: 0.2776, Adjusted R-squared: 0.277
## F-statistic: 489.3 on 4 and 5095 DF, p-value: < 2.2e-16
El p-value del estadístico F es < 2.2e-16, lo que indica una fuerte evidencia en contra de la hipótesis nula. Esto sugiere que al menos una de las zonas tiene un impacto significativo en el precio de las viviendas. En resumen, el modelo es estadísticamente relevante, lo que respalda su capacidad para predecir el precio de las viviendas en función de la ubicación geográfica (Centro, Norte, Oeste, Oriente, Sur).
Como resultado de este análisis exploratorio, se llevaron a cabo los siguientes pasos para solucionar los problemas de calidad detectados en el conjunto de datos.
Analisis = vivienda %>%
group_by(zona,estrato) %>%
summarise(
parqueaderos = round(median(parqueaderos, na.rm = TRUE), digits = 0),
Piso = round(median(piso, na.rm = TRUE), digits = 0)
)
datatable(Analisis, list(pageLength=10))
# Imputación de variable parqueaderos
vivienda = vivienda %>%
mutate(parqueaderos = case_when(
is.na(parqueaderos) & zona == "Zona Centro" ~ 1,
is.na(parqueaderos) & zona == "Zona Norte" & estrato == "3" ~ 1,
is.na(parqueaderos) & zona == "Zona Norte" & estrato == "4" ~ 1,
is.na(parqueaderos) & zona == "Zona Norte" & estrato == "5" ~ 1,
is.na(parqueaderos) & zona == "Zona Norte" & estrato == "6" ~ 2,
is.na(parqueaderos) & zona == "Zona Oeste" & estrato == "3" ~ 1,
is.na(parqueaderos) & zona == "Zona Oeste" & estrato == "4" ~ 1,
is.na(parqueaderos) & zona == "Zona Oeste" & estrato == "5" ~ 2,
is.na(parqueaderos) & zona == "Zona Oeste" & estrato == "6" ~ 2,
is.na(parqueaderos) & zona == "Zona Oriente" & estrato == "3" ~ 1,
is.na(parqueaderos) & zona == "Zona Oriente" & estrato == "4" ~ 1,
is.na(parqueaderos) & zona == "Zona Oriente" & estrato == "5" ~ 1,
is.na(parqueaderos) & zona == "Zona Oriente" & estrato == "6" ~ 3,
is.na(parqueaderos) & zona == "Zona Sur" & estrato == "3" ~ 1,
is.na(parqueaderos) & zona == "Zona Sur" & estrato == "4" ~ 1,
is.na(parqueaderos) & zona == "Zona Sur" & estrato == "5" ~ 1,
is.na(parqueaderos) & zona == "Zona Sur" & estrato == "6" ~ 2,
TRUE ~ parqueaderos
))
# Imputación de variable piso
vivienda = vivienda %>%
mutate(piso = case_when(
is.na(piso) & zona == "Zona Centro" & estrato == "3" ~ 4,
is.na(piso) & zona == "Zona Centro" & estrato == "4" ~ 8,
is.na(piso) & zona == "Zona Norte" & estrato == "3" ~ 4,
is.na(piso) & zona == "Zona Norte" & estrato == "4" ~ 4,
is.na(piso) & zona == "Zona Norte" & estrato == "5" ~ 5,
is.na(piso) & zona == "Zona Norte" & estrato == "6" ~ 4,
is.na(piso) & zona == "Zona Oeste" & estrato == "3" ~ 4,
is.na(piso) & zona == "Zona Oeste" & estrato == "4" ~ 3,
is.na(piso) & zona == "Zona Oeste" & estrato == "5" ~ 4,
is.na(piso) & zona == "Zona Oeste" & estrato == "6" ~ 5,
is.na(piso) & zona == "Zona Oriente" & estrato == "3" ~ 2,
is.na(piso) & zona == "Zona Oriente" & estrato == "4" ~ 4,
is.na(piso) & zona == "Zona Oriente" & estrato == "5" ~ 5,
is.na(piso) & zona == "Zona Sur" ~ 4,
TRUE ~ piso
))
vivienda = na.omit(vivienda)
gg_miss_var(vivienda)
vivienda = vivienda %>% mutate(Preciometro=round(preciom/areaconst,digits = 1))
vivienda = vivienda %>%
group_by(zona) %>%
filter(Preciometro >= quantile(Preciometro, 0.25) - 1.5 * IQR(Preciometro) &
Preciometro <= quantile(Preciometro, 0.75) + 1.5 * IQR(Preciometro)) %>%
ungroup()
vivienda$Preciometro = NULL
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).
Solución:
A partir de la base de datos vivienda, se estimó un modelo de regresión lineal múltiple con el precio como variable de respuesta (\(y\)) y las siguientes variables predictoras: área construida, número de parqueaderos, número de baños y estrato. La variable número de habitaciones no fue incluida en el modelo debido a su baja correlación lineal con el precio. Dado que el estrato es una variable categórica, se generaron variables indicadoras (dicotómicas) para representar adecuadamente esta característica en el modelo.
vivienda_m = vivienda[,c(4,5,6,7,8)]
vivienda_m$E4 = as.numeric(vivienda_m$estrato == 4)
vivienda_m$E5 = as.numeric(vivienda_m$estrato == 5)
vivienda_m$E6 = as.numeric(vivienda_m$estrato == 6)
modelo = lm(preciom ~ areaconst+parqueaderos+banios+E4+E5+E6, data = vivienda_m)
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + banios + E4 +
## E5 + E6, data = vivienda_m)
##
## Residuals:
## Min 1Q Median 3Q Max
## -990.88 -40.72 1.84 37.69 827.22
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -127.15594 5.95283 -21.361 < 2e-16 ***
## areaconst 2.13602 0.04107 52.014 < 2e-16 ***
## parqueaderos 70.18530 3.52097 19.934 < 2e-16 ***
## banios 25.76647 2.50079 10.303 < 2e-16 ***
## E4 35.43949 5.61342 6.313 2.97e-10 ***
## E5 59.24246 5.70979 10.376 < 2e-16 ***
## E6 186.82896 7.20346 25.936 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 115.3 on 4986 degrees of freedom
## Multiple R-squared: 0.8249, Adjusted R-squared: 0.8247
## F-statistic: 3914 on 6 and 4986 DF, p-value: < 2.2e-16
Con lo anterior, obtenemos la siguiente ecuación:
\(precio= -127.15594+2.13602(area)+70.18530(parqueaderos)+25.76647(baños)+35.43949(E4)+59.24246(E5)\\ +186.82896(E6)\)
El análisis de regresión múltiple sobre los datos de precios de las viviendas permite interpretar los siguientes coeficientes:
a. Intercepto (\(\beta_0\)):
b. Área construida (\(\beta_1\)):
c. Número de parqueaderos (\(\beta_2\)):
d. Número de baños (\(\beta_3\)):
e. Estrato 4 (\(\beta_4\)):
f. Estrato 5 (\(\beta_5\)):
g. Estrato 6 (\(\beta_6\)):
Por otro lado, el \(R^{2}\) del modelo es de 0.8249, lo que indica que aproximadamente el 82.49% de la variabilidad en los precios de las viviendas es explicada por las variables incluidas en el modelo. Este es un buen ajuste, sugiriendo que las variables seleccionadas son adecuadas para predecir el precio, aunque aún queda un 17.51% de la variabilidad sin explicar, lo que podría ser capturado por otras variables no incluidas en el algoritmo, como la antigüedad, la accesibilidad al transporte, el estado del inmueble, entre otros.
Para mejorar el ajuste del modelo, se pueden considerar varias estrategias adicionales que permitirán un análisis más completo y ajustado a la realidad del fenómeno estudiado:
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).
Solución:
La validación de los supuestos del modelo lineal comenzó con un análisis gráfico, que facilitó una evaluación visual de la idoneidad del modelo y permitió verificar los supuestos subyacentes. Este enfoque inicial es fundamental para identificar posibles problemas y asegurar la validez del modelo. Entre los gráficos comúnmente utilizados en este proceso se incluyen:
par(mfrow =c(2,2))
plot(modelo)
Procediendo con su interpretación:
| Supuestos | Análisis | Cumplimiento |
|---|---|---|
| Normalidad | En el Gráfico 2 (Q - Q Residuals) se aprecia una distribución no normal, ya que los puntos no siguen una disposición lineal con respecto a la diagonal que representa la concordancia entre los residuales estandarizados y los cuantiles teóricos. | No |
| Homocedasticidad | En el Gráfico 1 (Residuals Vs. Fitted), se nota un patrón creciente en los residuales a medida que avanzan los valores ajustados, contradiciendo el supuesto de una dispersión constante de los residuales. Esta observación se confirma de manera más clara en el Gráfico 3 (Scale-Location), donde se aprecia claramente el comportamiento mencionado. Por lo tanto, se concluye que el modelo exhibe heterocedasticidad. | No |
| Linealidad | Basando en el Gráfico 1 (Residuals Vs. Fitted), no se observa una relación lineal clara entre la variable dependiente y la independiente. Los residuos no se distribuyen de manera aleatoria alrededor de la línea horizontal en cero, y la curva de ajuste en rojo no sigue una línea perfectamente horizontal. Esto sugiere que el modelo no cumple adecuadamente con el supuesto de linealidad, lo que indica que la relación entre las variables podría no ser estrictamente lineal. | No |
| No autocorrelación | Dado que los datos no están temporalmente ordenados, no es posible validar este supuesto en primera instancia desde la perspectiva grafica. Por lo tanto, se descarta su evaluación en esta aproximación lineal | No |
| Outliers | En la Gráfica 4 (Residuals Vs. Leverage) se observa una gran cantidad de puntos con residuos estandarizados cercanos a 0 y valores de leverage pequeños, lo que indica observaciones bien ajustadas por el modelo. Sin embargo, también se aprecia la presencia significativa de valores atípicos, representados por puntos con residuos estandarizados grandes (positivos o negativos) y valores de leverage altos, lo que influye considerablemente en la calidad del ajuste del modelo. | No |
Para corroborar los análisis previos, se llevaron a cabo las pruebas de hipótesis respectivas para los supuestos de normalidad, homocedasticidad y no autocorrelación, tal como se describió anteriormente. Los resultados obtenidos a través de estas pruebas confirman las conclusiones derivadas del análisis gráfico. Los p-value obtenidos fueron aproximadamente 0, lo que conduce al rechazo de la hipótesis nula en cada caso, y por lo tanto, se acepta la hipótesis alternativa de la no normalidad, heterocedasticidad y autocorrelación.
Normalidad <- shapiro.test(modelo$residuals)
homocedasticidad <- lmtest::bptest(modelo)
autocorrelacion <- lmtest::dwtest(modelo)
resultados <- rbind(
c("Normalidad", Normalidad$method, format(Normalidad$p.value,
scientific = TRUE)),
c("Homocedasticidad", homocedasticidad$method, format(homocedasticidad$p.value,
scientific = TRUE)),
c("No Autocorrelación", autocorrelacion$method, format(autocorrelacion$p.value,
scientific = TRUE)))
colnames(resultados) <- c("Prueba", "Método", "Valor p")
kable(resultados)
| Prueba | Método | Valor p |
|---|---|---|
| Normalidad | Shapiro-Wilk normality test | 6.899206e-57 |
| Homocedasticidad | studentized Breusch-Pagan test | 1.664836e-317 |
| No Autocorrelación | Durbin-Watson test | 1.359676e-41 |
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.
Solución:
Se llevó a cabo la partición del dataset vivienda_m siguiendo la proporción recomendada para dividirlo en conjunto de entrenamiento y conjunto de prueba.
set.seed(123)
train = sample(1:4993,4993*0.7)
modelo_train = lm(preciom ~ areaconst+parqueaderos+banios+E4+E5+E6, data = vivienda_m, subset = train)
summary(modelo_train)
##
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + banios + E4 +
## E5 + E6, data = vivienda_m, subset = train)
##
## Residuals:
## Min 1Q Median 3Q Max
## -973.68 -41.35 1.01 38.62 806.80
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -131.12716 7.14680 -18.348 < 2e-16 ***
## areaconst 2.10202 0.04845 43.382 < 2e-16 ***
## parqueaderos 71.46340 4.16973 17.139 < 2e-16 ***
## banios 27.37152 3.00443 9.110 < 2e-16 ***
## E4 37.79319 6.81313 5.547 3.12e-08 ***
## E5 59.15508 6.93936 8.525 < 2e-16 ***
## E6 189.33788 8.65381 21.879 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 118.3 on 3488 degrees of freedom
## Multiple R-squared: 0.8224, Adjusted R-squared: 0.8221
## F-statistic: 2692 on 6 and 3488 DF, p-value: < 2.2e-16
Como resultado, se obtuvo el siguiente modelo:
\(precio= -131.12716+2.10202(area)+71.46340(parqueaderos)+27.37152(baños)+37.79319(E4)+59.15508(E5) \\ +189.33788(E6)\)
6. Realice predicciones con el modelo anterior usando los datos de prueba (30%).
Solución:
Utilizando el modelo ajustado previamente, se procedió a predecir los precios de las viviendas en el conjunto de prueba. Para facilitar la interpretación de los resultados, se generó una tabla que muestra de manera clara la relación entre el valor real de los precios, el valor predicho por el modelo y el error absoluto asociado a cada predicción. Esta visualización permite evaluar la precisión del modelo y examinar el desempeño de las predicciones en comparación con los valores reales.
predicciones = predict(object = modelo_train, newdata = vivienda_m[-train, ])
valores_reales = vivienda_m$preciom[-train]
resultados = data.frame(
Valor_Real = valores_reales,
Prediccion = round(predicciones,0),
Error_Absoluto = round(abs(valores_reales - predicciones),0)
)
datatable(resultados, list(pageLength=10))
7. Calcule el error cuadrático medio, el error absoluto medio y el R2, interprete.
Solución:
Para calcular las métricas solicitadas, se realizó el siguiente procedimiento:
MSE = mean((valores_reales - predicciones)^2)
MAE = mean(abs(valores_reales - predicciones))
SST = sum((valores_reales - mean(valores_reales))^2)
SSE = sum((valores_reales - predicciones)^2)
R2 = 1 - (SSE / SST)
resultados = data.frame(
Métrica = c("MSE (Error Cuadrático Medio)", "MAE (Error Absoluto Medio)", "R2"),
Valor = c(round(MSE, 3), round(MAE, 3), round(R2, 3))
)
kable(resultados, caption = "Métricas del Modelo con Validación cruzada")
| Métrica | Valor |
|---|---|
| MSE (Error Cuadrático Medio) | 11656.357 |
| MAE (Error Absoluto Medio) | 67.221 |
| R2 | 0.831 |
Interpretación:
Error Cuadrático Medio (MSE): El MSE es de aproximadamente 11,656.357 MM². Este valor indica que, en promedio, las predicciones del modelo se desvían en 107.96 MM de los valores reales. El MSE es una métrica que penaliza más severamente los errores grandes, ya que eleva las diferencias al cuadrado. Aunque proporciona una visión general del ajuste del modelo, su interpretación directa puede ser complicada debido a las unidades cuadráticas, lo que hace que no sea tan intuitivo. No obstante, un MSE más bajo generalmente sugiere un modelo con mejor capacidad predictiva.
Error Absoluto Medio (MAE): El MAE es de 67.221 MM, lo que significa que, en promedio, las predicciones del modelo se desvían en 67.221 MM de los precios reales. A diferencia del MSE, el MAE es una métrica más fácil de interpretar porque no eleva las diferencias al cuadrado, lo que la hace más intuitiva al expresar el error en las mismas unidades que los precios de las viviendas. El MAE indica la magnitud promedio del error sin considerar la dirección del mismo (es decir, si las predicciones son superiores o inferiores a los valores reales), lo que lo convierte en una métrica útil para evaluar el desempeño general del modelo en términos de precisión.
Coeficiente de Determinación (\(R^2\)): El coeficiente \(R^2\) de 0.831 sugiere que el modelo es capaz de explicar el 83.1% de la variabilidad observada en los precios de las viviendas, tomando en cuenta variables predictoras como el área construida, número de parqueaderos, número de baños y estrato. Un \(R^2\) cercano a 1 indica que el modelo tiene un buen ajuste, lo que implica que la mayoría de la variabilidad en los precios de las viviendas puede atribuirse a las variables incluidas en el modelo. Este alto valor de \(R^2\) demuestra que el modelo es bastante eficaz para capturar las relaciones entre las variables predictoras y el precio de las viviendas. Sin embargo, es importante considerar que un \(R^2\) alto no siempre implica que el modelo sea perfecto; aún pueden existir factores no considerados o errores que podrían mejorarse con ajustes adicionales o la inclusión de otras variables relevantes.