library(paqueteMODELOS)
## Loading required package: boot
## Loading required package: broom
## Loading required package: GGally
## Loading required package: ggplot2
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
## Loading required package: gridExtra
## Loading required package: knitr
## Loading required package: summarytools
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
data("vivienda")
# Conteo de registros
Registros <- nrow(vivienda)
cat("Número total de registros en la base: ", Registros, "\n")
## Número total de registros en la base: 8322
# Filtrar la base de datos
base_filtrada <- vivienda[vivienda$tipo == "Casa" & vivienda$zona == "Zona Norte", ]
# Quitar registros nulos
base_filtrada <- na.omit(base_filtrada)
# Mostrar los primeros 3 registros
head(base_filtrada, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4460 Zona N… 02 4 625 355 3 5 5
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Conteo de registros
num_registros <- nrow(base_filtrada)
cat("Número total de registros en la base: ", num_registros, "\n")
## Número total de registros en la base: 254
# Resumen
tabla_resumen <- summary(base_filtrada[, c("preciom", "areaconst", "estrato", "banios", "habitaciones")])
tabla_resumen
## preciom areaconst estrato banios
## Min. : 89.0 Min. : 60.0 Min. :3.00 Min. :0.000
## 1st Qu.: 350.0 1st Qu.: 196.5 1st Qu.:4.00 1st Qu.:3.000
## Median : 450.0 Median : 275.5 Median :5.00 Median :4.000
## Mean : 499.6 Mean : 305.9 Mean :4.52 Mean :3.882
## 3rd Qu.: 600.0 3rd Qu.: 365.5 3rd Qu.:5.00 3rd Qu.:5.000
## Max. :1600.0 Max. :1440.0 Max. :6.00 Max. :9.000
## habitaciones
## Min. : 0.00
## 1st Qu.: 4.00
## Median : 4.00
## Mean : 4.87
## 3rd Qu.: 5.75
## Max. :10.00
Dentro de esta parte exploratoria se identifico que la base cuenta con 8.322 registros; al momento de aplicar el filtro en la zona Norte para el tipo de inmueble casa, estos disminuyen a 254 lo que corresponde al 3% de la base. Sobre las variables cuantitativas (Precio, área construida, estrato, baños y habitaciones) se realizó un análisis descriptivo donde se identifica los valores mínimos, promedios y máximos; esto permite a los interesados comprender el contexto del mercado sobre las casas que se ofertan en la zona norte de la ciudad.
# Gráfico de dispersión en 3D - 1
scatter3d_plot <- plot_ly(base_filtrada, x = ~areaconst, y = ~estrato, z = ~preciom,
type = "scatter3d", mode = "markers",
marker = list(size = 10, opacity = 0.5, color = ~banios),
text = ~paste("Zona: ", zona, "<br>Habitaciones: ", habitaciones))
scatter3d_plot <- scatter3d_plot %>% layout(title = "Correlación en 3D",
scene = list(xaxis = list(title = "Área Construida"),
yaxis = list(title = "Estrato"),
zaxis = list(title = "Precio")))
# Mostrar gráfico en 3D
scatter3d_plot
Dentro del primer gráfico de dispersión en 3D se representa la relación entre el precio de la casa, el área construida y el estrato. El color de los puntos en el gráfico está determinado por el número de baños. Se evidencia que las casas de estratos 4 y 5 son los inmuebles que cuentan con un mayor número de baños, y al ser mayor esta variable, el precio de la casa y el área construida va incrementando si el número de baños es mayor.
# Gráfico 3D interactivo - 2
scatter_3d <- plot_ly(base_filtrada, x = ~areaconst, y = ~banios, z = ~preciom,
color = ~factor(estrato), symbol = ~habitaciones,
colors = c("red", "blue", "green", "purple"),
symbols = c("circle", "square", "diamond", "cross"),
text = ~paste("Zona: ", zona))
scatter_3d <- scatter_3d %>% layout(title = "Relación entre Área Construida, Número de Baños, Precio y Estrato",
scene = list(xaxis = list(title = "Área Construida"),
yaxis = list(title = "Número de Baños"),
zaxis = list(title = "Precio")))
# Mostrar gráfico 3D
scatter_3d
## No trace type specified:
## Based on info supplied, a 'scatter3d' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter3d
## No scatter3d mode specifed:
## Setting the mode to markers
## Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Para esta segunda grafica el eje x representa el área construida, el eje y representa el número de baños, el eje z representa el precio, el color representa el estrato y el símbolo representa el número de habitaciones. En este caso se evidencia que a mayor número de habitaciones, mayor es el área construida y el precio del inmueble.
# Cargar paquete necesario para regresión lineal
library(stats)
# Estimar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base_filtrada)
# Mostrar resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = base_filtrada)
##
## Residuals:
## Min 1Q Median 3Q Max
## -761.11 -84.10 -16.36 52.22 925.67
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -245.62878 60.86958 -4.035 7.27e-05 ***
## areaconst 0.66444 0.06703 9.913 < 2e-16 ***
## estrato 85.58184 13.17690 6.495 4.51e-10 ***
## habitaciones 8.91428 7.14129 1.248 0.213
## parqueaderos 28.05949 6.77575 4.141 4.74e-05 ***
## banios 11.49860 9.51130 1.209 0.228
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 152.8 on 248 degrees of freedom
## Multiple R-squared: 0.5952, Adjusted R-squared: 0.587
## F-statistic: 72.92 on 5 and 248 DF, p-value: < 2.2e-16
Dentro del desarrollo del modelo de regresión lineal múltiple, se obtuvieron los siguientes resultados:
Coeficiente:
El coeficiente de área construida fue de 0.6644 sugiere que, manteniendo constantes las demás variables, un incremento de una unidad sobre esta variable se asocia con el aumento de $ 0.6644 en el precio de la vivienda.
El coeficiente de estrato fue de 85.581 sugiere que, manteniendo constantes las demás variables, un incremento de una unidad sobre esta variable se asocia con el aumento estimado de $ 85.58 en el precio de la vivienda.
El coeficiente de las demás variables como número de habitaciones, baños y parqueaderos indican el cambio estimado en el precio para un aumento de una unidad en cada una de ellas, manteniendo constantes las demás variables.
Significancia estadística:
Los valores p para cada coeficiente indican su significancia estadística; para este caso el intercepto, área construida, estrato y número de parqueaderos parecen ser estadísticamente significativos (p < 0.05), mientras que el número de habitaciones y número de baños no son estadísticamente significativos.
R2:
Define la proporción de la variabilidad en el precio que es explicada por el modelo. Para este informe se identificó que alrededor del 59.52% de la variabilidad en el precio se explica por las variables predictoras.
De acuerdo con lo anterior, las variables de área construida, estrato y número de parqueaderos parecen ser factores importantes para determinar el precio de la vivienda, mientras que el número de habitaciones y el número de baños no parecen ser tan relevantes en este contexto específico. Sin embargo, el modelo en su conjunto tiene un buen ajuste, explicando alrededor del 59.52% de la variabilidad en el precio de la vivienda.
# Validación de supuestos en el modelo de regresión lineal
# Residuos del modelo
residuos <- residuals(modelo)
# 1. Linealidad
# Gráfico de residuos contra valores ajustados
plot(modelo$fitted.values, residuos, main = "Linealidad: Residuos vs. Valores Ajustados",
xlab = "Valores Ajustados", ylab = "Residuos")
abline(h = 0, col = "red", lty = 2)
# 2. Homocedasticidad
# Gráfico de residuos estandarizados contra valores ajustados
residuos_estandarizados <- rstandard(modelo)
plot(modelo$fitted.values, residuos_estandarizados,
main = "Homocedasticidad: Residuos Estandarizados vs. Valores Ajustados",
xlab = "Valores Ajustados", ylab = "Residuos Estandarizados")
abline(h = 0, col = "red", lty = 2)
# 3. Normalidad de los Residuos
# Gráfico QQ de los residuos estandarizados
qqnorm(residuos_estandarizados, main = "Normalidad de los Residuos")
qqline(residuos_estandarizados, col = 2)
# 4. Independencia de los Residuos
# Gráfico de residuos contra índices
plot(residuos, main = "Independencia de los Residuos: Residuos vs. Índices")
Linealidad: En el gráfico de residuos contra valores ajustados, se observa una dispersión aleatoria de los puntos alrededor de la línea horizontal en cero. De acuerdo con lo anterior el modelo captura la verdadera relación entre las variables y no queda ningún patrón no explicado en los residuos. Este patrón aleatorio en el gráfico de residuos sugiere que la linealidad del modelo se mantiene y no hay violaciones significativas de la suposición de linealidad.
Homocedasticidad: En el gráfico de residuos estandarizados contra valores ajustados, se observa una dispersión constante de puntos alrededor de una línea horizontal.
Para este caso las gráficas de linealidad y homocedasticidad muestran patrones similares, generalmente es un resultado positivo en el análisis de regresión, ya que indica que tanto la relación entre las variables independientes y la variable dependiente (linealidad) como la constancia de la varianza de los errores (homocedasticidad) se mantienen.
Normalidad de los residuos: En el gráfico QQ de los residuos estandarizados, se evidencia que los puntos se alinean aproximadamente a la línea diagonal. Para este caso se evidencia que:
Desde -2 hasta 1: Esto indica que la mayoría de los residuos caen dentro de un rango razonable esperado para una distribución normal estándar. Los residuos están en línea con lo que se esperaría si siguieran una distribución normal.
A partir de uno ya no están sobre la línea: A medida que los puntos se alejan de la media de la distribución, los residuos comienzan a desviarse de lo que se esperaría en una distribución normal.
# Cargar paquete necesario para particionar los datos
library(caTools)
# Fijar semilla para reproducibilidad
set.seed(123)
# Partición aleatoria de los datos
split <- sample.split(base_filtrada$preciom, SplitRatio = 0.7)
# Crear conjuntos de entrenamiento y prueba
datos_entrenamiento <- subset(base_filtrada, split == TRUE)
datos_prueba <- subset(base_filtrada, split == FALSE)
# Estimar el modelo con la muestra del 70%
modelo_entrenamiento <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = datos_entrenamiento)
# Mostrar resumen del modelo con la muestra del 70%
summary(modelo_entrenamiento)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = datos_entrenamiento)
##
## Residuals:
## Min 1Q Median 3Q Max
## -761.06 -83.26 -15.26 51.13 914.93
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -256.00551 76.33663 -3.354 0.00097 ***
## areaconst 0.66619 0.07895 8.438 9.79e-15 ***
## estrato 89.24279 16.65332 5.359 2.51e-07 ***
## habitaciones 11.42352 8.96827 1.274 0.20437
## parqueaderos 38.68502 8.88601 4.353 2.23e-05 ***
## banios 1.77480 11.65424 0.152 0.87913
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 163 on 182 degrees of freedom
## Multiple R-squared: 0.605, Adjusted R-squared: 0.5941
## F-statistic: 55.75 on 5 and 182 DF, p-value: < 2.2e-16
Dentro del desarrollo del modelo de regresión lineal múltiple, para la partición definida se obtuvieron los siguientes resultados:
Coeficiente:
El coeficiente de área construida fue de 0.66619 sugiere que, manteniendo constantes las demás variables, un incremento de una unidad sobre esta variable se asocia con el aumento de $ 0.66619 en el precio de la vivienda.
El coeficiente de estrato fue de 89.24279 sugiere que, manteniendo constantes las demás variables, un incremento de una unidad sobre esta variable se asocia con el aumento estimado de $ 89.24 en el precio de la vivienda.
El coeficiente de las demás variables como número de habitaciones, baños y parqueaderos indican el cambio estimado en el precio para un aumento de una unidad en cada una de ellas, manteniendo constantes las demás variables.
Significancia estadística:
Los valores p para cada coeficiente indican su significancia estadística; para este caso el intercepto, área construida, estrato y número de parqueaderos parecen ser estadísticamente significativos (p < 0.05), mientras que el número de habitaciones y número de baños no son estadísticamente significativos.
R2:
Define la proporción de la variabilidad en el precio que es explicada por el modelo. Para este informe se identificó que alrededor del 60.5% de la variabilidad en el precio se explica por las variables predictoras.
De acuerdo con la partición realizada:
• Las variables de área construida y estrato parecen ser significativas en la predicción del precio de la vivienda.
• Las variables de habitaciones, parqueaderos y baños no parecen ser estadísticamente significativas en este modelo.
• El modelo explica alrededor del 60.5% de la variabilidad en el precio, según el R2.
# Realizar predicciones con el modelo utilizando los datos de prueba
predicciones <- predict(modelo_entrenamiento, newdata = datos_prueba)
# Comparar predicciones con los valores reales en los datos de prueba
resultados_predicciones <- data.frame(Valor_Real = datos_prueba$preciom, Prediccion = predicciones)
head(resultados_predicciones)
## Valor_Real Prediccion
## 1 420 542.4034
## 2 270 324.1974
## 3 220 154.6233
## 4 200 168.2692
## 5 335 427.6807
## 6 400 513.5669
Al realizar las predicciones con el modelo anterior se identifico:
• El dataframe muestra dos columnas, “Valor_Real” que contiene los valores reales de los precios de las viviendas en el conjunto de prueba y “Prediccion” que contiene las predicciones realizadas por el modelo.
• La interpretación de estos resultados se centra en comparar la columna “Valor_Real” con la columna “Prediccion”. Cuanto más cercanos estén los valores predichos a los valores reales, mejor será el desempeño del modelo en los datos de prueba.
# Calcular errores y R2
mse <- mean((resultados_predicciones$Valor_Real - resultados_predicciones$Prediccion)^2)
mae <- mean(abs(resultados_predicciones$Valor_Real - resultados_predicciones$Prediccion))
r2 <- 1 - (sum((resultados_predicciones$Valor_Real - resultados_predicciones$Prediccion)^2) /
sum((resultados_predicciones$Valor_Real - mean(resultados_predicciones$Valor_Real))^2))
# Mostrar resultados
cat("Error Cuadrático Medio (MSE):", mse, "\n")
## Error Cuadrático Medio (MSE): 15729.74
cat("Error Absoluto Medio (MAE):", mae, "\n")
## Error Absoluto Medio (MAE): 94.92225
cat("Coeficiente de Determinación (R2):", r2, "\n")
## Coeficiente de Determinación (R2): 0.4540579
Error Cuadrático Medio (MSE): El MSE es 15729.74. Este valor representa el promedio de los errores cuadráticos entre las predicciones y los valores reales en el conjunto de prueba. Cuanto menor sea el MSE, mejor será el rendimiento del modelo. En este caso, el MSE indica que, en promedio, los errores cuadráticos entre las predicciones y los valores reales son de aproximadamente 15729.74 unidades cuadradas en la escala de precios.
Error Absoluto Medio (MAE): El MAE es 94.92225. Este valor representa el promedio de las diferencias absolutas entre las predicciones y los valores reales. En este caso, el MAE indica que, en promedio, las predicciones tienen un error absoluto de aproximadamente 94.92 unidades en la escala de precios.
Coeficiente de Determinación (R2): El R2 es 0.4540579. Este valor representa la proporción de la variabilidad en la variable de respuesta (precio) que es explicada por el modelo. Un R2 más cercano a 1 indica un mejor ajuste del modelo. En este caso, el R2 sugiere que alrededor del 45.41% de la variabilidad en los precios de las viviendas es explicada por las variables predictoras incluidas en el modelo.
En resumen, el modelo muestra un rendimiento moderado en la predicción de precios de viviendas, con una capacidad para explicar alrededor del 45.41% de la variabilidad observada en los precios. Aunque el modelo tiene un rendimiento significativo, aún hay margen para mejoras, especialmente en la reducción del error cuadrático medio y del error absoluto medio para una predicción más precisa de los precios de las viviendas.