Resumen Ejecutivo

Este informe técnico-estratégico responde a la solicitud de una compañía multinacional para la adquisición de dos inmuebles en la ciudad de Cali. Aprovechando la coyuntura de reactivación en el sector de la construcción, se han desarrollado modelos de regresión lineal múltiple para tasar el valor justo de las propiedades y optimizar el presupuesto preaprobado por la corporación. El documento aborda la limpieza de datos, análisis exploratorio espacial, modelación paramétrica y recomendaciones accionables.


PARTE 1: Solicitud Vivienda 1 (Casas, Zona Norte)

Parámetros de búsqueda: Casa, 200m2, 1 Parqueadero, 2 Baños, 4 Habitaciones, Estrato 4 o 5, Zona Norte. Presupuesto máximo: 350 Millones.

Paso 1: Filtro, Depuración y Análisis Espacial

# Limpieza profunda y filtro
base1 <- vivienda %>%
  filter(tipo == "Casa", zona == "Zona Norte") %>%
  drop_na(preciom, areaconst, estrato, banios, habitaciones, parqueaderos, longitud, latitud) %>%
  mutate(estrato = as.numeric(estrato),
         parqueaderos = as.numeric(parqueaderos)) %>%
  filter(longitud > -76.6 & longitud < -76.4, latitud > 3.3 & latitud < 3.5) # Limpieza de outliers espaciales

datatable(head(base1, 3), options = list(dom = 't', scrollX = TRUE), 
          caption = "Tabla 1.1: Primeros 3 registros de Base 1 (Casas Norte)")
plot_mapa_inmuebles(base1, "#2980B9")

Análisis Detallado: El proceso de depuración eliminó registros con valores nulos para garantizar la estabilidad de los algoritmos. Al visualizar el mapa interactivo, notamos que la inmensa mayoría de los puntos se agrupan coherentemente en el norte de la ciudad. Sin embargo, pueden existir leves dispersiones o valores en otras zonas. Esto es un fenómeno recurrente en bases inmobiliarias conocido como “ruido de geocodificación”, el cual ocurre cuando el agente inmobiliario introduce manualmente un barrio y la API de mapas asigna un centroide incorrecto. Para mitigar esto, se aplicó un filtro de coordenadas en el código.

Paso 2: Análisis Exploratorio de Datos (EDA)

p1 <- ggplot(base1, aes(x = areaconst, y = preciom, color = factor(estrato))) +
  geom_point(alpha = 0.5) +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Dispersión de Precio vs Área por Estrato (Norte)",
       x = "Área Construida (m2)", y = "Precio (Millones COP)", color = "Estrato") +
  theme_minimal()
ggplotly(p1)

Análisis Detallado: El análisis exploratorio revela una fuerte dependencia lineal entre el área construida y el precio de la vivienda. Observamos un efecto de “abanico”: a medida que las casas son más grandes, la dispersión del precio aumenta drásticamente. Esto indica que en casas de gran metraje entran en juego características “premium” (como piscina o diseño arquitectónico) no capturadas en los datos. Además, las líneas de tendencia paralelas confirman el “premium” de ubicación codificado en el estrato.

Paso 3: Estimación del Modelo de Regresión

modelo1 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base1)
kable(summary(modelo1)$coefficients, digits = 3, caption = "Tabla 1.2: Coeficientes del Modelo (Base 1)")
Tabla 1.2: Coeficientes del Modelo (Base 1)
Estimate Std. Error t value Pr(>|t|)
(Intercept) -238.171 44.406 -5.364 0.000
areaconst 0.677 0.053 12.814 0.000
estrato 80.635 9.826 8.206 0.000
habitaciones 7.645 5.659 1.351 0.177
parqueaderos 24.006 5.869 4.090 0.000
banios 18.899 7.488 2.524 0.012

Análisis Detallado y Lógico: El modelo estimado nos ayuda a aislar el impacto de cada variable:

  • Área Construida: El coeficiente positivo y estadísticamente significativo indica el valor marginal de cada metro cuadrado adicional. Es un resultado completamente lógico y esperado.

  • Estrato: Se comporta como un ponderador de plusvalía. Un cambio de estrato incrementa significativamente el valor base de la propiedad.

  • Ajuste y Mejoras: El Multiple R-squared del modelo indica la proporción de varianza explicada. Para mejorarlo, el modelo requiere variables geoespaciales explícitas (distancia a centros comerciales, estaciones de transporte) o la edad de la propiedad, lo cual reduciría el sesgo de variables omitidas.

Paso 4: Validación de Supuestos

kable(test_supuestos(modelo1), digits = 4, caption = "Tabla 1.3: Validación de Supuestos (Base 1)")
Tabla 1.3: Validación de Supuestos (Base 1)
Supuesto Estadistico P_Valor
BP Homocedasticidad (Breusch-Pagan) 80.2808 0
Multicolinealidad Máx (VIF) 1.9674 NA
W Normalidad Residuos (Shapiro) 0.8525 0

Análisis Detallado y Sugerencias:

  • Multicolinealidad (VIF): Si observamos valores elevados para habitaciones y baños, es natural en bienes raíces: una casa más grande estructuralmente requiere más baños. Sugerencia: Crear un índice compuesto de tamaño.

  • Homocedasticidad (Breusch-Pagan): El p-valor rechaza la hipótesis nula, confirmando heterocedasticidad (varianza no constante). Sugerencia: Para inferencia precisa, se deberían usar Errores Estándar Robustos o aplicar una transformación logarítmica a la variable precio.

  • Normalidad: Fallida debido a la asimetría de precios (colas pesadas hacia la derecha, típico de bienes de capital).

Paso 5: Predicción Puntual

casa_obj <- data.frame(areaconst = 200, estrato = 4, habitaciones = 4, parqueaderos = 1, banios = 2)
pred_puntual1 <- predict(modelo1, newdata = casa_obj, interval = "confidence")
kable(pred_puntual1, digits = 2, caption = "Tabla 1.4: Predicción con Intervalo de Confianza (95%)")
Tabla 1.4: Predicción con Intervalo de Confianza (95%)
fit lwr upr
312.1 287.19 337.01

Análisis Detallado: Para el perfil de 200m2 en estrato 4, el modelo estima un valor central (fit) en millones de COP. Adicionalmente, se presenta el intervalo de confianza (lwr - upr). Si este intervalo se acerca peligrosamente o supera los 350 millones, se levanta una alerta comercial: el presupuesto de la multinacional podría estar ligeramente ajustado para la realidad actual del mercado del norte.

Paso 6: Análisis de Ofertas Potenciales

ofertas_norte <- base1 %>%
  filter(preciom <= 350, areaconst >= 180, banios >= 2, habitaciones >= 3) %>%
  arrange(desc(areaconst), preciom) %>%
  head(5)

datatable(ofertas_norte %>% select(barrio, preciom, areaconst, estrato, habitaciones), 
          options = list(dom = 't'), caption = "Tabla 1.5: Top 5 Ofertas (Norte - Max 350M)")
plot_mapa_inmuebles(ofertas_norte, "#27AE60")

Análisis Estratégico de Ofertas: Se filtraron las propiedades que respetan el límite estricto de $350 millones. Las opciones presentadas en el mapa representan la frontera de eficiencia (mayor área y mejores características por el menor precio posible). Se recomienda presentar estas 5 opciones a la empresa, haciendo la salvedad de que flexibilizar el requisito de área a 180m2 garantiza mantenerse holgadamente dentro del presupuesto.


PARTE 2: Solicitud Vivienda 2 (Apartamentos, Zona Sur)

Parámetros de búsqueda: Apartamento, 300m2, 3 Parqueaderos, 3 Baños, 5 Habitaciones, Estrato 5 o 6, Zona Sur. Presupuesto máximo: 850 Millones.

Paso 1: Filtro, Depuración y Análisis Espacial

base2 <- vivienda %>%
  filter(tipo == "Apartamento", zona == "Zona Sur") %>%
  drop_na(preciom, areaconst, estrato, banios, habitaciones, parqueaderos, longitud, latitud) %>%
  mutate(estrato = as.numeric(estrato),
         parqueaderos = as.numeric(parqueaderos)) %>%
  filter(longitud > -76.6 & longitud < -76.4, latitud > 3.3 & latitud < 3.5)

datatable(head(base2, 3), options = list(dom = 't', scrollX = TRUE), 
          caption = "Tabla 2.1: Primeros 3 registros de Base 2 (Aptos Sur)")
plot_mapa_inmuebles(base2, "#8E44AD")

Análisis Detallado: El sur de Cali concentra un alto desarrollo de apartamentos de estratos altos (ej. Ciudad Jardín, Pance). El mapa filtra correctamente este clúster, evidenciando que el mercado objetivo de la segunda solicitud se concentra fuertemente en este sector geográfico, validando la petición de la multinacional.

Paso 2: Análisis Exploratorio de Datos (EDA)

p2 <- ggplot(base2, aes(x = areaconst, y = preciom, color = factor(estrato))) +
  geom_point(alpha = 0.5) +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Dispersión de Precio vs Área por Estrato (Sur)",
       x = "Área Construida (m2)", y = "Precio (Millones COP)", color = "Estrato") +
  theme_minimal() + scale_color_brewer(palette = "Set1")
ggplotly(p2)

Análisis Detallado: La gráfica muestra que apartamentos de 300m2 pertenecen a un segmento de ultra-lujo (Penthouses). En estos metrajes altos, la varianza del precio es inmensa. El comportamiento de los precios en el estrato 6 (línea roja) demuestra que la valoración en este segmento obedece a dinámicas de exclusividad y no solo a la suma de metros cuadrados.

Paso 3: Estimación del Modelo de Regresión

modelo2 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base2)
kable(summary(modelo2)$coefficients, digits = 3, caption = "Tabla 2.2: Coeficientes del Modelo (Base 2)")
Tabla 2.2: Coeficientes del Modelo (Base 2)
Estimate Std. Error t value Pr(>|t|)
(Intercept) -261.625 15.632 -16.736 0
areaconst 1.285 0.054 23.785 0
estrato 60.897 3.084 19.746 0
habitaciones -24.837 3.892 -6.381 0
parqueaderos 72.915 3.958 18.422 0
banios 50.697 3.396 14.927 0

Análisis Detallado y Lógico: En el mercado de apartamentos de lujo del sur, la variable parqueaderos tiene un coeficiente altísimo en comparación con el mercado general. Esto es estructuralmente lógico: en propiedades verticales, la escasez de espacio hace que un parqueadero adicional (solicitan 3) se cotice a un precio premium muy elevado. Mejora sugerida: Para inmuebles de ultra-lujo, algoritmos de Machine Learning no lineales (como Random Forest) suelen capturar mejor estas explosiones de precios.

Paso 4: Validación de Supuestos

kable(test_supuestos(modelo2), digits = 4, caption = "Tabla 2.3: Validación de Supuestos (Base 2)")
Tabla 2.3: Validación de Supuestos (Base 2)
Supuesto Estadistico P_Valor
BP Homocedasticidad (Breusch-Pagan) 754.8051 0
Multicolinealidad Máx (VIF) 2.5295 NA
W Normalidad Residuos (Shapiro) 0.7912 0

Análisis Detallado: De manera predecible, los supuestos de MCO no se cumplen debido a la alta varianza en los estratos altos. No obstante, para efectos de predicción puntual (que es nuestro objetivo de negocio), la falla en la normalidad o la homocedasticidad no invalida el valor predicho, aunque sí requiere cautela al interpretar los intervalos de confianza estadísticos.

Paso 5: Predicción Puntual

apto_obj <- data.frame(areaconst = 300, estrato = 6, habitaciones = 5, parqueaderos = 3, banios = 3)
pred_puntual2 <- predict(modelo2, newdata = apto_obj, interval = "confidence")
kable(pred_puntual2, digits = 2, caption = "Tabla 2.4: Predicción con Intervalo de Confianza (95%)")
Tabla 2.4: Predicción con Intervalo de Confianza (95%)
fit lwr upr
735.92 712.72 759.12

Análisis Detallado: El valor teórico arrojado por el modelo nos permite validar si la cifra de $850 millones es realista para el sur de la ciudad. Dado el metraje y las especificaciones exigentes (3 parqueaderos), este punto de referencia cuantitativo es vital para la negociación que llevará a cabo la agencia C&A.

Paso 6: Análisis de Ofertas Potenciales

ofertas_sur <- base2 %>%
  filter(preciom <= 850, areaconst >= 250, parqueaderos >= 2, habitaciones >= 4) %>%
  arrange(desc(areaconst), preciom) %>%
  head(5)

datatable(ofertas_sur %>% select(barrio, preciom, areaconst, estrato, parqueaderos), 
          options = list(dom = 't'), caption = "Tabla 2.5: Top 5 Ofertas (Sur - Max 850M)")
plot_mapa_inmuebles(ofertas_sur, "#E74C3C")

Análisis Estratégico de Ofertas: Se logró extraer un portafolio de 5 propiedades altamente competitivas con un tope de $850 millones. Aunque encontrar apartamentos exactos de 300m2 con este presupuesto es desafiante, las opciones mapeadas priorizan el área (por encima de 250m2) y garantizan la pluralidad de parqueaderos en zonas exclusivas del sur. Representan la mejor recomendación accionable para el cliente internacional.