Actividad 2

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

Primeros 3 registros

apartamentos=subset(vivienda, tipo=="Apartamento")

kable(head(apartamentos, 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

Conteo por tipo de vivienda

#Tabla de Conteo de Apartamentos
table(apartamentos$tipo)
## 
## Apartamento 
##        5100

Valores únicos de tipo de vivienda

unique(apartamentos$tipo)
## [1] "Apartamento"

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

#Eliminamos los datos con NA
apartamentos <- na.omit(apartamentos)

# Selección de columnas relevantes para el análisis
datos <- apartamentos %>% select(preciom, areaconst, estrato, parqueaderos, banios, habitaciones, zona)
summary(datos)
##     preciom       areaconst        estrato       parqueaderos       banios     
##  Min.   :  58   Min.   : 40.0   Min.   :3.000   Min.   :1.000   Min.   :0.000  
##  1st Qu.: 220   1st Qu.: 75.0   1st Qu.:4.000   1st Qu.:1.000   1st Qu.:2.000  
##  Median : 300   Median : 96.0   Median :5.000   Median :1.000   Median :2.000  
##  Mean   : 390   Mean   :117.1   Mean   :4.887   Mean   :1.548   Mean   :2.752  
##  3rd Qu.: 450   3rd Qu.:135.0   3rd Qu.:6.000   3rd Qu.:2.000   3rd Qu.:3.000  
##  Max.   :1900   Max.   :932.0   Max.   :6.000   Max.   :7.000   Max.   :7.000  
##   habitaciones       zona          
##  Min.   :0.000   Length:3182       
##  1st Qu.:3.000   Class :character  
##  Median :3.000   Mode  :character  
##  Mean   :3.023                     
##  3rd Qu.:3.000                     
##  Max.   :7.000
# Gráfico de dispersión Precio vs Area
plot_area_precio <- plot_ly(datos, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
                            marker = list(size = 10, color = 'rgba(152, 0, 0, .8)', line = list(color = 'rgba(152, 0, 0, 1.0)', width = 2)))

# Agregar el título y etiquetas
plot_area_precio <- plot_area_precio %>% 
  layout(
    title = list(text = "Relación entre Precio y Área Construida"),
    xaxis = list(title = "Área Construida (m2)"),
    yaxis = list(title = "Precio (Millones de Pesos)")
  )

# Precio vs Estrato
plot_precio_estrato <- plot_ly(datos, x = ~factor(estrato), y = ~preciom, type = 'box', boxpoints = 'all') %>%
  layout(title = 'Distribución del Precio por Estrato',
         xaxis = list(title = 'Estrato'),
         yaxis = list(title = 'Precio (Millones de Pesos)'))

# Precio vs Número de Baños
plot_precio_banios <- plot_ly(datos, x = ~factor(banios), y = ~preciom, type = 'box', boxpoints = 'all') %>%
  layout(title = 'Distribución del Precio por Número de Baños',
         xaxis = list(title = 'Número de Baños'),
         yaxis = list(title = 'Precio (Millones de Pesos)'))

# Precio vs Número de Habitaciones
plot_precio_habitaciones <- plot_ly(datos, x = ~factor(habitaciones), y = ~preciom, type = 'box', boxpoints = 'all') %>%
  layout(title = 'Distribución del Precio por Número de Habitaciones',
         xaxis = list(title = 'Número de Habitaciones'),
         yaxis = list(title = 'Precio (Millones de Pesos)'))

# Precio vs Zona
plot_precio_zona <- plot_ly(datos, x = ~zona, y = ~preciom, type = 'box', boxpoints = 'all') %>%
  layout(title = 'Distribución del Precio por Zona',
         xaxis = list(title = 'Zona'),
         yaxis = list(title = 'Precio (Millones de Pesos)'))

# Precio vs Parqueaderos
plot_precio_parqueaderos <- plot_ly(datos, x = ~parqueaderos, y = ~preciom, type = 'box', boxpoints = 'all') %>%
  layout(title = 'Distribución del Precio Número de Parqueaderos',
         xaxis = list(title = 'Parqueaderos'),
         yaxis = list(title = 'Precio (Millones de Pesos)'))

# Mostrar gráficos
plot_area_precio
plot_precio_estrato
plot_precio_banios
plot_precio_habitaciones
plot_precio_zona
plot_precio_parqueaderos
# Crear la matriz de pares
ggpairs(datos,
        title = "Matriz de Pares: Correlación entre Precio de la Vivienda y Variables Seleccionadas",
        aes(color = zona, alpha = 0.5))
## Warning in cor(x, y): the standard deviation is zero
## Warning in cor(x, y): the standard deviation is zero
## Warning in cor(x, y): the standard deviation is zero
## Warning in cor(x, y): the standard deviation is zero
## Warning in cor(x, y): the standard deviation is zero
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Análisis

  • Preciom vs areaconst: Existe una fuerte correlación positiva (0.829), lo que indica que a medida que aumenta el área construida, el precio de la vivienda también tiende a aumentar. Esto es coherente con la expectativa de que las viviendas más grandes suelen ser más costosas.

  • Preciom vs estrato: Hay una correlación positiva moderada (0.667), sugiriendo que las viviendas en estratos más altos tienden a tener precios más altos.

  • Preciom vs baños: La correlación es alta (0.740), lo que indica que el número de baños está relacionado positivamente con el precio de la vivienda. Esto podría reflejar que viviendas con más baños suelen ser más costosas.

  • Preciom vs habitaciones: La correlación es moderada (0.297), indicando que el número de habitaciones tiene una relación más débil con el precio en comparación con otras variables como el área construida o el número de baños.

  • Preciom vs zona: La relación varía según la zona, pero en general, se observa que ciertas zonas tienen precios más altos que otras, siendo los apartamentos de la zona Oeste de mayor valor, lo cual es esperado dado que la ubicación es un factor determinante en el valor de las viviendas.

  • Preciom vs parqueaderos: el resultado de la correlación es alta, según lo esperado, porque que la vivienda que tenga parqueadero es un factor diferencial en el precio.

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 de Regresión Lineal Multiple

# Estimación del modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = apartamentos)

# Resumen del modelo
summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = apartamentos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1609.23   -55.44    -0.01    47.99   963.98 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -285.9869    17.5604  -16.29   <2e-16 ***
## areaconst       1.9061     0.0549   34.72   <2e-16 ***
## estrato        52.5560     3.4642   15.17   <2e-16 ***
## habitaciones  -35.3350     4.2623   -8.29   <2e-16 ***
## parqueaderos  100.3163     4.9734   20.17   <2e-16 ***
## banios         53.5608     3.8771   13.81   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 133.5 on 3176 degrees of freedom
## Multiple R-squared:  0.7823, Adjusted R-squared:  0.7819 
## F-statistic:  2282 on 5 and 3176 DF,  p-value: < 2.2e-16

Al interpretar el modelo utilizando todas las variables, observamos que el intercepto es negativo (-278). En la práctica, un intercepto negativo puede carecer de una interpretación directa, especialmente cuando algunas variables no pueden ser cero en la realidad. En este caso, la baja correlación entre el precio y el número de habitaciones sugiere que esta variable podría no ser relevante para el modelo y se recomienda considerarla para su exclusión.

Interpretación de los Coeficientes

Intercepto (-286): El intercepto de -286 millones de pesos representa el valor estimado del precio cuando todas las demás variables (área construida, estrato, número de parqueaderos y número de baños) son cero. En la práctica, este valor puede no tener una interpretación directa, ya que es poco realista que un inmueble tenga cero metros cuadrados de área construida o pertenezca a un estrato cero. Este valor negativo podría indicar que hay otros factores no modelados que afectan el precio cuando las variables predictoras son bajas,

Área Construida (1,9): Cada metro cuadrado adicional de área construida está asociado con un incremento de 1.9 millones de pesos en el precio del inmueble, manteniendo constantes las demás variables. Este coeficiente es estadísticamente significativo (p < 2e-16), lo que indica que el área construida tiene un impacto considerable en el precio de las viviendas, lo cual es lógico, ya que más espacio suele traducirse en un mayor valor.

Estrato (52.55): Un aumento de una unidad en el estrato socioeconómico está asociado con un incremento de 52.55 millones de pesos en el precio del inmueble, manteniendo constantes las demás variables. Este coeficiente es también estadísticamente significativo (p < 2e-16), sugiriendo que vivir en un estrato más alto, que generalmente implica mejores servicios y una mejor ubicación, aumenta significativamente el valor del inmueble.

Número de Parqueaderos (100.31): Cada parqueadero adicional está asociado con un aumento de 100.31 millones de pesos en el precio del inmueble, manteniendo constantes las demás variables. Este coeficiente, estadísticamente significativo (p < 2e-16), indica que la disponibilidad de parqueaderos es un factor importante en la determinación del precio de una vivienda, lo cual es coherente con la creciente demanda por estacionamientos, especialmente en zonas urbanas.

Número de Baños (53.56): Cada baño adicional está asociado con un aumento de 53.56 millones de pesos en el precio del inmueble, manteniendo constantes las demás variables. Este coeficiente es significativo (p < 2e-16), lo que sugiere que el número de baños también contribuye de manera positiva al precio, reflejando la importancia de la comodidad y la funcionalidad en la valoración de un inmueble.

Número de Habitaciones (-35.33):Un aumento de una habitación está asociado con una disminución de 35.33 millones de pesos en el precio, manteniendo constantes las demás variables. Aunque este coeficiente es significativo (p < 2e-16), un efecto negativo sobre el precio de las habitaciones es inusual y está asociado a que la correlación del precio de aparamento es muy baja con respecto al número de habitaciones.

Interpretación del R²

𝑅² = El valor de 0.7823 indica que aproximadamente el 78.23% de la variabilidad en el precio de la vivienda es explicada por el modelo que incluye el área construida, estrato, número de habitaciones, parqueaderos y baños.

R² Ajustado = 0.77819: El número de predictores en el modelo, es ligeramente menor pero muy similar al R², lo que indica que las variables seleccionadas no están añadiendo ruido innecesario al modelo.

Dado los resultados del modelo de regresión, algunas sugerencias para ajustar y mejorar el modelo podrían ser:

  • Revisar la Significancia y Coherencia de las Variables: Habitaciones (-35.33), el coeficiente negativo y significativo para el número de habitaciones es inesperado, ya que normalmente se esperaría que más habitaciones aumenten el valor de la vivienda. Este resultado podría indicar que hay colinealidad entre las variables (por ejemplo, entre el número de habitaciones y el área construida). Se Podría Verificar Colinealidad y reformular la variable, interactuar el número de habitaciones con otra variable como el área construida.

  • Evaluar la Inclusión del Intercepto: El intercepto negativo sugiere que cuando todas las variables predictoras son cero, el precio predicho es negativo, lo que no tiene sentido práctico. Entonces se dendría que forzar el Intercepto a cero.

  • Interacciones entre Variables: Las interacciones entre variables como el área construida y el número de habitaciones o entre estrato y el número de parqueaderos podrían capturar mejor la variabilidad en los precios.

  • Variables Cualitativas: Variables como la zona podrían ser útiles para capturar efectos espaciales que el estrato solo no puede captar.

  • Evaluar la Transformación de Variables a Transformación Logarítmica: la variable areaconst también muestra una distribución sesgada hacia la derecha, lo que sugiere que una transformación logarítmica podría ser útil.

  • Análisis de Residuos: Realizar un análisis más detallado de los residuos (normalidad, heterocedasticidad) para aseguranos de que el modelo cumpla con los supuestos de regresión.

  • Validación cruzada (Cross-Validation): Para asegurarnos de que el modelo generaliza bien y no está sobreajustado a los datos de entrenamiento.

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).

A continuación, se muestran las pruebas de cada supuesto:

- Linealidad: La relación entre las variables independientes y la variable dependiente debe ser lineal.

# 1. Verificación de Linealidad
plot(fitted(modelo), residuals(modelo), main = "Residuals vs Fitted")
abline(h = 0, col = "red")

Aunque hay un cierto grado de alineación alrededor de la línea cero, el patrón observado en la gráfica sugiere que el supuesto de linealidad puede no estar completamente satisfecho para todos los valores ajustados. La curva sugiere que puede haber una relación no lineal que no está siendo capturada por el modelo actual.

- Independencia de los errores: Los residuos deben ser independientes entre sí. Se practica la prueba de Durbin-Watson.

# 2. Prueba de Durbin-Watson para independencia
dwtest(modelo)
## 
##  Durbin-Watson test
## 
## data:  modelo
## DW = 1.5868, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0

Indica que los residuos están correlacionados positivamente, lo que significa que un error positivo en un período tiende a ser seguido por otro error positivo, y lo mismo ocurre con los errores negativos. Esto puede ser problemático porque viola el supuesto de independencia de los errores, lo cual puede afectar la validez de los resultados del modelo.

- Homoscedasticidad: La varianza de los residuos debe ser constante a lo largo de todos los valores de las variables independientes.

# 3. Verificación de Homoscedasticidad
plot(fitted(modelo), sqrt(abs(residuals(modelo))), main = "Scale-Location")
abline(h = 0, col = "red")

Se observa un patrón en forma de abanico donde la dispersión de los residuos parece aumentar a medida que aumentan los valores ajustados (fitted values). Este patrón es un indicio de heterocedasticidad, es decir, la varianza de los errores no es constante a lo largo de los valores predichos por el modelo

- Normalidad de los residuos: Los residuos del modelo deben seguir una distribución normal.

# 4. Verificación de Normalidad de los Residuos
qqnorm(residuals(modelo))
qqline(residuals(modelo), col = "red")

La presencia de puntos alejados de la línea recta en las colas sugiere que los residuos presentan distribución no normal, con posibles valores atípicos o outliers que podrían estar afectando el modelo.

- Ausencia de multicolinealidad: No debe haber una alta correlación entre las variables independientes.

vif(modelo)
##    areaconst      estrato habitaciones parqueaderos       banios 
##     2.518858     1.680141     1.421734     2.207342     2.927053

Los resultados de los VIF sugieren que no hay problemas serios de multicolinealidad en las variables independientes del modelo. Esto significa que las estimaciones de los coeficientes de regresión son confiables y no están distorsionadas por la correlación entre las variables predictoras.

Sugerencias para Ajuste del Modelo:

  • Transformación de Variables: Como ya se mencionó, algunas variables podrían beneficiarse de una transformación logarítmica para mejorar la linealidad y la homoscedasticidad.
  • Identificar y eliminar outliers extremos puede ayudar a mejorar la normalidad de los residuos.
  • Utilizar validación cruzada para evaluar la estabilidad de los resultados del modelo sin depender estrictamente de los supuestos de normalidad y homocedasticidad.

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).

# Semilla para reproducibilidad
set.seed(123) 

# Indice aleatorio para el 70% de los datos
train_index <- sample(seq_len(nrow(apartamentos)), size = 0.7 * nrow(apartamentos))

# Conjuntos de entrenamiento y prueba
train_data <- datos[train_index, ]
test_data <- datos[-train_index, ]

# Contar elementos en cada conjunto
num_train <- nrow(train_data)
num_test <- nrow(test_data)

# Mostrar resultados
cat("Número de elementos en el conjunto de entrenamiento:", num_train, "\n")
## Número de elementos en el conjunto de entrenamiento: 2227
cat("Número de elementos en el conjunto de prueba:", num_test, "\n")
## Número de elementos en el conjunto de prueba: 955
# Estimar el modelo de regresión lineal
modeloTrain <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = train_data)

# Mostrar el resumen del modelo
summary(modeloTrain)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = train_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1206.30   -52.70     0.72    47.73   949.70 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -275.85441   20.87286 -13.216  < 2e-16 ***
## areaconst       2.11600    0.06812  31.062  < 2e-16 ***
## estrato        49.66599    4.08581  12.156  < 2e-16 ***
## habitaciones  -35.53463    5.10337  -6.963 4.37e-12 ***
## parqueaderos   93.05787    5.98705  15.543  < 2e-16 ***
## banios         50.82708    4.64058  10.953  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 132.5 on 2221 degrees of freedom
## Multiple R-squared:  0.791,  Adjusted R-squared:  0.7905 
## F-statistic:  1681 on 5 and 2221 DF,  p-value: < 2.2e-16

6. Realice predicciones con el modelo anterior usando los datos de prueba (30%).

# Predicciones con los datos de prueba
predicciones <- predict(modeloTrain, newdata = test_data)

# Extraer los valores reales del conjunto de prueba
valores_reales <- test_data$preciom

# Data frame para comparar
comparacion <- data.frame(
  PrecioReal = valores_reales,
  PrecioPrediccion = predicciones
)

# Ver las primeras comparaciones
head(comparacion)
##   PrecioReal PrecioPrediccion
## 1        220        214.00766
## 2        320        383.33087
## 3        420        559.91076
## 4        170        163.78733
## 5         78         30.59933
## 6       1130        899.51209

7. Calcule el error cuadrático medio, el error absoluto medio y el R2, interprete.

# Error absoluto medio (MAE)
mae <- mean(abs(valores_reales - predicciones))

# Error cuadrático medio (RMSE)
rmse <- sqrt(mean((valores_reales - predicciones)^2))

# Coeficiente de Determinación (R²)
ss_total <- sum((valores_reales - mean(valores_reales))^2)
ss_residual <- sum((valores_reales - predicciones)^2)
r2 <- 1 - (ss_residual / ss_total)

# Mostrar métricas
cat("Error Absoluto Medio:", mae, "\n")
## Error Absoluto Medio: 81.80488
cat("Error Cuadrático Medio):", rmse, "\n")
## Error Cuadrático Medio): 136.8376
cat("R²:", r2, "\n")
## R²: 0.7561123
  • Error Absoluto Medio: Las predicciones del modelo se desvían en 81.80 millones del precio real.
  • RMSE (Error Cuadrático Medio): El modelo tiene un error cuadrático medio de 136.84 millones en promedio.
  • : Indica el modelo explica aproximadamente el 75.6% de la variabilidad en los precios de las viviendas.