INTRODUCCIÓN

María inició su carrera como agente de bienes raíces en Cali hace diez años, y tras adquirir experiencia en Bogotá, decidió fundar su propia empresa, C&A (Casas y Apartamentos), en Cali, junto a dos excompañeros. Actualmente, lidera un equipo de ocho agentes. Aunque el mercado inmobiliario en Cali ha experimentado una baja este año, se espera una recuperación con la estabilización de la situación política y social. Recientemente, María recibió una solicitud de asesoría por parte de una empresa internacional interesada en adquirir dos viviendas para alojar a empleados y sus familias en la ciudad.

A — Zona Norte (Casa, crédito 350 millones)

Paso 1: Filtrar casas en zona norte

El mapa presentado corresponde a la visualización geográfica de las casas ubicadas en la zona norte de la ciudad de Cali. Utilizando la librería Leaflet en R, se representaron mediante círculos azules los puntos georreferenciados correspondientes a cada inmueble, con información emergente sobre el precio de cada propiedad.

data("vivienda")
nm <- names(vivienda)

find_col <- function(patterns, nm) {
  for (p in patterns) {
    m <- nm[str_detect(nm, regex(p, ignore_case = TRUE))]
    if (length(m) >= 1) return(m[1])
  }
  NA_character_
}

tipo_col    <- find_col(c("tipo", "property_type"), nm)
zona_col    <- find_col(c("zona", "sector", "region"), nm)
precio_col  <- find_col(c("preciom", "precio", "price", "valor"), nm)
area_col    <- find_col(c("areaconst", "area", "area_construida", "m2"), nm)
estrato_col <- find_col(c("estrato", "stratum"), nm)
cuartos_col <- find_col(c("habitaciones", "cuart", "habita", "rooms"), nm)
banos_col   <- find_col(c("banios", "bañ", "bano", "bath"), nm)
parq_col    <- find_col(c("parqueaderos", "parque", "parking"), nm)
lat_col     <- find_col(c("latitud", "lat", "latitude"), nm)
lon_col     <- find_col(c("longitud", "lon", "long"), nm)

base_norte_casas <- vivienda %>%
  filter(str_detect(tolower(.data[[tipo_col]]), "casa|house") &
         tolower(.data[[zona_col]]) == "zona norte")

Paso 2: Mapa de ubicación

En el grafico tiene un marcador de radio de 1, color azul y una opacidad de relleno del 70%, lo cual permite una visualización clara sin saturar el mapa. Además, se incluyó un control en la esquina superior derecha con la leyenda “Ubicación de Casas en Zona Norte” para contextualizar al usuario. Esta visualización es clave para identificar la concentración de propiedades en dicha zona y facilitar el análisis espacial del mercado inmobiliario.

leaflet(data = base_norte_casas) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = base_norte_casas[[lon_col]],
    lat = base_norte_casas[[lat_col]],
    popup = paste("Precio:", base_norte_casas[[precio_col]]),
    radius = 1, color = "blue", fillOpacity = 0.7
  ) %>%
  addControl("Ubicación de Casas en Zona Norte", position = "topright")

Paso 3: Análisis exploratorio (≤ 350 millones)

En este paso se realizó un análisis exploratorio de los datos correspondientes a las propiedades con un valor igual o inferior a 350 millones de pesos. Para ello, se filtraron las observaciones del conjunto de datos base_norte_casas y se seleccionaron variables predictoras relevantes como el área construida, estrato, número de baños, número de habitaciones y la zona. Posteriormente, se utilizó una visualización de tipo SPLOM (Scatterplot Matrix) para examinar gráficamente las relaciones bivariadas entre el precio y las variables seleccionadas.

El gráfico permite observar patrones de dispersión, tendencias lineales y posibles correlaciones. Por ejemplo, se evidencia una relación directa entre el precio y el área construida, así como una ligera asociación entre el precio y el número de habitaciones. Este análisis resulta fundamental para identificar variables predictoras clave que podrían ser utilizadas en modelos de valoración o predicción del precio de vivienda en este segmento del mercado.

ofertas_350 <- base_norte_casas %>%
  filter(.data[[precio_col]] <= 350000000)

eda_vars <- c(precio_col, area_col, estrato_col, banos_col, cuartos_col, zona_col)
eda_vars <- eda_vars[!is.na(eda_vars) & eda_vars %in% names(ofertas_350)]

eda_df <- ofertas_350 %>%
  select(all_of(eda_vars)) %>%
  na.omit()

plot_ly(type = 'splom', data = eda_df,
        dimensions = lapply(eda_vars[1:5], function(colname) list(label = colname, values = ~ get(colname))),
        marker = list(size = 5, color = 'rgba(255, 140, 0, 0.5)')) %>%
  layout(title = "Relaciones entre Precio y Variables Predictoras (≤ 350M)")

Paso 4: Modelo de regresión

En esta etapa se construyó un modelo de regresión lineal múltiple para predecir el precio de las casas en la zona norte de Cali, utilizando como variables explicativas: área construida, estrato, número de cuartos, número de parqueaderos y número de baños. El modelo se ajustó con la función lm() sobre el conjunto de datos base_norte_casas.

Los resultados muestran que las variables área construida, estrato, parqueaderos y baños son estadísticamente significativas (p < 0.05), mientras que el número de habitaciones no mostró significancia. La variable con mayor influencia positiva sobre el precio es el área construida, con un coeficiente de 0.6767, lo que indica que por cada unidad adicional en área, el precio estimado aumenta en promedio 0.68 millones de pesos. El modelo presenta un R² ajustado de 0.5995, lo cual sugiere que aproximadamente el 60% de la variabilidad del precio puede explicarse por las variables incluidas en el modelo. En conclusión, el modelo es estadísticamente significativo (p < 2.2e-16) y proporciona una base útil para realizar estimaciones de precios en el mercado inmobiliario del sector analizado.

predictoras <- c(area_col, estrato_col, cuartos_col, parq_col, banos_col)
predictoras <- predictoras[!is.na(predictoras) & predictoras %in% names(base_norte_casas)]

formula_mod <- as.formula(paste0("`", precio_col, "` ~ ", paste0("`", predictoras, "`", collapse = " + ")))
modelo_norte <- lm(formula_mod, data = base_norte_casas)
summary(modelo_norte)
## 
## Call:
## lm(formula = formula_mod, data = base_norte_casas)
## 
## 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

Paso 5: Validación de supuestos

GRAFICO: Residuos vs Valores Ajustados

En este paso se realiza la validación de los supuestos del modelo de regresión lineal mediante el análisis gráfico de los residuos vs valores ajustados. El gráfico permite verificar si los errores del modelo cumplen con los supuestos de homocedasticidad (varianza constante) y linealidad.

En la visualización se observa una cierta dispersión no homogénea de los residuos, especialmente en los valores ajustados más altos, donde hay mayor variabilidad y presencia de residuos extremos. Esto sugiere una posible violación del supuesto de homocedasticidad, ya que la varianza de los errores no parece mantenerse constante en todo el rango de valores predichos. No se evidencia una forma clara o patrón en los residuos, lo cual es positivo para el supuesto de linealidad. Sin embargo, la presencia de outliers también podría estar afectando la precisión del modelo.

QQ Plot de Residuos

Además del análisis gráfico, se realizaron pruebas estadísticas para validar los supuestos del modelo de regresión aplicado a las viviendas de la zona norte:

Normalidad de los residuos:

El QQ plot de residuos muestra una desviación respecto a la línea teórica, especialmente en los extremos, lo que sugiere la presencia de outliers y una distribución no completamente normal.

Esto se confirma con el test de Shapiro-Wilk, cuyo estadístico W = 0.8526 y valor-p < 2.2e-16 indica una violación significativa del supuesto de normalidad.

Homoscedasticidad (igual varianza):

El test de Breusch-Pagan reporta un valor-p de 7.33e-16, lo que indica evidencia significativa de heterocedasticidad. Es decir, los residuos no presentan varianza constante, afectando la fiabilidad de los errores estándar del modelo.

Independencia de los errores:

El test de Durbin-Watson entrega un estadístico de 1.76 con un valor-p de 0.824, por lo que no se encuentra evidencia suficiente para rechazar la hipótesis nula de ausencia de autocorrelación. Esto sugiere que los errores son independientes entre sí, cumpliendo este supuesto.

res <- resid(modelo_norte)
fitted <- fitted(modelo_norte)

ggplot(data.frame(res, fitted), aes(x = fitted, y = res)) +
  geom_point() + geom_hline(yintercept = 0, linetype = 2) + theme_minimal() +
  ggtitle("Residuos vs Valores Ajustados — Zona Norte")

ggplot(data.frame(res), aes(sample = res)) +
  stat_qq() + stat_qq_line() + theme_minimal() +
  ggtitle("QQ Plot de Residuos — Zona Norte")

shapiro.test(res)
## 
##  Shapiro-Wilk normality test
## 
## data:  res
## W = 0.85246, p-value < 2.2e-16
bptest(modelo_norte)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo_norte
## BP = 80.281, df = 5, p-value = 7.33e-16
durbinWatsonTest(modelo_norte)
##  lag Autocorrelation D-W Statistic p-value
##    1       0.1173407      1.761505    0.02
##  Alternative hypothesis: rho != 0

Paso 6: Predicción y ofertas sugeridas

En este último paso se realizó una predicción del precio de una vivienda nueva con características específicas: 200 m² de área construida, estrato 4, 4 habitaciones, 1 parqueadero y 2 baños. Usando el modelo de regresión ajustado previamente, se estimó que el valor aproximado de esta vivienda sería de 312.101 millones de pesos.

Posteriormente, con base en este valor estimado, se identificaron las cinco ofertas más cercanas en precio dentro del conjunto de datos de viviendas de la zona norte, filtrando aquellas con un valor menor o igual a 350 millones. Estas propiedades se visualizaron en un mapa interactivo mediante la librería Leaflet, destacadas con marcadores azules. Al hacer clic sobre cada punto, se puede consultar el precio correspondiente de la propiedad.

Esta visualización permite a los interesados comparar el valor estimado de su propiedad con opciones reales disponibles en el mercado, facilitando la toma de decisiones de compra o inversión en función de ubicación y precio.

nueva_vivienda <- data.frame(
  `area_construida` = 200,
  `estrato`= 4,
  `habitaciones` = 4,
  `parqueaderos` = 1,
  `banos` = 2
)
names(nueva_vivienda) <- predictoras
predict(modelo_norte, newdata = nueva_vivienda)
##       1 
## 312.101
ofertas_potenciales <- base_norte_casas %>%
  filter(.data[[precio_col]] <= 350000000) %>%
  arrange(.data[[precio_col]]) %>%
  slice_head(n = 5)

leaflet(data = ofertas_potenciales) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ofertas_potenciales[[lon_col]],
    lat = ofertas_potenciales[[lat_col]],
    popup = paste("Precio:", formatC(ofertas_potenciales[[precio_col]], format = "f", big.mark = ",", digits = 0)),
    radius = 6, color = "blue", fillOpacity = 0.8
  ) %>%
  addControl("Ofertas Sugeridas — Zona Norte", position = "topright")

B — Zona Sur (Apartamento, crédito 850 millones)

Paso 1: Filtrar apartamentos en zona sur

En punto corresponde a la búsqueda de un apartamento en la zona sur de Cali con un presupuesto de hasta 850 millones de pesos, se realizó un filtrado inicial del conjunto de datos. Este proceso seleccionó únicamente aquellas propiedades que fueran clasificadas como apartamento y que estuvieran ubicadas en la zona sur de la ciudad.

base_sur_apart <- vivienda %>%
  filter(str_detect(tolower(.data[[tipo_col]]), "apartamento|apartment") &
         tolower(.data[[zona_col]]) == "zona sur")

Paso 2: Mapa de ubicación

Posteriormente, se generó un mapa de ubicación con la herramienta Leaflet, donde se visualizan los apartamentos filtrados mediante puntos naranjas, cada uno representando una propiedad. Al interactuar con los puntos del mapa, se puede consultar el precio específico de cada apartamento. Esta representación geográfica permite identificar rápidamente la distribución espacial de las ofertas y facilita la evaluación de opciones en función de su ubicación, en el marco del crédito disponible para la compra.

leaflet(data = base_sur_apart) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = base_sur_apart[[lon_col]],
    lat = base_sur_apart[[lat_col]],
    popup = paste("Precio:", base_sur_apart[[precio_col]]),
    radius = 1, color = "orange", fillOpacity = 0.7
  ) %>%
  addControl("Ubicación de Apartamentos en Zona Sur", position = "topright")

Paso 3: Análisis exploratorio (≤ 850 millones)

En este paso se realizó un análisis exploratorio de los apartamentos ubicados en la zona sur cuyo precio es igual o inferior a 850 millones de pesos, con el fin de entender mejor las relaciones entre el precio y las variables predictoras disponibles: área construida, estrato, número de baños, habitaciones y zona.

A través de un gráfico de dispersión múltiple (splom), se evidencian algunas tendencias clave:

Existe una relación positiva clara entre el precio y el área construida, es decir, a mayor área, mayor es el precio del apartamento.

El estrato también muestra una tendencia creciente con el precio, lo que indica que propiedades en estratos más altos suelen tener mayor valor.

Las variables baños y habitaciones también presentan asociaciones positivas, aunque menos definidas, con el precio.

La mayor concentración de ofertas se encuentra en rangos de precios entre 200 y 600 millones, lo que puede ser relevante para acotar la búsqueda en el rango presupuestal disponible.

Este análisis permite identificar patrones clave en el mercado del sur de la ciudad y facilitar la construcción de un modelo predictivo más robusto en pasos posteriores.

ofertas_850 <- base_sur_apart %>%
  filter(.data[[precio_col]] <= 850000000)

eda_vars <- c(precio_col, area_col, estrato_col, banos_col, cuartos_col, zona_col)
eda_vars <- eda_vars[!is.na(eda_vars) & eda_vars %in% names(ofertas_850)]

eda_df <- ofertas_850 %>%
  select(all_of(eda_vars)) %>%
  na.omit()

plot_ly(type = 'splom', data = eda_df,
        dimensions = lapply(eda_vars[1:5], function(colname) list(label = colname, values = ~ get(colname))),
        marker = list(size = 5, color = 'rgba(0, 150, 255, 0.5)')) %>%
  layout(title = "Relaciones entre Precio y Variables Predictoras (≤ 850M)")

Paso 4: Modelo de regresión

En esta etapa se construyó un modelo de regresión lineal múltiple para estimar el precio de los apartamentos en la zona sur de Cali, utilizando como variables predictoras: área construida, estrato, número de habitaciones, parqueaderos y baños.

Los resultados del modelo indican lo siguiente:

Todas las variables son estadísticamente significativas (p < 0.001), lo que confirma su relevancia en la predicción del precio.

El área construida tiene el mayor impacto positivo en el precio, seguida de los baños y parqueaderos.

Curiosamente, el número de habitaciones muestra un coeficiente negativo, lo que podría indicar que, manteniendo las demás variables constantes, más habitaciones podrían asociarse con una reducción del precio, posiblemente por efectos de distribución interna o ubicación.

El coeficiente de estrato también muestra un efecto positivo importante sobre el precio.

En cuanto a la calidad del modelo:

El R-cuadrado ajustado es de 0.748, lo que indica que el modelo explica aproximadamente el 75% de la variabilidad del precio, lo cual es una muy buena capacidad predictiva para un modelo lineal.

El error estándar residual es de 98.02, lo que indica una dispersión relativamente controlada en las predicciones.

El modelo fue ajustado sobre 2.376 observaciones (tras eliminar casos con datos faltantes) y es altamente significativo (valor-p < 2.2e-16).

Este modelo ofrece una base sólida para estimar precios de apartamentos en la zona sur y será útil para generar recomendaciones de compra en función del crédito disponible.

predictoras <- c(area_col, estrato_col, cuartos_col, parq_col, banos_col)
predictoras <- predictoras[!is.na(predictoras) & predictoras %in% names(base_sur_apart)]

formula_mod <- as.formula(paste0("`", precio_col, "` ~ ", paste0("`", predictoras, "`", collapse = " + ")))
modelo_sur <- lm(formula_mod, data = base_sur_apart)
summary(modelo_sur)
## 
## Call:
## lm(formula = formula_mod, data = base_sur_apart)
## 
## 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

Paso 5: Validación de supuestos

En el Paso 5 para la Zona Sur, la validación de supuestos muestra que los residuos presentan cierta dispersión creciente en valores ajustados altos, lo que indica posible heterocedasticidad, y el QQ plot revela desviaciones de la normalidad en los extremos, señalando que los residuos no siguen completamente una distribución normal. Estos hallazgos sugieren que, aunque el modelo es adecuado, podría beneficiarse de ajustes o transformaciones para mejorar la precisión y cumplir mejor con los supuestos del modelo lineal.

En el análisis de validación de supuestos para el modelo de la Zona Sur, el gráfico QQ muestra que los residuos se desvían de la línea diagonal en los extremos, indicando que no siguen una distribución normal. Esto se confirma con la prueba de Shapiro-Wilk, que reporta un valor W de 0.79118 y un p-valor menor a 2.2e-16, rechazando la normalidad. Además, la prueba de Breusch-Pagan revela heterocedasticidad con un valor BP de 754.81 y un p-valor también menor a 2.2e-16. Por último, la prueba de Durbin-Watson muestra una estadística cercana a 2, sugiriendo que no hay autocorrelación significativa en los residuos. En resumen, aunque no se cumple la normalidad ni la homocedasticidad, no hay evidencia de autocorrelación.

res <- resid(modelo_sur)
fitted <- fitted(modelo_sur)

ggplot(data.frame(res, fitted), aes(x = fitted, y = res)) +
  geom_point() + geom_hline(yintercept = 0, linetype = 2) + theme_minimal() +
  ggtitle("Residuos vs Valores Ajustados — Zona Sur")

ggplot(data.frame(res), aes(sample = res)) +
  stat_qq() + stat_qq_line() + theme_minimal() +
  ggtitle("QQ Plot de Residuos — Zona Sur")

shapiro.test(res)
## 
##  Shapiro-Wilk normality test
## 
## data:  res
## W = 0.79118, p-value < 2.2e-16
bptest(modelo_sur)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo_sur
## BP = 754.81, df = 5, p-value < 2.2e-16
durbinWatsonTest(modelo_sur)
##  lag Autocorrelation D-W Statistic p-value
##    1       0.2314604      1.533316       0
##  Alternative hypothesis: rho != 0

Paso 6: Predicción y ofertas sugeridas

En el paso de predicción para la Zona Sur, se estima que un apartamento con 300 metros cuadrados, estrato 5, 3 habitaciones, 2 parqueaderos y 3 baños tendría un precio aproximado de 651.7839 millones. Además, se filtran las ofertas potenciales con un precio menor a 850 millones para mostrar opciones accesibles dentro del rango de interés. En el mapa interactivo se visualizan estas ofertas sugeridas, destacadas con marcadores naranjas, facilitando la ubicación y comparación de las propiedades dentro de la zona. Esto permite una toma de decisión informada basada en las predicciones del modelo y la disponibilidad real del mercado.

nuevo_apartamento <- data.frame(
  `area_construida` = 300,
  `estrato` = 5,
  `habitaciones` = 3,
  `parqueaderos` = 2,
  `banos` = 3
)
names(nuevo_apartamento) <- predictoras
predict(modelo_sur, newdata = nuevo_apartamento)
##        1 
## 651.7839
ofertas_potenciales <- base_sur_apart %>%
  filter(.data[[precio_col]] <= 850000000) %>%
  arrange(.data[[precio_col]]) %>%
  slice_head(n = 5)

leaflet(data = ofertas_potenciales) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ofertas_potenciales[[lon_col]],
    lat = ofertas_potenciales[[lat_col]],
    popup = paste("Precio:", formatC(ofertas_potenciales[[precio_col]], format = "f", big.mark = ",", digits = 0)),
    radius = 6, color = "orange", fillOpacity = 0.8
  ) %>%
  addControl("Ofertas Sugeridas — Zona Sur", position = "topright")

CONCLUSIONES

El análisis realizado para las zonas Norte y Sur permitió construir modelos de regresión lineal para predecir los precios de viviendas y apartamentos, con base en variables como área construida, estrato, número de habitaciones, parqueaderos y baños. En ambas zonas, los modelos presentaron un buen ajuste, con valores de R-cuadrado ajustado superiores al 0.60, lo que indica que las variables seleccionadas explican una parte significativa de la variabilidad en los precios. Sin embargo, la validación de supuestos mostró que los residuos no cumplen completamente con la normalidad ni la homocedasticidad, evidenciando posibles limitaciones en el modelo que podrían mejorarse mediante transformaciones o modelos más complejos. Los análisis gráficos y las pruebas estadísticas, como el test de Shapiro-Wilk para normalidad, el test de Breusch-Pagan para heterocedasticidad y el test de Durbin-Watson para autocorrelación, confirmaron estas observaciones. A pesar de estas limitaciones, el modelo es útil para realizar predicciones y sugerir ofertas de vivienda dentro de rangos de precio específicos, facilitando la toma de decisiones para potenciales compradores en cada zona. Además, los mapas interactivos permiten visualizar geográficamente las propiedades recomendadas, mejorando la aplicabilidad práctica del análisis. Finalmente, se recomienda explorar modelos alternativos o la inclusión de variables adicionales que puedan capturar mejor la complejidad del mercado inmobiliario, con el fin de obtener predicciones más precisas y robustas.

Estos fueron los inmuebles escogidos para la compra, con marcador azul para el crédito de 350 millones en la Zona Norte y marcador naranja para el crédito de 850 millones en la Zona Sur. Las ubicaciones reflejan las mejores ofertas sugeridas basadas en los modelos de regresión y los filtros aplicados, considerando características como área construida, estrato, número de habitaciones, parqueaderos y baños, optimizando así la inversión de acuerdo con el presupuesto y las preferencias establecidas.