Informe Ejecutivo: Asesoría Inmobiliaria para C&A (Casas y Apartamentos)

Para: María (Directora de C&A)
Asunto: Análisis de viabilidad y selección de ofertas para clientes internacionales


1. Resumen

El presente informe tiene como objetivo respaldar la decisión comercial de C&A frente a la solicitud de una compañía internacional interesada en adquirir dos propiedades en Cali para sus colaboradores. A partir del análisis exploratorio, la estimación de modelos econométricos de precios y la validación de supuestos sobre la base de datos histórica de la agencia, se presentan a continuación los hallazgos, la viabilidad de los créditos preaprobados y las recomendaciones estratégicas para ambos casos.


2. Análisis del Caso 1: Vivienda en la Zona Norte (Casas)

  • Condiciones de la solicitud: Casa en la Zona Norte, área construida de 200 m², 1 parqueadero, 2 baños, 4 habitaciones, estrato 4 o 5, con un crédito preaprobado de 350 millones de pesos.
  • Análisis de Mercado y Modelo: El modelo de regresión múltiple estimado para la Zona Norte muestra un ajuste significativo (\(R^2 \approx 0.60\)), donde variables como el área construida, el estrato y los parqueaderos impactan positivamente y de manera significativa en el precio.
  • Evaluación del Crédito: Al contrastar las condiciones con el mercado real, se observa que un presupuesto de 350 millones de pesos es ajustado pero viable para encontrar casas que se acerquen a los requerimientos, especialmente en estratos 4 en barrios del norte o zonas de expansión cercanas.
  • Recomendación para María: Se recomienda enfocar la búsqueda en las ofertas identificadas en el top 5 (como las ubicadas en barrios como Acopi, Chipichape o El Bosque dentro del rango de presupuesto), negociando directamente aquellos inmuebles que presenten mejores especificaciones de área y distribución.

3. Análisis del Caso 2: Vivienda en la Zona Sur (Apartamentos)

  • Condiciones de la solicitud: Apartamento en la Zona Sur, área construida de 300 m², 3 parqueaderos, 3 baños, 5 habitaciones, estrato 5 o 6, con un crédito preaprobado de 850 millones de pesos.
  • Análisis de Mercado y Modelo: El modelo para la Zona Sur presenta un excelente poder predictivo (\(R^2 \approx 0.75\)), evidenciando una fuerte prima en los precios asociada al estrato socioeconómico y al área construida en esta zona de la ciudad.
  • Evaluación del Crédito: Con un presupuesto de 850 millones de pesos, el cliente cuenta con un respaldo financiero muy sólido y competitivo. Las predicciones y el filtrado del mercado indican que este valor permite acceder a apartamentos amplios y de alta valorización en el sur.
  • Recomendación para María: El segmento de estrato 6 en el sector de Ciudad Jardín ofrece múltiples opciones que se adaptan al presupuesto. Se sugiere presentar las 5 alternativas seleccionadas en el mapa, resaltando aquellas que garanticen los 3 parqueaderos solicitados, una característica escasa y de alta demanda en el sur.

Anexos Técnicos: Estimaciones, Validaciones y Modelación

A continuación se presentan los códigos, salidas de los modelos econométricos, pruebas formales de supuestos y soportes cartográficos utilizados para respaldar el presente informe.

# --- CARGAR LIBRERÍAS ---
library(paqueteMODELOS)
library(dplyr)
library(knitr)
library(leaflet)

# CARGAR Y FILTRAR DATOS (Casas en Zona Norte)
data("vivienda", package = "paqueteMODELOS")

# Filtrar usando los nombres exactos de columnas
base1 <- vivienda %>% 
  filter(tipo == "Casa" & zona == "Zona Norte")

# 1. Mostrar los primeros 3 registros
cat("Primeros 3 registros de la Base 1 (Casas - Zona Norte):")
## Primeros 3 registros de la Base 1 (Casas - Zona Norte):
base1 %>% head(3) %>% kable()
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud
1209 Zona Norte 02 5 320 150 2 4 6 Casa acopi -76.51341 3.47968
1592 Zona Norte 02 5 780 380 2 3 3 Casa acopi -76.51674 3.48721
4057 Zona Norte 02 6 750 445 NA 7 6 Casa acopi -76.52950 3.38527
# 2. Tabla de comprobación
cat("\nComprobación del filtro (Conteo):")
## 
## Comprobación del filtro (Conteo):
base1 %>% 
  count(tipo, zona) %>% 
  kable()
tipo zona n
Casa Zona Norte 722
# 3. Mapa interactivo con Leaflet
leaflet(base1) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ~longitud, lat = ~latitud,
    radius = 4, color = "blue", stroke = FALSE, fillOpacity = 0.6,
    popup = paste("Precio:", base1$preciom, "Millones<br>",
                  "Área:", base1$areaconst, "m²")
  ) %>%
  addControl("<b>Casas - Zona Norte</b>", position = "topright")
library(plotly)

# 1. Gráfico de dispersión: Precio vs Área Construida según Estrato
p1 <- plot_ly(base1, x = ~areaconst, y = ~preciom, color = ~as.factor(estrato),
              type = 'scatter', mode = 'markers') %>%
  layout(title = "Precio vs Área Construida según Estrato")

p1
# 2. Gráfico de caja para ver la relación Precio vs Estrato
p2 <- plot_ly(base1, x = ~as.factor(estrato), y = ~preciom, type = 'box',
              color = ~as.factor(estrato)) %>%
  layout(title = "Distribución del Precio según el Estrato")

p2
#3: MODELO DE REGRESIÓN LINEAL MÚLTIPLE ---

modelo1 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base1)

# Resumen detallado del modelo
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
# 4.VALIDACIÓN DE SUPUESTOS (PRUEBAS FORMALES Y GRÁFICOS) ---

# Cargar librerías necesarias para pruebas formales
library(lmtest) # Para Breusch-Pagan y Durbin-Watson

# 1. Gráficos de diagnóstico estándar
par(mfrow = c(2, 2))
plot(modelo1)

par(mfrow = c(1, 1)) # Restaurar ventana

# 2. Supuesto de Normalidad de los Residuos
# Prueba de Shapiro-Wilk (H0: los residuos tienen distribución normal)
residuos <- residuals(modelo1)
shapiro_res <- shapiro.test(residuos)
print(shapiro_res)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuos
## W = 0.85246, p-value < 2.2e-16
# 3. Supuesto de Homocedasticidad (Varianza constante de los errores)
# Prueba de Breusch-Pagan (H0: los errores son homocedásticos)
bp_res <- bptest(modelo1)
print(bp_res)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo1
## BP = 80.281, df = 5, p-value = 7.33e-16
# 4. Supuesto de No Autocorrelación de los errores
# Prueba de Durbin-Watson (H0: no hay autocorrelación)
dw_res <- dwtest(modelo1)
print(dw_res)
## 
##  Durbin-Watson test
## 
## data:  modelo1
## DW = 1.7615, p-value = 0.005472
## alternative hypothesis: true autocorrelation is greater than 0
# 5: PREDICCIÓN PARA LA VIVIENDA

# Creamos un "data.frame" con las características solicitadas para la Vivienda 1
# (Asumir estrato 4 para la predicción en especifico)
nueva_vivienda1 <- data.frame(
  areaconst = 200,
  estrato = 4,
  habitaciones = 4,
  parqueaderos = 1,
  banios = 2
)

# Realizamos la predicción con su intervalo de confianza
prediccion_precio1 <- predict(modelo1, newdata = nueva_vivienda1, interval = "prediction")

print("Precio estimado (en millones) para la Vivienda 1:")
## [1] "Precio estimado (en millones) para la Vivienda 1:"
print(prediccion_precio1)
##       fit      lwr      upr
## 1 312.101 6.205196 617.9968
# 6: BÚSQUEDA DE OFERTAS POTENCIALES de maximo 350 millone

# Filtramos la base1 (Casas en Zona Norte) con las condiciones de presupuesto y características cercanas
# Estrato 4 o 5, precio menor o igual a 350 millones, y área cercana a 200m²
ofertas_potenciales1 <- base1 %>%
  filter(preciom <= 350, estrato %in% c(4, 5)) %>%
  arrange(desc(preciom)) # Ordenadas de mayor a menor precio (o como prefieras)

# Seleccionamos al menos 5 ofertas potenciales para presentar en la tabla y el mapa
top_5_ofertas1 <- head(ofertas_potenciales1, 5)

# Mostrar la tabla con las 5 ofertas seleccionadas
cat("Top 5 ofertas potenciales para la Solicitud 1:")
## Top 5 ofertas potenciales para la Solicitud 1:
top_5_ofertas1 %>% 
  select(barrio, preciom, areaconst, estrato, habitaciones, banios, parqueaderos) %>% 
  kable()
barrio preciom areaconst estrato habitaciones banios parqueaderos
acopi 350 118 4 3 3 NA
chipichape 350 98 4 4 3 2
el bosque 350 200 5 4 3 3
el bosque 350 300 5 6 5 3
el bosque 350 240 5 6 3 2
# Mapa interactivo con las 5 ofertas seleccionadas
leaflet(top_5_ofertas1) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ~longitud, lat = ~latitud,
    radius = 8, color = "green", stroke = FALSE, fillOpacity = 0.8,
    popup = paste("<b>Barrio:</b>", top_5_ofertas1$barrio, "<br>",
                  "<b>Precio:</b>", top_5_ofertas1$preciom, "Millones<br>",
                  "<b>Área:</b>", top_5_ofertas1$areaconst, "m²<br>",
                  "<b>Estrato:</b>", top_5_ofertas1$estrato)
  ) %>%
  addControl("<b>Top 5 Ofertas - Vivienda 1 (Zona Norte)</b>", position = "topright")
# ==========================================
# PASO 7: ANÁLISIS COMPLETO PARA VIVIENDA 2
# (Apartamentos en la Zona Sur)
# ==========================================

# --- 1. FILTRO Y MAPA INICIAL
base2 <- vivienda %>% 
  filter(tipo == "Apartamento" & zona == "Zona Sur")

cat("Primeros 3 registros de la Base 2 (Apartamentos - Zona Sur):")
## Primeros 3 registros de la Base 2 (Apartamentos - Zona Sur):
base2 %>% head(3) %>% kable()
id zona piso estrato preciom areaconst parqueaderos banios habitaciones tipo barrio longitud latitud
5098 Zona Sur 05 4 290 96 1 2 3 Apartamento acopi -76.53464 3.44987
698 Zona Sur 02 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
cat("\nComprobación del filtro (Conteo):")
## 
## Comprobación del filtro (Conteo):
base2 %>% count(tipo, zona) %>% kable()
tipo zona n
Apartamento Zona Sur 2787
# Mapa inicial de la Base 2
leaflet(base2) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ~longitud, lat = ~latitud,
    radius = 4, color = "purple", stroke = FALSE, fillOpacity = 0.6,
    popup = paste("Precio:", base2$preciom, "Millones<br>", "Área:", base2$areaconst, "m²")
  ) %>%
  addControl("<b>Apartamentos - Zona Sur</b>", position = "topright")
# --- 2 y 3. MODELO DE REGRESIÓN LINEAL MÚLTIPLE 
modelo2 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base2)

cat("\n--- Resumen del Modelo 2 ---")
## 
## --- Resumen del Modelo 2 ---
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
# --- 4. VALIDACIÓN DE SUPUESTOS
# Pruebas formales para la Base 2
library(lmtest)

shapiro_res2 <- shapiro.test(residuals(modelo2))
bp_res2 <- bptest(modelo2)
dw_res2 <- dwtest(modelo2)

print(shapiro_res2)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(modelo2)
## W = 0.79118, p-value < 2.2e-16
print(bp_res2)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo2
## BP = 754.81, df = 5, p-value < 2.2e-16
print(dw_res2)
## 
##  Durbin-Watson test
## 
## data:  modelo2
## DW = 1.5333, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
# --- 5. PREDICCIÓN PARA LA VIVIENDA 2 ---
nueva_vivienda2 <- data.frame(
  areaconst = 300,
  estrato = 5, # estrato 5 como base para la predicción
  habitaciones = 5,
  parqueaderos = 3,
  banios = 3
)

prediccion_precio2 <- predict(modelo2, newdata = nueva_vivienda2, interval = "prediction")

cat("\nPrecio estimado (en millones) para la Vivienda 2:")
## 
## Precio estimado (en millones) para la Vivienda 2:
print(prediccion_precio2)
##        fit     lwr      upr
## 1 675.0247 481.455 868.5945
# --- 6. BÚSQUEDA DE OFERTAS POTENCIALES (Máx 850 millones) ---
ofertas_potenciales2 <- base2 %>%
  filter(preciom <= 850, estrato %in% c(5, 6)) %>%
  arrange(desc(preciom))

top_5_ofertas2 <- head(ofertas_potenciales2, 5)

cat("\nTop 5 ofertas potenciales para la Solicitud 2:")
## 
## Top 5 ofertas potenciales para la Solicitud 2:
top_5_ofertas2 %>% 
  select(barrio, preciom, areaconst, estrato, habitaciones, banios, parqueaderos) %>% 
  kable()
barrio preciom areaconst estrato habitaciones banios parqueaderos
ciudad jardín 850 187.0 6 4 5 3
ciudad jardín 850 168.0 6 4 5 3
ciudad jardín 850 192.0 6 3 5 2
ciudad jardín 850 191.8 6 4 5 2
ciudad jardín 850 186.0 6 4 5 3
# Mapa interactivo con las 5 ofertas seleccionadas para la Vivienda 2
leaflet(top_5_ofertas2) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ~longitud, lat = ~latitud,
    radius = 8, color = "orange", stroke = FALSE, fillOpacity = 0.8,
    popup = paste("<b>Barrio:</b>", top_5_ofertas2$barrio, "<br>",
                  "<b>Precio:</b>", top_5_ofertas2$preciom, "Millones<br>",
                  "<b>Área:</b>", top_5_ofertas2$areaconst, "m²<br>",
                  "<b>Estrato:</b>", top_5_ofertas2$estrato)
  ) %>%
  addControl("<b>Top 5 Ofertas - Vivienda 2 (Zona Sur)</b>", position = "topright")