Fase 1. Carga de Datos

#install.packages("devtools") # solo la primera vez
#devtools::install_github("centromagis/paqueteMODELOS", force =TRUE)
# Carga Paquetes
#install.packages("leaflet")

library(paqueteMETODOS) # Datos
library(dplyr)          # Manipulación de datos
library(ggplot2)        # Graficos
library(plotly)         # Gráficos interactivos
library(leaflet)        # Mapas
library(car)            # Para VIF (multicolinealidad)
library(lmtest)         # Prueba de Breusch-Pagan

Exploración de los Datos:

#install.packages("DT")  # Instalar el paquete
library(DT)  # Cargar la librería
data("vivienda")

# Mostrar los primeros registros en una tabla interactiva
datatable(head(vivienda), options = list(pageLength = 5, scrollX = TRUE))

Estructura y Resumen Estadistico de los Datos:

library(knitr)
library(tibble)

# Convertir `str()` en un formato de tabla
df_info <- tibble(
  Variable = names(vivienda),
  Tipo = sapply(vivienda, class)
)

kable(df_info, caption = "Estructura del DataFrame")
Estructura del DataFrame
Variable Tipo
id numeric
zona character
piso character
estrato numeric
preciom numeric
areaconst numeric
parqueaderos numeric
banios numeric
habitaciones numeric
tipo character
barrio character
longitud numeric
latitud numeric
#install.packages("Hmisc")
library(Hmisc)
describe(vivienda)
## vivienda 
## 
##  13  Variables      8322  Observations
## --------------------------------------------------------------------------------
## id 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     8319        3     8319        1     4160     4160     2773    416.9 
##      .10      .25      .50      .75      .90      .95 
##    832.8   2080.5   4160.0   6239.5   7487.2   7903.1 
## 
## lowest :    1    2    3    4    5, highest: 8315 8316 8317 8318 8319
## --------------------------------------------------------------------------------
## zona 
##        n  missing distinct 
##     8319        3        5 
##                                                                            
## Value       Zona Centro   Zona Norte   Zona Oeste Zona Oriente     Zona Sur
## Frequency           124         1920         1198          351         4726
## Proportion        0.015        0.231        0.144        0.042        0.568
## --------------------------------------------------------------------------------
## piso 
##        n  missing distinct 
##     5684     2638       12 
##                                                                             
## Value          1     2     3     4     5     6     7     8     9    10    11
## Frequency    860  1450  1097   607   567   245   204   211   146   130    84
## Proportion 0.151 0.255 0.193 0.107 0.100 0.043 0.036 0.037 0.026 0.023 0.015
##                 
## Value         12
## Frequency     83
## Proportion 0.015
## --------------------------------------------------------------------------------
## estrato 
##        n  missing distinct     Info     Mean  pMedian      Gmd 
##     8319        3        4    0.928    4.634      4.5    1.142 
##                                   
## Value          3     4     5     6
## Frequency   1453  2129  2750  1987
## Proportion 0.175 0.256 0.331 0.239
## 
## For the frequency table, variable is rounded to the nearest 0
## --------------------------------------------------------------------------------
## preciom 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     8320        2      539        1    433.9    372.5    326.7      121 
##      .10      .25      .50      .75      .90      .95 
##      145      220      330      540      870     1200 
## 
## lowest :   58   62   65   69   70, highest: 1850 1900 1940 1950 1999
## --------------------------------------------------------------------------------
## areaconst 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     8319        3      652        1    174.9    150.5    135.7       57 
##      .10      .25      .50      .75      .90      .95 
##       60       80      123      229      350      450 
## 
## lowest :   30   35   40   42   43, highest: 1440 1500 1586 1600 1745
## --------------------------------------------------------------------------------
## parqueaderos 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     6717     1605       10    0.846    1.835      1.5    1.039        1 
##      .10      .25      .50      .75      .90      .95 
##        1        1        2        2        3        4 
##                                                                       
## Value          1     2     3     4     5     6     7     8     9    10
## Frequency   3155  2475   520   384    68    68    18    17     4     8
## Proportion 0.470 0.368 0.077 0.057 0.010 0.010 0.003 0.003 0.001 0.001
## 
## For the frequency table, variable is rounded to the nearest 0
## --------------------------------------------------------------------------------
## banios 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     8319        3       11    0.935    3.111        3    1.525        1 
##      .10      .25      .50      .75      .90      .95 
##        2        2        3        4        5        6 
##                                                                             
## Value          0     1     2     3     4     5     6     7     8     9    10
## Frequency     45   496  2946  1993  1456   890   314   107    48    15     9
## Proportion 0.005 0.060 0.354 0.240 0.175 0.107 0.038 0.013 0.006 0.002 0.001
## 
## For the frequency table, variable is rounded to the nearest 0
## --------------------------------------------------------------------------------
## habitaciones 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     8319        3       11     0.87    3.605      3.5      1.4        2 
##      .10      .25      .50      .75      .90      .95 
##        2        3        3        4        5        7 
##                                                                             
## Value          0     1     2     3     4     5     6     7     8     9    10
## Frequency     66    59   926  4097  1729   679   318   173   138    83    51
## Proportion 0.008 0.007 0.111 0.492 0.208 0.082 0.038 0.021 0.017 0.010 0.006
## 
## For the frequency table, variable is rounded to the nearest 0
## --------------------------------------------------------------------------------
## tipo 
##        n  missing distinct 
##     8319        3        2 
##                                   
## Value      Apartamento        Casa
## Frequency         5100        3219
## Proportion       0.613       0.387
## --------------------------------------------------------------------------------
## barrio 
##        n  missing distinct 
##     8319        3      436 
## 
## lowest : 20 de julio      3 de julio       acopi            agua blanca      aguablanca      
## highest: zona norte los   zona oeste       zona oriente     zona residencial zona sur        
## --------------------------------------------------------------------------------
## longitud 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     8319        3     2928        1   -76.53   -76.53   0.0193   -76.55 
##      .10      .25      .50      .75      .90      .95 
##   -76.55   -76.54   -76.53   -76.52   -76.50   -76.50 
## 
## lowest : -76.5892 -76.5888 -76.5874 -76.5873 -76.5853
## highest: -76.465  -76.4648 -76.4644 -76.464  -76.463 
## --------------------------------------------------------------------------------
## latitud 
##        n  missing distinct     Info     Mean  pMedian      Gmd      .05 
##     8319        3     3679        1    3.418    3.417  0.04911    3.351 
##      .10      .25      .50      .75      .90      .95 
##    3.365    3.381    3.416    3.452    3.477    3.486 
## 
## lowest : 3.333   3.33308 3.33324 3.33333 3.33367
## highest: 3.49659 3.49666 3.49684 3.497   3.4977 
## --------------------------------------------------------------------------------

Conversión de datos categoricos a numericos: Variable: piso.

Se transforma la variable categorica piso a numerica.

# Convertir piso a numerico. Mas adelante se apreciara.

vivienda$piso <- as.numeric(vivienda$piso)

Visualización de Datos Faltantes:

#install.packages("naniar")
library(naniar)
p <- vivienda %>%
  gg_miss_var() +
  theme_classic() +
  labs(title = "Datos Faltantes por Variable",
       x = "Variables",
       y = "Número de Datos Faltantes",
       fill = "Faltante") +
  scale_fill_manual(values = c("red", "blue")) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 12),  # Tamaño de fuente en eje X
    axis.text.y = element_text(size = 12),  # Tamaño de fuente en eje Y
    axis.title = element_text(size = 14, face = "bold"),  # Tamaño y estilo de títulos de ejes
    plot.title = element_text(size = 16, face = "bold", hjust = 0.5)  # Título centrado y en negrita
  )

# Convertir en interactivo
ggplotly(p)

Desarrollo del Ejercicio: Vivienda 1 - Casa en Zona Norte

Paso 1.

Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?)

library(knitr)
base1 <- vivienda %>%
  filter(tipo == "Casa", zona == "Zona Norte")

# Mostrar los primeros 3 registros con formato de tabla
kable(head(base1, 3), caption = "Primeros 3 Registros - Casas en Zona Norte")
Primeros 3 Registros - Casas en Zona Norte
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud
1209 Zona Norte 2 5 320 150 2 4 6 Casa acopi -76.51341 3.47968
1592 Zona Norte 2 5 780 380 2 3 3 Casa acopi -76.51674 3.48721
4057 Zona Norte 2 6 750 445 NA 7 6 Casa acopi -76.52950 3.38527
# Mapa con Leaflet para verificar ubicación
leaflet(base1) %>%
  addTiles() %>%
  addCircleMarkers(
    ~longitud, ~latitud, 
    color = "red", 
    popup = ~paste("ID:", id, "<br>Precio:", preciom, "millones")
  )
base1 <- base1 %>%
  filter(!is.na(latitud) & !is.na(longitud))  # Elimina filas con NA
base1$latitud <- as.numeric(base1$latitud)  # Asegura que sean numéricos
base1$longitud <- as.numeric(base1$longitud)

Verificación de las ubicaciones.

Para verificar que las ubicaciones esten correctas, se toma un punto de la visualización de las ubicaciones de la zona norte que este ubicada en otra zona y se verifica mediante la verificaciòn tanto en el set de datos como una ubicación individual.

library(leaflet)

# Crear un data frame con la coordenada
punto <- data.frame(
  longitud = -76.54594,
  latitud = 3.33308
)

# Generar el mapa con un marcador en la coordenada especificada
leaflet(punto) %>%
  addTiles() %>%
  addMarkers(~longitud, ~latitud, popup = "Ubicación específica")

En este caso la coordenada consultada es la del ID 6906 la cual esta ubicada en el sur de la ciudad, pero en el set de datos indica que es un registro de la zona norte, Despues de verificar los datos de longitud y latitud, se puede comprobar que para una gran cantidad de registros, la ubicación no corresponde a la zona norte de la ciudad lo que nos dice que no podemos usar estas variables para hacer el analisis.

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

# Gráficos entre precio y variables relevantes
p1 <- ggplot(vivienda, aes(x = areaconst, y = preciom)) +
  geom_point(color = "grey") +
  labs(title = "Precio vs Área Construida",
        x = "Area Construida",
        y = "Precio en Millones") +
  theme_classic()

p2 <- ggplot(vivienda, aes(x = estrato, y = preciom)) +
  geom_boxplot(fill = "white", color = "black") +
  labs(title = "Precio vs Estrato",
        x = "Estrato",
        y = "Precio en Millones") +
  theme_classic()

p_banios <- ggplot(vivienda, aes(x = factor(banios), y = preciom)) +
  geom_boxplot(fill = "white", color = "black") +
  labs(title = "Distribución del Precio según Número de Baños",
       x = "Número de Baños",
       y = "Precio en Millones") +
  theme_classic()

p_habitaciones <- ggplot(vivienda, aes(x = factor(habitaciones), y = preciom)) +
  geom_boxplot(fill = "white", color = "black") +
  labs(title = "Distribución del Precio según Número de Habitaciones",
       x = "Número de Habitaciones",
       y = "Precio en Millones") +
  theme_classic()

p_zona <- ggplot(vivienda, aes(x = zona, y = preciom)) +
  geom_boxplot(fill = "white", color = "black") +
  labs(title = "Distribución del Precio según la Zona",
       x = "Zona",
       y = "Precio en Millones") +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))


# Convertir gráficos a interactivos
ggplotly(p1)
ggplotly(p2)
ggplotly(p_banios)
ggplotly(p_habitaciones)
ggplotly(p_zona)

Interpretación de los resultados:

  1. La gran densidad de los datos del precio respecto al area construida se ubican hasta 500 metros cuadrados y pueden llegar hasta casi 2000 millones el costo del inmueble.

  2. Para el caso de los precios respecto al estrato se puede observar en la grafica de cajas que la tendencia de medias tiende a aumentar, sin embargo cada uno de los casos presenta una gran cantidad de outlier que muestran precios elevados lejos de los datos centrados.

  3. En el caso del precio respecto al numero de baños podemos notar que desde la cantidad 6 hasta el 10 los precios y medias se presentan sobre simiares rangos de precios. Sin que sea concluyente, este grafico puede darnos a entender que el numero de baños puede representar datos outlier de los precios respecto al estrato y area construida. Ademas hay que tener en cuenta que los datos con numero de baños cero, pueden ser los datos faltantes del dataset, estos serian tratados.

  4. Con el numero de habitaciones respecto a los precios se presenta el caso de que las viviendas de tres muestran varios datos outlier, con precios elevados y en gran cantidad. Por otra parte, existen inmuebles de mas de 5 habitaciones que pueden tener precios de aquellas cuales tienen 2, lo que indica que el numero de habitaciones no podria ser una variable predictora que aporte en gran medida al precio.

  5. La relación de zonas puede ser una predictora bastante interesante, ya que se puede observar que las zonas norte y sur presentan similares rangos de precio en cambio la zona oeste supera estos valores, lo que nos indica que esta variable en si misma puede ser represenativa.

Paso 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 R Cuadrado y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

# Modelo de regresión para Casas - Zona Norte
modelo1 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base1)
summary(modelo1)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -784.29  -77.56  -16.03   47.67  978.61 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -238.17090   44.40551  -5.364 1.34e-07 ***
## areaconst       0.67673    0.05281  12.814  < 2e-16 ***
## estrato        80.63495    9.82632   8.206 2.70e-15 ***
## habitaciones    7.64511    5.65873   1.351    0.177    
## parqueaderos   24.00598    5.86889   4.090 5.14e-05 ***
## banios         18.89938    7.48800   2.524    0.012 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 155.1 on 429 degrees of freedom
##   (287 observations deleted due to missingness)
## Multiple R-squared:  0.6041, Adjusted R-squared:  0.5995 
## F-statistic: 130.9 on 5 and 429 DF,  p-value: < 2.2e-16
# R² (R-cuadrado): Explica qué proporción de la variabilidad en preciom es explicada por reaconst + estrato + habitaciones + parqueaderos + banios.
# p-valores de los coeficientes: Si p < 0.05, la variable es significativa.
# Signo y magnitud de los coeficientes: Indican el impacto de cada variable en la respuesta.

Discusion:

1- R²: El modelo explica aproximadamente 60.4% de la variabilidad en los precios de las propiedades. 2- R² Ajustado: Agregar más variables no está sobreajustando el modelo.

Conclusión: El modelo tiene un buen poder explicativo, pero hay un 39.6% de la variabilidad que no se explica por estas variables. Podría mejorar incluyendo otras características (ubicación exacta, tipo de vivienda, antigüedad, etc.).

Explicacion de coeficientes y p-value.

Intercepto: Muestra que cuando todas las variables son 0, el precio predicho es -238.17 millones, no tiene sentido, pero ayuda a entender las relaciones de las otras variables.

Area Construida: Indica que por cada metro cuadrado el precio del inmueble aumenta 0.67 Millones, y tiene significancia, ya que el p-value es menor a 0.05.

Estrato: Esta es la varianle mas significativa sobre el precio final, ya que por aumento de estrato el inmueble aumenta 80.63 millones, y su p-value muestra que es una variable significativa.

Habitaciones: A pesar que por cada habitacion de mas el precio aumenta 7.64 millones, el modelo no es significativo, ya que el p-value es mayor 0.05.

Paqueaderos: Esta variable realiza un aporte significativo de 24.01 millones, eso quiere decir que por cada parqueadero de mas, el costo del inmueble aumenta los 24.01 millones y ademas es significante en el analisis.

Baños: En el caso de los baños, aporta un poco menos que el de los parqueaderos, pero es menos significante.

Conclusiones: Se logra encontrar que habitaciones no es significativa. por lo que se podria remover para simplificar el modelo.

El estrato tiene un impacto muy fuerte, que podria ser logico en este mercado.

Analisis de Errores.

El residual estandar el cual es de 155.1 muestra que los precios pueden desviarse en promedio entre +/-155.1 millones del precio real. Ademas de esto el rando de estos residuos puede ir desde -784.29 millones hasta 978.61 millones, son errores de prediccion bastante grandes, lo que sugiere que hay algunas caracteristicas mal estimadas e impactar significativamente al modelo, lo que sugiere realizar un analisis de hetereocedasticidad e implementar una variable que explique mejor el precio.

Recomendaciones para mejorar el modelo:

Para el caso de las variables con alta variabilidad, como los indican las graficas de cajas donde se aprecian los outlier, se podria implementar una transformacion como la logaritmica o cuadratica, otra opcion podria ser incluir nuevas variables si se pudiera.

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

# Normalidad de residuos
shapiro.test(residuals(modelo1)) 
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(modelo1)
## W = 0.85246, p-value < 2.2e-16
# p > 0.05 → No hay evidencia de que los residuos se desvíen de la normalidad.
# p < 0.05 → Posible violación del supuesto de normalidad.

# Homoscedasticidad (Prueba de Breusch-Pagan)
bptest(modelo1)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo1
## BP = 80.281, df = 5, p-value = 7.33e-16
# p-valor < 0.05 → Hay heterocedasticidad significativa.
# p-valor > 0.05 → No hay evidencia de heterocedasticidad.

# Si hay heterocedasticidad, se puede:
# Transformar la variable dependiente (Ej: log(Y), sqrt(Y)).
# Usar estimadores robustos a la heterocedasticidad:
# Usar regresión ponderada (glm()) si la heterocedasticidad es severa.

library(car)

dwtest(modelo1)
## 
##  Durbin-Watson test
## 
## data:  modelo1
## DW = 1.7615, p-value = 0.005472
## alternative hypothesis: true autocorrelation is greater than 0
# Si el estadístico de Durbin-Watson está cerca de 2 → Cumple el supuesto
# Si p < 0.05 → Hay autocorrelación


# Multicolinealidad (Factor de Inflación de Varianza - VIF)
vif(modelo1)
##    areaconst      estrato habitaciones parqueaderos       banios 
##     1.460998     1.307757     1.721015     1.226334     1.967421
# VIF > 10 → Multicolinealidad alta (deberías eliminar alguna variable).
# VIF < 5 → No hay multicolinealidad preocupante
# Crear un nuevo dataframe con los valores usados en el modelo1
residuos_df <- data.frame(
  ajustados = fitted(modelo1),
  residuos = resid(modelo1)
)

# Gráfico de residuos vs. valores ajustados
ggplot(residuos_df, aes(x = ajustados, y = residuos)) +
  geom_point(alpha = 0.6, color = "black") +
  #geom_smooth(method = "loess", color = "red", se = FALSE) +
  labs(title = "Gráfico de Residuos vs. Valores Ajustados",
       x = "Valores Ajustados",
       y = "Residuos") +
  theme_classic()

qqnorm(residuals(modelo1))
qqline(residuals(modelo1), col = "red")

Analisis de los Supuestos.

Linealidad:

Supuesto: Existe una relación lineal entre la variable dependiente (preciom) y las variables predictoras (areaconst, estrato, habitaciones, parqueaderos, banios). Como se puede observar en la grafica de residuos contra valores ajustados, la nube de puntos presenta un comportamiento determinado por mayor dispersion a medida que el precio aumenta, por lo que se concluye que no se cumple el supuesto de linealidad de las variables predictoras. Para mejorar este resultado se podria obtar por aplicar logaritmo o aplicar raiz cuadrada la variable respuesta preciom, otra alternativa es aplicar terminos polinomiales a variables predictoras o finalmente probar modelos no lineales de predicción.

Normalidad de los Residuos

Supuesto: Los residuos deben seguir una distribución normal para que las pruebas de hipótesis sean válidas. Como se aprecia en el grafico de normalidad de los residuos, los datos no se ajustan a la linea central presentando mayor dispersion o distancia en los puntos mas altos, a esto sumado que el valor p de la prueba Shapiro-Wilk es menor al valor de significancia 0.05, por esta razon ni se cumple el supuesto. En terminos de mejorar este indicador, lo que se podria probar es similar al supuesto de linealidad, aplicar logaritmo o raiz cuadrada a la variable respuesta.

Homocedasticidad (Varianza constante de los residuos)

Supuesto: La varianza de los residuos debe ser constante (homocedasticidad).

studentized Breusch-Pagan test

data: modelo1 BP = 80.281, df = 5, p-value = 7.33e-16

p-valor < 0.05 → Hay heterocedasticidad significativa.

Si hay heterocedasticidad, se puede: Transformar la variable dependiente (Ej: log(Y), sqrt(Y)). Usar estimadores robustos a la heterocedasticidad: Usar regresión ponderada (glm()) si la heterocedasticidad es severa.

Independencia de los residuos (Autocorrelación)

Supuesto: Los residuos no deben estar correlacionados entre sí.

Prueba de Durbin-Watson:

Durbin-Watson test

data: modelo1 DW = 1.7615, p-value = 0.005472 alternative hypothesis: true autocorrelation is greater than 0

Si el estadístico de Durbin-Watson está cerca de 2 → Cumple el supuesto Si p < 0.05 → Hay autocorrelación.

Posibles soluciones: Incluir variables explicativas adicionales. Usar modelos con errores correlacionados (lmrob en robustbase).

Multicolinealidad

Supuesto: Las variables predictoras no deben estar fuertemente correlacionadas.

Factor de Inflación de Varianza (VIF)

areaconst estrato habitaciones parqueaderos banios 1.460998 1.307757 1.721015 1.226334 1.967421

VIF > 10 → Multicolinealidad alta (deberías eliminar alguna variable). VIF < 5 → No hay multicolinealidad grave.

Todos los VIF están por debajo de 2, lo que indica baja multicolinealidad. No hay problemas graves de redundancia entre las variables predictoras lo que indica que no es necesario eliminar variables o combinarlas.

# Instalar y cargar la librería GGally (si no está instalada)
# install.packages("GGally")  # Solo la primera vez
library(GGally)

# Seleccionar solo las variables de interés
vars_interes <- base1 %>% select(areaconst, estrato, habitaciones, parqueaderos, banios)

# Generar la matriz de dispersión
ggpairs(vars_interes)

En la matriz de correlación y dispersión se puede apreciar en la diagonal que la mayoria de datos tienen sesgo hacia la derecha esto tiene logica en la mayoria de las variables y soporta el hecho de la asimetria de los datos, ademas basado en los valores de correlaciones se ven que entre variables existen positiva y moderadas relaciones.

Paso 5.

Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

Predicción de Caso Estrato 4.

# Cargar librerías necesarias
library(gt)  # Para crear tablas elegantes

# Características de la Vivienda 1 (Casa en Zona Norte)
nueva_vivienda1 <- data.frame(
  areaconst = 200,
  estrato = 4,
  habitaciones = 4,
  parqueaderos = 1,
  banios = 2
)

# Predicción del precio para Vivienda 1
prediccion <- predict(modelo1, newdata = nueva_vivienda1)

# Crear un data frame con los resultados
resultados <- data.frame(
  Característica = c("Área Construida (m²)", "Estrato", "Habitaciones", "Parqueaderos", "Baños", "Precio Predicho"),
  Valor = c(nueva_vivienda1$areaconst, nueva_vivienda1$estrato, nueva_vivienda1$habitaciones, 
            nueva_vivienda1$parqueaderos, nueva_vivienda1$banios, round(prediccion, 2))
)

# Crear una tabla con estilo clásico usando gt
tabla_resultados <- resultados %>%
  gt() %>%
  tab_header(
    title = "Características de la Vivienda 1",
    subtitle = "Casa en Zona Norte"
  ) %>%
  cols_label(
    Característica = "Característica",
    Valor = "Valor"
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_fill(color = "lightgray"),
    locations = cells_body(rows = 6)  # Resaltar la fila del precio predicho
  )

# Mostrar la tabla
tabla_resultados
Características de la Vivienda 1
Casa en Zona Norte
Característica Valor
Área Construida (m²) 200.0
Estrato 4.0
Habitaciones 4.0
Parqueaderos 1.0
Baños 2.0
Precio Predicho 312.1

Predicción Caso Estrato 5

# Cargar librerías necesarias
library(gt)  # Para crear tablas elegantes

# Características de la Vivienda 1 (Casa en Zona Norte)
nueva_vivienda1 <- data.frame(
  areaconst = 200,
  estrato = 5,
  habitaciones = 4,
  parqueaderos = 1,
  banios = 2
)

# Predicción del precio para Vivienda 1
prediccion <- predict(modelo1, newdata = nueva_vivienda1)

# Crear un data frame con los resultados
resultados <- data.frame(
  Característica = c("Área Construida (m²)", "Estrato", "Habitaciones", "Parqueaderos", "Baños", "Precio Predicho"),
  Valor = c(nueva_vivienda1$areaconst, nueva_vivienda1$estrato, nueva_vivienda1$habitaciones, 
            nueva_vivienda1$parqueaderos, nueva_vivienda1$banios, round(prediccion, 2))
)

# Crear una tabla con estilo clásico usando gt
tabla_resultados <- resultados %>%
  gt() %>%
  tab_header(
    title = "Características de la Vivienda 1",
    subtitle = "Casa en Zona Norte"
  ) %>%
  cols_label(
    Característica = "Característica",
    Valor = "Valor"
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_fill(color = "lightgray"),
    locations = cells_body(rows = 6)  # Resaltar la fila del precio predicho
  )

# Mostrar la tabla
tabla_resultados
Características de la Vivienda 1
Casa en Zona Norte
Característica Valor
Área Construida (m²) 200.00
Estrato 5.00
Habitaciones 4.00
Parqueaderos 1.00
Baños 2.00
Precio Predicho 392.74

Paso 6.

Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga en cuenta que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

# Cargar librerías necesarias
library(dplyr)
library(leaflet)
library(gt)

# Filtrar casas en la zona norte con las condiciones solicitadas
vivienda_filtrada <- vivienda %>%
  filter(tipo == "Casa",
         zona == "Zona Norte",
         areaconst >= 200,
         parqueaderos >= 1,
         banios >= 2,
         habitaciones >= 4,
         estrato %in% c(4, 5))

# Usar el modelo estimado para predecir precios
vivienda_filtrada$precio_estimado <- predict(modelo1, newdata = vivienda_filtrada)

# Calcular la desviación absoluta entre el precio real y el estimado
vivienda_filtrada <- vivienda_filtrada %>%
  mutate(desviacion = abs(precio_estimado - preciom))  # Usar preciom

# Filtrar opciones dentro del presupuesto (máximo 350 millones)
ofertas_validas <- vivienda_filtrada %>%
  filter(preciom <= 350) %>%  # Usar preciom
  arrange(desviacion)  # Ordenar por menor desviación

# Si hay menos de 5 ofertas, completar con las más cercanas al presupuesto y con menor desviación
if (nrow(ofertas_validas) < 5) {
  faltantes <- 5 - nrow(ofertas_validas)
  opciones_adicionales <- vivienda_filtrada %>%
    filter(preciom > 350) %>%  # Usar preciom
    arrange(desviacion) %>%  # Ordenar por menor desviación
    head(faltantes)
  
  # Unir las opciones dentro del presupuesto con las adicionales
  mejores_ofertas <- bind_rows(ofertas_validas, opciones_adicionales)
} else {
  # Si hay suficientes opciones, seleccionar solo las 5 con menor desviación
  mejores_ofertas <- head(ofertas_validas, 5)
}

# Mostrar las mejores ofertas en una tabla con estilo clásico, incluyendo el id
tabla_ofertas <- mejores_ofertas %>%
  select(id, areaconst, estrato, habitaciones, parqueaderos, banios, preciom, precio_estimado, desviacion) %>%  # Usar preciom
  gt() %>%
  tab_header(
    title = "Mejores Ofertas de Vivienda en Zona Norte",
    subtitle = "Presupuesto máximo de 350 millones"
  ) %>%
  cols_label(
    id = "ID",  # Etiqueta para la columna id
    areaconst = "Área Construida (m²)",
    estrato = "Estrato",
    habitaciones = "Habitaciones",
    parqueaderos = "Parqueaderos",
    banios = "Baños",
    preciom = "Precio Real (M)",  # Usar preciom
    precio_estimado = "Precio Estimado (M)",
    desviacion = "Desviación (M)"
  ) %>%
  fmt_number(columns = c(preciom, precio_estimado, desviacion), decimals = 2) %>%  # Formatear precios y desviación con 2 decimales
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_fill(color = "lightgray"),
    locations = cells_body(rows = which(mejores_ofertas$preciom > 350))
  )  # Resaltar las opciones que superan el presupuesto

# Mostrar la tabla
tabla_ofertas
Mejores Ofertas de Vivienda en Zona Norte
Presupuesto máximo de 350 millones
ID Área Construida (m²) Estrato Habitaciones Parqueaderos Baños Precio Real (M) Precio Estimado (M) Desviación (M)
1108 260 4 4 1 3 330.00 371.60 41.60
1144 200 4 4 2 4 320.00 373.91 53.91
937 280 4 4 2 3 350.00 409.15 59.15
1822 295 4 4 2 2 340.00 400.40 60.40
1270 203 5 5 2 2 350.00 426.42 76.42
# Mostrar en un mapa las 5 ofertas
leaflet(data = mejores_ofertas) %>%
  addTiles() %>%
  addMarkers(~longitud, ~latitud, 
             popup = ~paste0("ID: ", id, "<br>",  # Usar id en lugar de ID
                             "Precio Real: ", round(preciom, 2), "M<br>",  # Usar preciom
                             "Precio Estimado: ", round(precio_estimado, 2), "M<br>",
                             "Desviación: ", round(desviacion, 2), "M<br>",
                             "Área: ", areaconst, " m²<br>",
                             "Parqueaderos: ", parqueaderos, "<br>",
                             "Baños: ", banios, "<br>",
                             "Habitaciones: ", habitaciones))

Discusiòn de Resultados

En el análisis de los resultados podriamos resaltar que las opciones generadas siguen y priorizan el precio real del inmueble, dejando como segundo plano el valor estimado por el modelo, ademas de eso considerar el hecho de que se realizaron dos predicciones una con vivienda de estrato 4 que arrojo un precio predicho de 312 millones y para el caso del modelo de estrato 5, de 392 Millones aproximadamente. En base a estos resultados podriamos considerar que las predicciones con cambio de estrato solo aumenta el valor del estrato encontrado en el parametro beta 1 o la pendiente del modelo. Otra conclusion que podriamos resaltar es el hecho de estas grandes desviaciones obedecerian al hecho del error estandar estimado anteriormente.

Puntos a considerar para mejorar el modelo:

  1. Se podrian inputar los datos de la variable parqueadero para tener mas registros de la base1 correspondientes a la zona norte, podrian hacerse con la moda de esta o asumir que si no se ha registrado parqueadero es porque simplemente el inmueble no tiene y podriamos asignarle un cero y evitariamos ignorar estos datos que podrian aportar significativamenten a disminuir el error, ya que no contar con parqueadero es un hecho que es bastante comun en la ciudad.

  2. Otra posible accion, es considerar todo el set de datos, incluyendo una variable de mas como lo es la zona, se realizaria una transformación de la variable para que sea condideraba podria utilizar fastDummies para convertirla a un factor numerico, bastante util para evitar la colinealidad.

  3. Aplicar logaritmos o raiz cuadrada a la variables Y o de respuesta en este caso preciom debido a que:

  • Presente gran variabilidad y asimetria.
  • La varianza de los residuos tiende a aumentar a medida que el precio aumenta.(Corrigiendo la heterocedasticidad)
  1. Utilizar modelos mas complejos como transformaciones polinomiales.

Desarrollo del Ejercicio: Vivienda 2 - Apartamento en Zona Sur

Paso 1.

Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?)

library(knitr)
base2 <- vivienda %>%
  filter(tipo == "Apartamento", zona == "Zona Sur")

# Mostrar los primeros 3 registros con formato de tabla
kable(head(base2, 3), caption = "Primeros 3 Registros - Casas en Zona Sur")
Primeros 3 Registros - Casas en Zona Sur
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud
5098 Zona Sur 5 4 290 96 1 2 3 Apartamento acopi -76.53464 3.44987
698 Zona Sur 2 3 78 40 1 1 2 Apartamento aguablanca -76.50100 3.40000
8199 Zona Sur NA 6 875 194 2 5 3 Apartamento aguacatal -76.55700 3.45900
# Mapa con Leaflet para verificar ubicación
leaflet(base2) %>%
  addTiles() %>%
  addCircleMarkers(
    ~longitud, ~latitud, 
    color = "blue", 
    popup = ~paste("ID:", id, "<br>Precio:", preciom, "millones")
  )
base2 <- base2 %>%
  filter(!is.na(latitud) & !is.na(longitud))  # Elimina filas con NA
base2$latitud <- as.numeric(base2$latitud)  # Asegura que sean numéricos
base2$longitud <- as.numeric(base2$longitud)

Verificación de las ubicaciones.

Para verificar que las ubicaciones esten correctas, se toma un punto de la visualización de las ubicaciones de la zona norte que este ubicada en otra zona y se verifica mediante la verificaciòn tanto en el set de datos como una ubicación individual.

library(leaflet)

# Crear un data frame con la coordenada
punto <- data.frame(
  longitud = -76.52789,
  latitud = 3.48383
)

# Generar el mapa con un marcador en la coordenada especificada
leaflet(punto) %>%
  addTiles() %>%
  addMarkers(~longitud, ~latitud, popup = "Ubicación específica")

En este caso la coordenada consultada es la del ID 3670 la cual esta ubicada en el norte de la ciudad, pero en el set de datos indica que es un registro de la zona sur, especificamente en el barrio Caney, Despues de verificar los datos de longitud y latitud, se puede comprobar que para una gran cantidad de registros como lo muestra el mapa, la ubicación no corresponde a la zona sur de la ciudad lo que nos dice que no podemos usar estas variables para hacer el analisis.

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

# Gráficos entre precio y variables relevantes
p10 <- ggplot(vivienda, aes(x = areaconst, y = preciom)) +
  geom_point(color = "#708090") +
  labs(title = "Precio vs Área Construida",
        x = "Area Construida",
        y = "Precio en Millones") +
  theme_classic()

p20 <- ggplot(vivienda, aes(x = estrato, y = preciom)) +
  geom_boxplot(fill = "white", color = "#708090") +
  labs(title = "Precio vs Estrato",
        x = "Estrato",
        y = "Precio en Millones") +
  theme_classic()

p_banios_2 <- ggplot(vivienda, aes(x = factor(banios), y = preciom)) +
  geom_boxplot(fill = "white", color = "#708090") +
  labs(title = "Distribución del Precio según Número de Baños",
       x = "Número de Baños",
       y = "Precio en Millones") +
  theme_classic()

p_habitaciones_2 <- ggplot(vivienda, aes(x = factor(habitaciones), y = preciom)) +
  geom_boxplot(fill = "white", color = "#708090") +
  labs(title = "Distribución del Precio según Número de Habitaciones",
       x = "Número de Habitaciones",
       y = "Precio en Millones") +
  theme_classic()

p_zona_2 <- ggplot(vivienda, aes(x = zona, y = preciom)) +
  geom_boxplot(fill = "white", color = "#708090") +
  labs(title = "Distribución del Precio según la Zona",
       x = "Zona",
       y = "Precio en Millones") +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))


# Convertir gráficos a interactivos
ggplotly(p10)
ggplotly(p20)
ggplotly(p_banios_2)
ggplotly(p_habitaciones_2)
ggplotly(p_zona_2)

Interpretación de los resultados:

  1. La gran densidad de los datos del precio respecto al area construida se ubican hasta 500 metros cuadrados y pueden llegar hasta casi 2000 millones el costo del inmueble.

  2. Para el caso de los precios respecto al estrato se puede observar en la grafica de cajas que la tendencia de medias tiende a aumentar, sin embargo cada uno de los casos presenta una gran cantidad de outlier que muestran precios elevados lejos de los datos centrados.

  3. En el caso del precio respecto al numero de baños podemos notar que desde la cantidad 6 hasta el 10 los precios y medias se presentan sobre simiares rangos de precios. Sin que sea concluyente, este grafico puede darnos a entender que el numero de baños puede representar datos outlier de los precios respecto al estrato y area construida. Ademas hay que tener en cuenta que los datos con numero de baños cero, pueden ser los datos faltantes del dataset, estos serian tratados.

  4. Con el numero de habitaciones respecto a los precios se presenta el caso de que las viviendas de tres muestran varios datos outlier, con precios elevados y en gran cantidad. Por otra parte, existen inmuebles de mas de 5 habitaciones que pueden tener precios de aquellas cuales tienen 2, lo que indica que el numero de habitaciones no podria ser una variable predictora que aporte en gran medida al precio.

  5. La relación de zonas puede ser una predictora bastante interesante, ya que se puede observar que las zonas norte y sur presentan similares rangos de precio en cambio la zona oeste supera estos valores, lo que nos indica que esta variable en si misma puede ser represenativa.

Paso 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 R Cuadrado y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

# Modelo de regresión para Casas - Zona Norte
modelo2 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base2)
summary(modelo2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base2)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1092.02   -42.28    -1.33    40.58   926.56 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -261.62501   15.63220 -16.736  < 2e-16 ***
## areaconst       1.28505    0.05403  23.785  < 2e-16 ***
## estrato        60.89709    3.08408  19.746  < 2e-16 ***
## habitaciones  -24.83693    3.89229  -6.381 2.11e-10 ***
## parqueaderos   72.91468    3.95797  18.422  < 2e-16 ***
## banios         50.69675    3.39637  14.927  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 98.02 on 2375 degrees of freedom
##   (406 observations deleted due to missingness)
## Multiple R-squared:  0.7485, Adjusted R-squared:  0.748 
## F-statistic:  1414 on 5 and 2375 DF,  p-value: < 2.2e-16
# R² (R-cuadrado): Explica qué proporción de la variabilidad en preciom es explicada por reaconst + estrato + habitaciones + parqueaderos + banios.
# p-valores de los coeficientes: Si p < 0.05, la variable es significativa.
# Signo y magnitud de los coeficientes: Indican el impacto de cada variable en la respuesta.

Discusion:

1- R²: El modelo explica aproximadamente 74.85% de la variabilidad en los precios de las propiedades. 2- R² Ajustado: Agregar más variables no está sobreajustando el modelo.

Conclusión: El modelo tiene un buen poder explicativo, pero hay un 25.15% de la variabilidad que no se explica por estas variables. Podría mejorar incluyendo otras características (ubicación exacta, tipo de vivienda, antigüedad, etc.).

Explicacion de coeficientes y p-value.

Intercepto: Muestra que cuando todas las variables son 0, el precio predicho es -261.61 millones, no tiene sentido, pero ayuda a entender las relaciones de las otras variables.

Area Construida: Indica que por cada metro cuadrado el precio del inmueble aumenta 1.28 Millones, y tiene significancia, ya que el p-value es menor a 0.05.

Estrato: Esta es la varianle mas significativa sobre el precio final, ya que por aumento de estrato el inmueble aumenta 60.89 millones, y su p-value muestra que es una variable significativa.

Habitaciones: A pesar que por cada habitacion de mas el precio disminuye 24.38 millones, para el modelo la variable essignificativa, ya que el p-value es menor de 0.05.

Paqueaderos: Esta variable realiza un aporte significativo de 50.69 millones, eso quiere decir que por cada parqueadero de mas, el costo del inmueble aumenta los 50.69 millones y ademas es significante en el analisis.

Baños: En el caso de los baños, aporta un poco menos que el de los parqueaderos, pero es menos significante.

Conclusiones: Se logra encontrar que todas las variables son significativas. por lo que se no seria recomendable remover alguna variable para simplificar el modelo.

El estrato y parqueadero tienen un impacto muy fuerte, que podria ser logico en este mercado.

Analisis de Errores.

El residual estandar el cual es de 98.02 muestra que los precios pueden desviarse en promedio entre +/-98.02 millones del precio real. Ademas de esto el rando de estos residuos puede ir desde -1092 millones hasta 926 millones, son errores de prediccion bastante grandes, lo que sugiere que hay algunas caracteristicas mal estimadas e impactar significativamente al modelo, lo que sugiere realizar un analisis de hetereocedasticidad e implementar una variable que explique mejor el precio.

Recomendaciones para mejorar el modelo:

Al igual que el anterior caso, las variables tienen alta variabilidad, como los indican las graficas de cajas donde se aprecian los outlier, se podria implementar una transformacion como la logaritmica o cuadratica, otra opcion podria ser incluir nuevas variables si se pudiera.

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

# Normalidad de residuos
shapiro.test(residuals(modelo2)) 
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(modelo2)
## W = 0.79118, p-value < 2.2e-16
# p > 0.05 → No hay evidencia de que los residuos se desvíen de la normalidad.
# p < 0.05 → Posible violación del supuesto de normalidad.

# Homoscedasticidad (Prueba de Breusch-Pagan)
bptest(modelo2)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo2
## BP = 754.81, df = 5, p-value < 2.2e-16
# p-valor < 0.05 → Hay heterocedasticidad significativa.
# p-valor > 0.05 → No hay evidencia de heterocedasticidad.

# Si hay heterocedasticidad, se puede:
# Transformar la variable dependiente (Ej: log(Y), sqrt(Y)).
# Usar estimadores robustos a la heterocedasticidad:
# Usar regresión ponderada (glm()) si la heterocedasticidad es severa.

library(car)

dwtest(modelo2)
## 
##  Durbin-Watson test
## 
## data:  modelo2
## DW = 1.5333, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
# Si el estadístico de Durbin-Watson está cerca de 2 → Cumple el supuesto
# Si p < 0.05 → Hay autocorrelación


# Multicolinealidad (Factor de Inflación de Varianza - VIF)
vif(modelo2)
##    areaconst      estrato habitaciones parqueaderos       banios 
##     2.066518     1.545162     1.429280     1.737878     2.529494
# VIF > 10 → Multicolinealidad alta (deberías eliminar alguna variable).
# VIF < 5 → No hay multicolinealidad preocupante
# Crear un nuevo dataframe con los valores usados en el modelo1
residuos_df2 <- data.frame(
  ajustados = fitted(modelo2),
  residuos = resid(modelo2)
)

# Gráfico de residuos vs. valores ajustados
ggplot(residuos_df2, aes(x = ajustados, y = residuos)) +
  geom_point(alpha = 0.6, color = "black") +
  #geom_smooth(method = "loess", color = "red", se = FALSE) +
  labs(title = "Gráfico de Residuos vs. Valores Ajustados",
       x = "Valores Ajustados",
       y = "Residuos") +
  theme_classic()

qqnorm(residuals(modelo2))
qqline(residuals(modelo2), col = "red")

Analisis de los Supuestos.

Linealidad:

Supuesto: Existe una relación lineal entre la variable dependiente (preciom) y las variables predictoras (areaconst, estrato, habitaciones, parqueaderos, banios). Como se puede observar en la grafica de residuos contra valores ajustados, la nube de puntos presenta un comportamiento determinado por mayor dispersion a medida que el precio aumenta, por lo que se concluye que no se cumple el supuesto de linealidad de las variables predictoras. Para mejorar este resultado se podria obtar por aplicar logaritmo o aplicar raiz cuadrada la variable respuesta preciom, otra alternativa es aplicar terminos polinomiales a variables predictoras o finalmente probar modelos no lineales de predicción.

Normalidad de los Residuos

Supuesto: Los residuos deben seguir una distribución normal para que las pruebas de hipótesis sean válidas. Como se aprecia en el grafico de normalidad de los residuos, los datos no se ajustan a la linea central presentando mayor dispersion o distancia en los puntos mas altos, a esto sumado que el valor p de la prueba Shapiro-Wilk es menor al valor de significancia 0.05, por esta razon ni se cumple el supuesto. En terminos de mejorar este indicador, lo que se podria probar es similar al supuesto de linealidad, aplicar logaritmo o raiz cuadrada a la variable respuesta.

Homocedasticidad (Varianza constante de los residuos)

Supuesto: La varianza de los residuos debe ser constante (homocedasticidad).

studentized Breusch-Pagan test

data: modelo2 BP = 754.81, df = 5, p-value < 2.2e-16

p-valor < 0.05 → Hay heterocedasticidad significativa.

Si hay heterocedasticidad, se puede: Transformar la variable dependiente (Ej: log(Y), sqrt(Y)). Usar estimadores robustos a la heterocedasticidad: Usar regresión ponderada (glm()) si la heterocedasticidad es severa.

Independencia de los residuos (Autocorrelación)

Supuesto: Los residuos no deben estar correlacionados entre sí.

Prueba de Durbin-Watson:

Durbin-Watson test

data: modelo2 DW = 1.5333, p-value < 2.2e-16 alternative hypothesis: true autocorrelation is greater than 0

Si el estadístico de Durbin-Watson está cerca de 2 → Cumple el supuesto Si p < 0.05 → Hay autocorrelación.

Posibles soluciones: Incluir variables explicativas adicionales. Usar modelos con errores correlacionados (lmrob en robustbase).

Multicolinealidad

Supuesto: Las variables predictoras no deben estar fuertemente correlacionadas.

Factor de Inflación de Varianza (VIF)

areaconst estrato habitaciones parqueaderos banios 2.066518 1.545162 1.429280 1.737878 2.529494

VIF > 10 → Multicolinealidad alta (deberías eliminar alguna variable). VIF < 5 → No hay multicolinealidad grave.

Todos los VIF están por debajo de 5, lo que indica baja multicolinealidad. No hay problemas graves de redundancia entre las variables predictoras lo que indica que no es necesario eliminar variables o combinarlas.

# Instalar y cargar la librería GGally (si no está instalada)
# install.packages("GGally")  # Solo la primera vez
library(GGally)

# Seleccionar solo las variables de interés
vars_interes_2 <- base2 %>% select(areaconst, estrato, habitaciones, parqueaderos, banios)

# Generar la matriz de dispersión
ggpairs(vars_interes_2)

En la matriz de correlación y dispersión se puede apreciar en la diagonal que la mayoria de datos tienen sesgo hacia la derecha esto tiene logica en la mayoria de las variables y soporta el hecho de la asimetria de los datos, ademas basado en los valores de correlaciones se ven que entre variables existen positiva y moderadas relaciones.

Paso 5.

Con el modelo identificado debe predecir el precio del apartamento con las características de la primera solicitud.

Predicción de Caso Estrato 5.

# Cargar librerías necesarias
library(gt)  # Para crear tablas elegantes

# Características de la Vivienda 1 (Casa en Zona Norte)
nueva_vivienda2 <- data.frame(
  areaconst = 300,
  estrato = 5,
  habitaciones = 5,
  parqueaderos = 3,
  banios = 3
)

# Predicción del precio para Vivienda 1
prediccion1 <- predict(modelo2, newdata = nueva_vivienda2)

# Crear un data frame con los resultados
resultados1 <- data.frame(
  Característica = c("Área Construida (m²)", "Estrato", "Habitaciones", "Parqueaderos", "Baños", "Precio Predicho"),
  Valor = c(nueva_vivienda2$areaconst, nueva_vivienda2$estrato, nueva_vivienda2$habitaciones, 
            nueva_vivienda2$parqueaderos, nueva_vivienda2$banios, round(prediccion1, 2))
)

# Crear una tabla con estilo clásico usando gt
tabla_resultados1 <- resultados1 %>%
  gt() %>%
  tab_header(
    title = "Características de la Vivienda 1",
    subtitle = "Apartamentos en Zona Sur"
  ) %>%
  cols_label(
    Característica = "Característica",
    Valor = "Valor"
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_fill(color = "lightgray"),
    locations = cells_body(rows = 6)  # Resaltar la fila del precio predicho
  )

# Mostrar la tabla
tabla_resultados1
Características de la Vivienda 1
Apartamentos en Zona Sur
Característica Valor
Área Construida (m²) 300.00
Estrato 5.00
Habitaciones 5.00
Parqueaderos 3.00
Baños 3.00
Precio Predicho 675.02

Predicción Caso Estrato 6

# Cargar librerías necesarias
library(gt)  # Para crear tablas elegantes

# Características de la Vivienda 1 (Casa en Zona Norte)
nueva_vivienda2 <- data.frame(
  areaconst = 300,
  estrato = 6,
  habitaciones = 5,
  parqueaderos = 3,
  banios = 3
)

# Predicción del precio para Vivienda 1
prediccion1 <- predict(modelo2, newdata = nueva_vivienda2)

# Crear un data frame con los resultados
resultados2 <- data.frame(
  Característica = c("Área Construida (m²)", "Estrato", "Habitaciones", "Parqueaderos", "Baños", "Precio Predicho"),
  Valor = c(nueva_vivienda2$areaconst, nueva_vivienda2$estrato, nueva_vivienda2$habitaciones, 
            nueva_vivienda2$parqueaderos, nueva_vivienda2$banios, round(prediccion1, 2))
)

# Crear una tabla con estilo clásico usando gt
tabla_resultados2 <- resultados2 %>%
  gt() %>%
  tab_header(
    title = "Características de la Vivienda 1",
    subtitle = "Apartamento en Zona Sur"
  ) %>%
  cols_label(
    Característica = "Característica",
    Valor = "Valor"
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_fill(color = "lightgray"),
    locations = cells_body(rows = 6)  # Resaltar la fila del precio predicho
  )

# Mostrar la tabla
tabla_resultados2
Características de la Vivienda 1
Apartamento en Zona Sur
Característica Valor
Área Construida (m²) 300.00
Estrato 6.00
Habitaciones 5.00
Parqueaderos 3.00
Baños 3.00
Precio Predicho 735.92

Paso 6.

Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga en cuenta que la empresa tiene crédito pre-aprobado de máximo 850 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

# Cargar librerías necesarias
library(dplyr)
library(leaflet)
library(gt)

# Filtrar casas en la zona norte con las condiciones solicitadas
vivienda_filtrada1 <- vivienda %>%
  filter(tipo == "Apartamento",
         zona == "Zona Sur",
         areaconst >= 300,
         parqueaderos >= 3,
         banios >= 3,
         habitaciones >= 5,
         estrato %in% c(5, 6))

# Usar el modelo estimado para predecir precios
vivienda_filtrada1$precio_estimado1 <- predict(modelo2, newdata = vivienda_filtrada1)

# Calcular la desviación absoluta entre el precio real y el estimado
vivienda_filtrada1 <- vivienda_filtrada1 %>%
  mutate(desviacion1 = abs(precio_estimado1 - preciom))  # Usar preciom

# Filtrar opciones dentro del presupuesto (máximo 350 millones)
ofertas_validas1 <- vivienda_filtrada1 %>%
  filter(preciom <= 350) %>%  # Usar preciom
  arrange(desviacion1)  # Ordenar por menor desviación

# Si hay menos de 5 ofertas, completar con las más cercanas al presupuesto y con menor desviación
if (nrow(ofertas_validas1) < 5) {
  faltantes1 <- 5 - nrow(ofertas_validas1)
  opciones_adicionales1 <- vivienda_filtrada1 %>%
    filter(preciom > 350) %>%  # Usar preciom
    arrange(desviacion1) %>%  # Ordenar por menor desviación
    head(faltantes1)
  
  # Unir las opciones dentro del presupuesto con las adicionales
  mejores_ofertas1 <- bind_rows(ofertas_validas1, opciones_adicionales1)
} else {
  # Si hay suficientes opciones, seleccionar solo las 5 con menor desviación
  mejores_ofertas1 <- head(ofertas_validas1, 5)
}

# Mostrar las mejores ofertas en una tabla con estilo clásico, incluyendo el id
tabla_ofertas1 <- mejores_ofertas1 %>%
  select(id, areaconst, estrato, habitaciones, parqueaderos, banios, preciom, precio_estimado1, desviacion1) %>%  # Usar preciom
  gt() %>%
  tab_header(
    title = "Mejores Ofertas de Apartamentos en Zona Sur",
    subtitle = "Presupuesto máximo de 850 millones"
  ) %>%
  cols_label(
    id = "ID",  # Etiqueta para la columna id
    areaconst = "Área Construida (m²)",
    estrato = "Estrato",
    habitaciones = "Habitaciones",
    parqueaderos = "Parqueaderos",
    banios = "Baños",
    preciom = "Precio Real (M)",  # Usar preciom
    precio_estimado1 = "Precio Estimado (M)",
    desviacion1 = "Desviación (M)"
  ) %>%
  fmt_number(columns = c(preciom, precio_estimado1, desviacion1), decimals = 2) %>%  # Formatear precios y desviación con 2 decimales
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_column_labels()
  ) %>%
  tab_style(
    style = cell_fill(color = "lightgray"),
    locations = cells_body(rows = which(mejores_ofertas1$preciom > 850))
  )  # Resaltar las opciones que superan el presupuesto

# Mostrar la tabla
tabla_ofertas1
Mejores Ofertas de Apartamentos en Zona Sur
Presupuesto máximo de 850 millones
ID Área Construida (m²) Estrato Habitaciones Parqueaderos Baños Precio Real (M) Precio Estimado (M) Desviación (M)
6023 464 6 5 4 6 1,150.00 1,171.67 21.67
7512 300 5 6 3 5 670.00 751.58 81.58
5248 344 6 5 4 5 1,150.00 966.77 183.23
4 346 6 5 4 6 1,280.00 1,020.04 259.96
7182 573 5 5 3 8 730.00 1,279.33 549.33
# Mostrar en un mapa las 5 ofertas
leaflet(data = mejores_ofertas1) %>%
  addTiles() %>%
  addMarkers(~longitud, ~latitud, 
             popup = ~paste0("ID: ", id, "<br>",  # Usar id en lugar de ID
                             "Precio Real: ", round(preciom, 2), "M<br>",  # Usar preciom
                             "Precio Estimado: ", round(precio_estimado1, 2), "M<br>",
                             "Desviación: ", round(desviacion1, 2), "M<br>",
                             "Área: ", areaconst, " m²<br>",
                             "Parqueaderos: ", parqueaderos, "<br>",
                             "Baños: ", banios, "<br>",
                             "Habitaciones: ", habitaciones))

Discusiòn de Resultados

En el análisis de los resultados podriamos resaltar que las opciones generadas siguen y priorizan el precio real del inmueble, dejando como segundo plano el valor estimado por el modelo, ademas de eso considerar el hecho de que se realizaron dos predicciones una con vivienda de estrato 5 que arrojo un precio predicho de 675 millones y para el caso del modelo de estrato 6, de 736 Millones aproximadamente. En base a estos resultados podriamos considerar que las predicciones con cambio de estrato solo aumenta el valor del estrato encontrado en el parametro beta 1 o la pendiente del modelo. Otra conclusion que podriamos resaltar es el hecho de estas grandes desviaciones obedecerian al hecho del error estandar estimado anteriormente.

Puntos a considerar para mejorar el modelo podrian considerarse al igual que los del punto 1 o vivienda 1.

Discusiones del Reporte y del Procedimiento.

Como se logro mostrar en el desarrollo de la presente actividad, en general los supuestos implementados para validar la prediccion realizada no se puede aceptar en ninguno de los dos casos, a esto se le suma la gran variabilidad de los residuos de los errores que los modelos arrojan, por lo que podriamos acusar a las siguientes condiciones el pobre desempeño de la regresión multiple:

Sesgo de los datos:

Se puede observar en las matrices de correlación el sesgo a la derecha de las variables, ademas en los graficos de cajas se pueden notar los valores o outlier para la mayoria de variables. Para este caso, se propondria normalizar mejor los datos usando tecnicas avanzadas como factorizacion de las variables para manejar rangos mas cerrados, otro metodo seria implementar polinomios para absorber ese comportamiento sesgado. Por ultimo se podria eliminar los datos outlier pero se debe tener en cuenta que son bastantes.

Ya que el ejercicio no solicita corrección para mejorar el modelo, en el presente reporte solo se realiza el análisis y describen las posibles soluciones.

Datos Faltantes:

Otra forma de de mejorar la predicción seria imputar datos faltantes, ya que el modelo de regresion implementado cuando se ejecuta realiza la eliminación de registros con datos faltantes, porque que eliminarlas no tendria gran impacto en el desempeño, sin embargo si no se mejoran la calidad de los datos es evidente que esta medida aportaria muy poco en comparaciòn a la normalización de los datos.

Muchas Gracias..