1 Informe Ejecutivo

1.1 Contexto y Alcance

La agencia C&A ha recibido una solicitud formal de una compañía internacional que requiere reubicar a dos de sus empleados en la ciudad de Cali. Cada solicitud tiene características habitacionales específicas y un límite de crédito preaprobado diferente. Con base en el análisis de regresión lineal múltiple aplicado sobre datos reales del mercado inmobiliario de Cali, este informe presenta las recomendaciones de valor para cada caso.

1.2 Recomendación Vivienda 1 — Casa, Zona Norte ($350 Millones)

El modelo estimado para casas en la Zona Norte (R² = 0.66) indica que el área construida y el estrato son los principales determinantes del precio. Para una casa de 200 m², 4 habitaciones, 2 baños y 1 parqueadero, el modelo proyecta:

  • Estrato 4: precio estimado de $317.73 millonesdentro del presupuesto preaprobado.
  • Estrato 5: precio estimado de $396.45 millonessupera el presupuesto disponible.

Recomendación: Concentrar la búsqueda en propiedades de estrato 4 en la Zona Norte. Se identificaron 5 ofertas reales en la base de datos que cumplen simultáneamente con el presupuesto y las características habitacionales requeridas, ubicadas principalmente en los barrios San Vicente, Vipasa y El Bosque, con áreas entre 300 m² y 355 m².

Tabla IE-1: Top 5 Ofertas Recomendadas — Vivienda 1 (Casas Zona Norte ≤ $350 M)
Barrio Estrato Precio (M) Área (m²) Habitaciones Baños
San Vicente 5 340 355 8 5
Salomia 4 350 350 5 4
Vipasa 5 350 346 4 2
El Bosque 5 350 300 6 5
Salomia 4 340 295 4 2
Nota: Ver Tabla 5 (Paso 6 - Vivienda 1) para el detalle completo con IDs.

Calidad de datos: Durante la validación espacial se detectaron coordenadas inconsistentes en algunos registros clasificados como “Zona Norte”. Se recomienda verificar físicamente la ubicación de las propiedades antes de concretar visitas.

1.3 Recomendación Vivienda 2 — Apartamento, Zona Sur ($850 Millones)

El modelo estimado para apartamentos en la Zona Sur presenta un ajuste superior (R² = 0.76). Para un apartamento de 300 m², 5 habitaciones, 3 baños y 3 parqueaderos, el modelo proyecta:

  • Estrato 5: precio estimado de $698.14 millonesdentro del presupuesto preaprobado.
  • Estrato 6: precio estimado de $755.58 millonesdentro del presupuesto preaprobado.

Recomendación: Ambos escenarios son financieramente viables. Se recomienda priorizar la búsqueda en estrato 6, ya que ofrece mayor exclusividad residencial sin comprometer el presupuesto disponible. Se identificaron 5 ofertas reales, destacándose propiedades en El Ingenio, Guadalupe y Cuarto de Legua, con áreas de hasta 600 m² y precios inferiores a $730 millones.

Tabla IE-2: Top 5 Ofertas Recomendadas — Vivienda 2 (Apartamentos Zona Sur ≤ $850 M)
Barrio Estrato Precio (M) Área (m²) Habitaciones Baños
El Ingenio 5 650 600 5 4
Guadalupe 5 730 573 5 8
El Ingenio 5 690 486 4 4
Cuarto De Legua 5 520 320 4 4
Seminario 5 670 300 6 5
Nota:Ver Tabla 8 (Paso 6 - Vivienda 2) para el detalle completo con IDs.

Calidad de datos: Al igual que en la Base 1, se detectaron coordenadas inconsistentes en registros de la Zona Sur. Se aplicaron filtros espaciales adicionales (latitud < 3.42) para garantizar que las ofertas recomendadas correspondan efectivamente a la ubicación solicitada.


2 Informe de Aplicación de Regresión Lineal

2.1 Descripción

El presente informe detalla el proceso de análisis de datos y modelación estadística desarrollado para la agencia de bienes raíces C&A, ubicada en la ciudad de Cali.

Ante la solicitud de una compañía internacional para reubicar a dos de sus empleados, se requiere identificar propiedades que cumplan con características habitacionales específicas y límites de crédito preaprobado ($350 millones y $850 millones, respectivamente). Para dar respuesta a este requerimiento, se implementan técnicas de Regresión Lineal Múltiple que permiten entender la dinámica de precios del mercado inmobiliario local. El documento abarca desde el filtrado espacial y análisis exploratorio de las propiedades, hasta la estimación de modelos predictivos, la validación de sus supuestos estadísticos y la recomendación final georreferenciada de las mejores ofertas disponibles en el mercado para cada perfil.

2.2 Objetivo General

Desarrollar modelos predictivos de Regresión Lineal Múltiple para estimar el precio de viviendas en la ciudad de Cali, con el fin de formular recomendaciones inmobiliarias estratégicas y georreferenciadas que cumplan con los requerimientos técnicos y las restricciones presupuestales de dos solicitudes específicas de reubicación corporativa.

2.3 Objetivos Específicos

  • Depurar y validar espacialmente los datos: Filtrar la base de datos inmobiliaria según el tipo de vivienda y zona geográfica requerida para cada solicitud.

  • Explorar la relación entre variables: Ejecutar un análisis exploratorio de datos (EDA) utilizando herramientas para evaluar la correlación entre el precio de las propiedades y sus características físicas (área, estrato, baños, habitaciones y zona).

  • Estimar e interpretar modelos predictivos: Construir modelos de regresión lineal múltiple para determinar el impacto de las características estructurales sobre el precio, analizando los coeficientes y el ajuste general (R-cuadrado).

  • Validar la robustez de los modelos: Evaluar el cumplimiento de los supuestos estadísticos subyacentes a la regresión lineal, identificando posibles desviaciones.

  • Generar predicciones y recomendaciones de valor: Predecir el valor de mercado de los inmuebles solicitados y seleccionar las 5 mejores ofertas potenciales por caso que se ajusten al crédito preaprobado, presentándolas de manera visual para facilitar la toma de decisiones.

El plan de trabajo y metodología aplicados en este ejercicio se encuentra especificado en el Anexo 1.


2.4 Modelación y Validación Técnica

Esta sección contiene todos los outputs técnicos del proceso de modelación estadística: resúmenes completos de los modelos estimados, gráficos de diagnóstico de residuos, valores VIF de multicolinealidad y los registros del proceso de carga y limpieza de datos. Todo el código R utilizado está disponible en los bloques de código del documento. Así mismo se cuenta con un resumen de los resultados en el Anexo 2.

2.4.1 Datos

El conjunto de datos utilizado en este estudio fue analizado previamente en el informe “Análisis del Mercado Inmobiliario Urbano” (https://rpubs.com/rflorezb/1397871), donde se realizó una primera exploración de la base de datos y sus variables. En esta sección tomaremos esos resultados como punto de partida para el preprocesamiento o preparación de los datos antes de la construcción de las bases requeridas por el ejercicio.

La fuente de datos para realizar este ejercicio proviene de datos tomados de OLX mediante procedimiento webscraping.

#Cargue de la base de datos
#install.packages("devtools")
#devtools::install_github("centromagis/paqueteMODELOS", force =TRUE)
library(paqueteMODELOS)
data("vivienda")
#str(vivienda)

A partir de esta fuente de datos generamos la Tabla 1 que contiene el nombre de la variable, su naturaleza y una breve descripción de la misma. Adicionalmente sub-agrupamos estas variables para un mejor conocimiento de su distribución.

# 3. Creación del diccionario de datos
tabla_descriptiva = tibble::tribble(
  ~`Nombre de la Variable`, ~`Descripción`, ~`Naturaleza`,
  
  # Variables de Identificación y Ubicación Geográfica
  "id", "Identificador único del inmueble en la base de datos", "Cualitativa Nominal",
  "zona", "Zona macro de la ciudad donde se ubica el inmueble", "Cualitativa Nominal",
  "barrio", "Nombre del barrio específico donde se ubica la vivienda", "Cualitativa Nominal",
  "longitud", "Coordenada geográfica (longitud) para mapeo espacial", "Cuantitativa Continua",
  "latitud", "Coordenada geográfica (latitud) para mapeo espacial", "Cuantitativa Continua",
  
  # Variables Socioeconómicas y de Valoración
  "estrato", "Clasificación socioeconómica del sector (escala del 1 al 6)", "Cualitativa Ordinal",
  "preciom", "Precio de oferta de la vivienda (en millones de pesos)", "Cuantitativa Continua",
  
  # Variables Estructurales y Físicas del Inmueble
  "tipo", "Clasificación arquitectónica de la vivienda (Casa o Apartamento)", "Cualitativa Nominal",
  "areaconst", "Área total construida del inmueble en metros cuadrados", "Cuantitativa Continua",
  "habitaciones", "Número de habitaciones o alcobas disponibles", "Cuantitativa Discreta",
  "banios", "Número de baños disponibles en el inmueble", "Cuantitativa Discreta",
  "parqueaderos", "Cantidad de espacios de estacionamiento (garajes)", "Cuantitativa Discreta",
  "piso", "Nivel o piso en el que se ubica el inmueble", "Cualitativa Ordinal"
)

# 4. Formato y renderizado de la tabla profesional
tabla_descriptiva %>%
  knitr::kable(
    col.names = c("Nombre de la Variable", "Descripción", "Naturaleza"),
    align = c('l', 'l', 'c') # Alineación: izquierda, izquierda, centro
  ) %>%
  kableExtra::kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  pack_rows("Identificación y Ubicación", 1, 5) %>%
  pack_rows("Socioeconómicas y Valoración", 6, 7) %>%
  pack_rows("Estructurales del Inmueble", 8, 13) %>%
  footnote(
    general = "Tabla 1: Diccionario de datos y naturaleza estadística de las variables del mercado inmobiliario.",
    general_title = ""
  )
Nombre de la Variable Descripción Naturaleza
Identificación y Ubicación
id Identificador único del inmueble en la base de datos Cualitativa Nominal
zona Zona macro de la ciudad donde se ubica el inmueble Cualitativa Nominal
barrio Nombre del barrio específico donde se ubica la vivienda Cualitativa Nominal
longitud Coordenada geográfica (longitud) para mapeo espacial Cuantitativa Continua
latitud Coordenada geográfica (latitud) para mapeo espacial Cuantitativa Continua
Socioeconómicas y Valoración
estrato Clasificación socioeconómica del sector (escala del 1 al 6) Cualitativa Ordinal
preciom Precio de oferta de la vivienda (en millones de pesos) Cuantitativa Continua
Estructurales del Inmueble
tipo Clasificación arquitectónica de la vivienda (Casa o Apartamento) Cualitativa Nominal
areaconst Área total construida del inmueble en metros cuadrados Cuantitativa Continua
habitaciones Número de habitaciones o alcobas disponibles Cuantitativa Discreta
banios Número de baños disponibles en el inmueble Cuantitativa Discreta
parqueaderos Cantidad de espacios de estacionamiento (garajes) Cuantitativa Discreta
piso Nivel o piso en el que se ubica el inmueble Cualitativa Ordinal
Tabla 1: Diccionario de datos y naturaleza estadística de las variables del mercado inmobiliario.

A partir de la Tabla 1 observamos que el conjunto de datos se compone de 4 variables cualitativas nominales, 2 cualitativas ordinales, 4 cuantitativas continuas y 3 cuantitativas discretas.

2.4.1.1 Exploración Inicial Dataset

A continuación, se desarrolla una exploración del conjunto de datos con el objetivo de comprender su estructura, evaluar la calidad de la información disponible y observar su comportamiento general. Durante esta etapa se examinan las variables de manera descriptiva, lo que permite identificar posibles valores atípicos, patrones iniciales y posibles inconsistencias en los registros.

# Calcular cantidad y porcentaje de nulos por variable
nulos_df <- data.frame(
  Variable = names(vivienda),
  Nulos = colSums(is.na(vivienda)),
  Porcentaje = round((colSums(is.na(vivienda)) / nrow(vivienda)) * 100, 2)
) %>%
  # Ordenar de mayor a menor cantidad de nulos
  arrange(desc(Nulos))

# Renderizar la tabla para el informe
nulos_df %>%
  knitr::kable(
    col.names = c("Variable", "Cantidad de Nulos", "Porcentaje (%)"),
    align = c('l', 'c', 'c'),
    row.names = FALSE
  ) %>%
  kableExtra::kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  kableExtra::footnote(
    general = "Tabla 2: Cuantificación y proporción de valores nulos por variable en la base de datos.",
    general_title = ""
  )
Variable Cantidad de Nulos Porcentaje (%)
piso 2638 31.70
parqueaderos 1605 19.29
id 3 0.04
zona 3 0.04
estrato 3 0.04
areaconst 3 0.04
banios 3 0.04
habitaciones 3 0.04
tipo 3 0.04
barrio 3 0.04
longitud 3 0.04
latitud 3 0.04
preciom 2 0.02
Tabla 2: Cuantificación y proporción de valores nulos por variable en la base de datos.

Como se observa en la Tabla 2, la evaluación de la calidad de los datos revela la presencia de valores nulos que deben ser considerados antes del proceso de modelamiento estadístico. En primer lugar, se identifica un patrón consistente de tres registros faltantes en la mayoría de las variables, lo que sugiere la posible presencia de filas completamente vacías desde el origen de la base de datos. Adicionalmente, la variable piso presenta la mayor proporción de valores ausentes (31.70%). Este comportamiento podría explicarse por la naturaleza de ciertos inmuebles, como las casas de una sola planta, donde dicha característica no resulta aplicable. Por último, la variable parqueaderos registra un 19.29% de valores faltantes.

2.4.1.2 Detección de Valores Atípicos

Para complementar el análisis exploratorio, se examina la presencia de valores atípicos en las variables cuantitativas. La identificación de estas observaciones es importante, ya que valores extremos en variables como precio o área pueden influir de manera significativa en los resultados del modelo de regresión lineal múltiple.

# Seleccionar solo las variables numéricas de interés
vivienda_num <- vivienda %>%
  select(preciom, areaconst, habitaciones, banios, parqueaderos)

# Transformar los datos a formato largo para graficarlos juntos con ggplot2
vivienda_larga <- vivienda_num %>%
  pivot_longer(cols = everything(), names_to = "Variable", values_to = "Valor")

# Crear los diagramas de caja (Boxplots)
ggplot(vivienda_larga, aes(x = Variable, y = Valor, fill = Variable)) +
  geom_boxplot(outlier.colour = "red", outlier.shape = 16, outlier.size = 2, alpha = 0.7) +
  facet_wrap(~ Variable, scales = "free", ncol = 3) +
  theme_minimal() +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title = "Figura 1: Distribución y Valores Atípicos por Variable Numérica",
    subtitle = "",
    x = "",
    y = "Valor"
  )

Como se observa en la Figura 1, las variables numéricas presentan una asimetría positiva, especialmente preciom y areaconst, donde la mayoría de las propiedades se concentra en rangos medios, mientras que un pequeño grupo de valores muy altos genera colas largas hacia la derecha. Esto sugiere que el mercado está compuesto tanto por viviendas estándar como por un segmento reducido de alto valor.

En las variables de diseño (habitaciones, banios y parqueaderos) se observa una mayor concentración alrededor de configuraciones típicas, aunque también aparecen algunos valores extremos que podrían corresponder a propiedades de lujo o a posibles inconsistencias en los datos. En conjunto, la presencia de dispersión y valores atípicos sugiere la existencia de distintos segmentos del mercado, por lo que será importante considerar su posible influencia en la estimación y el ajuste del modelo de regresión lineal múltiple.

2.4.1.3 Tratamiento y Depuración

Con base en los hallazgos del diagnóstico exploratorio (Tabla 2 y Figura 1), se procede a realizar un proceso de limpieza y preparación de los datos previo al modelamiento. La consistencia de la matriz de datos es un requisito fundamental para la regresión lineal múltiple, ya que valores faltantes, inconsistencias o registros atípicos pueden afectar la estimación de los coeficientes y el ajuste del modelo.

En esta fase se aplican cuatro criterios de depuración:

*1. Nulos totales: se eliminan las observaciones completamente vacías presentes desde el origen de la base de datos.

*2. Datos atípicos: se excluyen registros que carecen de sentido dentro del mercado de vivienda urbana, como propiedades reportadas con 0 habitaciones o 0 baños. Estos casos podrían corresponder a otros tipos de inmuebles (locales, oficinas o lotes) que introducirían ruido en el análisis del mercado residencial.

*3. Imputación: los valores faltantes de la variable parqueaderos (19.29%) se imputan utilizando la mediana condicionada por estrato y tipo de vivienda, con el fin de preservar la representatividad de la muestra.

*4. Ajuste categórico: los valores faltantes de la variable piso se recodifican como “No Aplica” para las viviendas tipo casa, en coherencia con la hipótesis planteada durante el análisis exploratorio.

# 1. Eliminación de registros con nulos estructurales (las 3 filas vacías)
vivienda_limpia <- vivienda %>%
  filter(!is.na(id) & !is.na(preciom))

# 2. Corrección de inconsistencias lógicas (observadas en los outliers)
vivienda_limpia <- vivienda_limpia %>%
  filter(habitaciones > 0, banios > 0) 

# 3. Imputación de la variable 'parqueaderos' usando la mediana agrupada
vivienda_limpia <- vivienda_limpia %>%
  group_by(estrato, tipo) %>%
  mutate(
    parqueaderos = ifelse(is.na(parqueaderos), 
                          median(parqueaderos, na.rm = TRUE), 
                          parqueaderos)
  ) %>%
  ungroup()

# 4. Tratamiento de la variable categórica 'piso'
vivienda_limpia <- vivienda_limpia %>%
  mutate(
    piso = ifelse(is.na(piso) & tipo == "Casa", "No Aplica", piso),
    piso = ifelse(is.na(piso) & tipo == "Apartamento", "No Registrado", piso)
  )

# Verificación final de calidad de los datos
#nulos_finales <- colSums(is.na(vivienda_limpia))
#cat("Total de valores nulos restantes en variables cuantitativas (esperado 0):\n")
#print(nulos_finales[c("preciom", "areaconst", "habitaciones", "banios", "parqueaderos")])

Para observar el proceso de limpieza y el resultado obtenido ver el ‘code-folding’ de este numeral.

2.4.2 Despliegue Caso Vivienda 1 - Base 1

2.4.2.1 Paso 1: Filtrado de datos y verificación espacial

En esta primera etapa, el objetivo es preparar el dataset. Se cargan los datos originales y aislan únicamente la información que nos interesa para la primera solicitud: casas ubicadas en la zona norte de la ciudad. Además, utilizaremos tablas de frecuencias para confirmar que el filtro se aplicó correctamente y proyectaremos las coordenadas en un mapa interactivo. Esto último es crucial para revisar calidad de los datos espaciales y verificar si, en efecto, todas las propiedades etiquetadas como “Zona Norte” coinciden geográficamente con ese sector.

# Exploración rápida de los nombres de las columnas para asegurar la sintaxis
# names(vivienda) 

# 3. Filtrado de la base de datos (base1: casas, zona norte)
# Nota: Asumimos que las columnas se llaman 'tipo' y 'zona' basándonos en bases de datos típicas.
base1 <- vivienda_limpia %>%
  filter(tipo == "Casa", zona == "Zona Norte")

# 4. Mostrar los primeros 3 registros
print("Primeros 3 registros de base1:")
## [1] "Primeros 3 registros de base1:"
head(base1, 3)
# 5. Tablas de comprobación
print("Comprobación de Tipo de vivienda:")
## [1] "Comprobación de Tipo de vivienda:"
table(base1$tipo)
## 
## Casa 
##  700
print("Comprobación de Zona:")
## [1] "Comprobación de Zona:"
table(base1$zona)
## 
## Zona Norte 
##        700
# 6. Mapeo de los puntos de las bases
# Filtrar posibles valores NA en coordenadas para que el mapa no arroje error
base1_mapa <- base1 %>% filter(!is.na(longitud) & !is.na(latitud))

mapa_base1 <- leaflet(base1_mapa) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, 
                   radius = 3, 
                   color = "blue", 
                   stroke = FALSE, 
                   fillOpacity = 0.6,
                   popup = ~paste("Barrio:", barrio, "<br>Precio:", preciom))

# Visualizar el mapa
mapa_base1

El resultado muestra que el 100% de los registros en base1 corresponden a “Casa” y “Zona Norte”, lo que confirma la correcta aplicación del filtro. No obstante, al analizar el mapa interactivo generado con leaflet es posible identificar algunos puntos geográficos atípicos (outliers espaciales) ubicados fuera del perímetro de la Zona Norte o incluso fuera de Cali. Lo observado puede estar asociado a errores en la digitación de direcciones o coordenadas geográficas. En consecuencia, la variable “zona” debe interpretarse como una clasificación registrada en la base de datos que puede presentar cierto nivel de imprecisión al compararse con la localización geográfica real de los inmuebles.

2.4.2.2 Paso 2: Análisis Exploratorio de Datos y Correlación

El objetivo en este paso es explorar visual y estadísticamente cómo se relacionan las características físicas y socioeconómicas de las casas en la Zona Norte con su precio de oferta. Se utilizan gráficos interactivos con plotly para identificar patrones, posibles valores atípicos y evaluar qué variables tienen la relación lineal más fuerte con el precio, lo cual será la base para construir el modelo predictivo.

# 1. Seleccionar solo las variables de interés para la correlación
base1_cor <- base1 %>%
  select(preciom, areaconst, estrato, banios, habitaciones) %>%
  drop_na()

# 2. Matriz de correlación lineal de Pearson
matriz_correlacion <- cor(base1_cor)

# Mostrar como tabla numerada y formateada
as.data.frame(round(matriz_correlacion, 2)) %>%
  tibble::rownames_to_column("Variable") %>%
  knitr::kable(
    caption = "Tabla 3: Matriz de Correlación de Pearson (Casas - Zona Norte)",
    align = "c"
  ) %>%
  kableExtra::kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  kableExtra::footnote(
    general = "Valores entre -1 y 1. |r| > 0.5 indica correlación moderada-fuerte.",
    general_title = ""
  )
Tabla 3: Matriz de Correlación de Pearson (Casas - Zona Norte)
Variable preciom areaconst estrato banios habitaciones
preciom 1.00 0.73 0.62 0.57 0.37
areaconst 0.73 1.00 0.47 0.51 0.45
estrato 0.62 0.47 1.00 0.43 0.10
banios 0.57 0.51 0.43 1.00 0.61
habitaciones 0.37 0.45 0.10 0.61 1.00
Valores entre -1 y 1. |r| > 0.5 indica correlación moderada-fuerte.
# Gráfico 1: Precio vs. Área Construida diferenciado por Estrato
grafico_eda1 <- plot_ly(data = base1, 
                       x = ~areaconst, 
                       y = ~preciom, 
                       type = 'scatter', 
                       mode = 'markers',
                       color = ~as.factor(estrato), 
                       colors = "Set1",
                       marker = list(size = 8, opacity = 0.7),
                       hoverinfo = 'text',
                       text = ~paste("<b>Precio:</b> $", preciom, " Millones",
                                     "<br><b>Área:</b>", areaconst, "m²",
                                     "<br><b>Estrato:</b>", estrato,
                                     "<br><b>Habitaciones:</b>", habitaciones,
                                     "<br><b>Baños:</b>", banios,
                                     "<br><b>Barrio:</b>", barrio)) %>%
  plotly::layout(
    title = list(text = "Gráfico 1: Precio vs. Área Construida<br><sup>Casas - Zona Norte</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Área Construida (m²)"),
    yaxis = list(title = "Precio de Oferta (Millones COP)"),
    legend = list(title = list(text = '<b>Estrato</b>')))

grafico_eda1
# Gráfico 2: Precio vs. Número de Baños (boxplot interactivo por cantidad de baños)
grafico_banios1 <- plot_ly(data = base1,
                           x = ~as.factor(banios),
                           y = ~preciom,
                           type = 'box',
                           color = ~as.factor(banios),
                           colors = "Set2",
                           hoverinfo = 'y',
                           boxpoints = 'outliers') %>%
  plotly::layout(
    title = list(text = "Gráfico 2: Distribución del Precio según N.° de Baños<br><sup>Casas - Zona Norte</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Número de Baños"),
    yaxis = list(title = "Precio de Oferta (Millones COP)"),
    showlegend = FALSE)

grafico_banios1
# Gráfico 3: Precio vs. Habitaciones
grafico_hab1 <- plot_ly(data = base1,
                        x = ~as.factor(habitaciones),
                        y = ~preciom,
                        type = 'box',
                        color = ~as.factor(habitaciones),
                        colors = "Set3",
                        hoverinfo = 'y',
                        boxpoints = 'outliers') %>%
  plotly::layout(
    title = list(text = "Gráfico 3: Distribución del Precio según N.° de Habitaciones<br><sup>Casas - Zona Norte</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Número de Habitaciones"),
    yaxis = list(title = "Precio de Oferta (Millones COP)"),
    showlegend = FALSE)

grafico_hab1
# Gráfico 4: Precio promedio por Estrato (barras interactivas)
resumen_estrato1 <- base1 %>%
  group_by(estrato) %>%
  summarise(precio_promedio = mean(preciom, na.rm = TRUE),
            n = n()) %>%
  arrange(estrato)

grafico_estrato1 <- plot_ly(data = resumen_estrato1,
                            x = ~as.factor(estrato),
                            y = ~precio_promedio,
                            type = 'bar',
                            color = ~as.factor(estrato),
                            colors = "Blues",
                            hoverinfo = 'text',
                            text = ~paste("<b>Estrato:</b>", estrato,
                                          "<br><b>Precio Promedio:</b> $", round(precio_promedio, 1), "M",
                                          "<br><b>N registros:</b>", n)) %>%
  plotly::layout(
    title = list(text = "Gráfico 4: Precio Promedio por Estrato<br><sup>Casas - Zona Norte</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Estrato Socioeconómico"),
    yaxis = list(title = "Precio Promedio (Millones COP)"),
    showlegend = FALSE)

grafico_estrato1

La matriz de correlación Tabla 3 muestra que el área construida es la variable que presenta la relación positiva más fuerte con el precio de oferta (\(r = 0.73\)), seguida por el estrato socioeconómico (\(r = 0.62\)). Entre las características del inmueble, el número de baños presenta una relación más fuerte con el precio (\(r = 0.57\)) que el número de habitaciones (\(r = 0.37\)).

El Gráfico 1 confirma la relación directa entre área y precio, evidenciando además segmentación clara por estrato. El Gráfico 2 muestra que a mayor número de baños el precio aumenta de forma consistente, con una dispersión más alta en viviendas de 4 o más baños que reflejan propiedades de alto valor. El Gráfico 3 revela que el precio no crece linealmente con el número de habitaciones, lo que anticipa la posible no significancia estadística de esta variable en el modelo. Finalmente, el Gráfico 4 confirma el efecto escalonado del estrato sobre el precio promedio, con diferencias marcadas entre estratos 3, 4 y 5.

Asimismo, se observa una correlación moderada entre habitaciones y baños (\(r = 0.61\)), lo que sugiere una posible colinealidad que deberá considerarse en el modelo de regresión múltiple.

2.4.2.3 Paso 3: Modelo de Regresión Lineal Múltiple

El propósito de esta fase es estimar un modelo de regresión lineal múltiple que permita cuantificar el efecto de distintas características estructurales y socioeconómicas como área construida, estrato, número de habitaciones, parqueaderos y baños, sobre el precio de oferta de las viviendas en la Zona Norte. A partir de este modelo se evaluará qué variables resultan estadísticamente significativas y se analizará la capacidad explicativa del modelo mediante el coeficiente R2.

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

# 2. Extraer el resumen estadístico detallado del modelo
resumen_modelo_v1 <- summary(modelo_v1)

# 3. Imprimir el resumen en la consola para analizar coeficientes y R-cuadrado
print(resumen_modelo_v1)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -894.38  -75.00  -18.45   44.29 1101.47 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -237.38679   31.89342  -7.443 2.92e-13 ***
## areaconst       0.76519    0.04615  16.580  < 2e-16 ***
## estrato        78.72606    7.75979  10.145  < 2e-16 ***
## habitaciones    3.58463    4.77684   0.750  0.45326    
## parqueaderos   17.81350    5.61309   3.174  0.00157 ** 
## banios         27.51162    5.90916   4.656 3.87e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 156.9 on 694 degrees of freedom
## Multiple R-squared:  0.6589, Adjusted R-squared:  0.6564 
## F-statistic: 268.1 on 5 and 694 DF,  p-value: < 2.2e-16

El modelo estimado para la Base 1 es:

\[ \widehat{preciom} = -237.39 + 0.765(areaconst) + 78.73(estrato) + 3.58(habitaciones) + 17.81(parqueaderos) + 27.51(banios) \] El modelo de regresión lineal múltiple muestra un buen ajuste para explicar el precio de las viviendas en la Zona Norte, con un 𝑅2 de 0.6589 y un 𝑅2 ajustado de 0.6564, lo que indica que aproximadamente el 66% de la variabilidad del precio es explicada por las variables incluidas. El modelo global resulta estadísticamente significativo (F = 268.1, p < 0.001).

Entre los predictores analizados, el área construida y el estrato socioeconómico se destacan como los principales determinantes del precio, ambos con alta significancia estadística. Asimismo, las variables baños y parqueaderos presentan efectos positivos y significativos sobre el valor de las propiedades. Por el contrario, la variable habitaciones no resulta estadísticamente significativa una vez controladas las demás características del inmueble, lo que sugiere que su efecto ya se encuentra parcialmente capturado por variables como el área construida o el número de baños.

2.4.2.4 Paso 4: Validación de supuestos

Una vez estimado el modelo de regresión lineal múltiple, es necesario garantizar la validez de los resultados obtenidos. En esta etapa se analizan los principales supuestos del modelo como son linealidad, normalidad de los residuos, homocedasticidad y ausencia de multicolinealidad, con el propósito de verificar la confiabilidad de las estimaciones y detectar posibles desviaciones que puedan afectar la interpretación del modelo.

# 2. Generar los 4 gráficos de diagnóstico estándar de R
# par(mfrow = c(2, 2)) divide la ventana de plots en una cuadrícula de 2x2
par(mfrow = c(2, 2))
plot(modelo_v1)

# 3. Calcular el Factor de Inflación de Varianza (VIF)
valores_vif <- vif(modelo_v1)
print("Valores VIF (Factor de Inflación de Varianza):")
## [1] "Valores VIF (Factor de Inflación de Varianza):"
print(valores_vif)
##    areaconst      estrato habitaciones parqueaderos       banios 
##     1.677462     1.658300     1.838469     1.378046     2.134855

La validación de los supuestos de la regresión lineal múltiple permite evaluar la confiabilidad de las estimaciones obtenidas. A partir de los gráficos diagnósticos de residuos y del Factor de Inflación de Varianza (VIF), se obtienen los siguientes resultados.

Multicolinealidad. Los valores del VIF para todas las variables explicativas son inferiores a 2.5 (Baños: 2.13; Habitaciones: 1.84; Área Construida: 1.68; Estrato: 1.66; Parqueaderos: 1.38), lo que indica ausencia de multicolinealidad severa. Por tanto, la correlación existente entre las variables estructurales de las viviendas no afecta de manera significativa la estabilidad de los coeficientes estimados.

Linealidad. El gráfico de residuos frente a valores ajustados (Residuals vs Fitted) muestra una dispersión aproximadamente aleatoria alrededor de cero y una línea de tendencia cercana a la horizontal, lo cual sugiere que el supuesto de relación lineal entre las variables explicativas y el precio se cumple razonablemente.

Normalidad de los residuos. El gráfico Q-Q indica que los residuos siguen de manera aproximada la línea teórica en la zona central, aunque se observan desviaciones en las colas de la distribución. Esto sugiere la presencia de algunos valores extremos, situación que puede presentarse debido a la naturaleza de los datos.

Homoscedasticidad. El gráfico Scale-Location evidencia un patrón de dispersión creciente de los residuos, formando una leve estructura en forma de embudo. Este comportamiento indica la presencia de heterocedasticidad, es decir, un aumento en la variabilidad de los errores a medida que aumentan los valores predichos del precio.

Observaciones influyentes. El gráfico Residuals vs Leverage identifica algunas observaciones potencialmente influyentes (como las 612, 174 y 880). Aunque la mayoría no supera los límites críticos de la distancia de Cook.

2.4.2.5 Paso 5: Predicción de Precio Vivienda 1

En este paso Utilizaremos el modelo de regresión lineal múltiple estimado para proyectar el valor comercial de la primera solicitud inmobiliaria. Dado que el cliente acepta propiedades de estrato 4 o 5, se evaluarán dos escenarios de predicción con el fin de identificar cuál se ajusta mejor al presupuesto preaprobado de 350 millones de pesos.

# 1. Creación del dataframe con las características exactas de la Vivienda 1
perfil_vivienda1 <- data.frame(
  areaconst = c(200, 200),
  estrato = c(4, 5),
  habitaciones = c(4, 4),
  parqueaderos = c(1, 1),
  banios = c(2, 2)
)

# 2. Generar las predicciones utilizando el modelo entrenado
prediccion_v1 <- predict(modelo_v1, newdata = perfil_vivienda1, interval = "confidence")

# 3. Formateo y renderizado de tabla

resultados_prediccion1 <- cbind(perfil_vivienda1, prediccion_v1) %>%
  mutate(
    fit = round(fit, 3),
    lwr = round(lwr, 3),
    upr = round(upr, 3)
  ) %>%
  rename(
    `Área (m²)` = areaconst,
    `Estrato` = estrato,
    `Habitaciones` = habitaciones,
    `Parqueaderos` = parqueaderos,
    `Baños` = banios,
    `Precio Estimado` = fit,
    `Límite Inferior` = lwr,
    `Límite Superior` = upr
  )

resultados_prediccion1 %>%
  kable(
    align = "c",
    caption = "Tabla 4: Predicción de precio para Vivienda 1 (Cifras en Millones COP)"
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  footnote(
    general = "Nota: El Límite Inferior y Superior corresponden a un intervalo de confianza del 95%. Límite de crédito preaprobado: $350 Millones.",
    general_title = ""
  )
Tabla 4: Predicción de precio para Vivienda 1 (Cifras en Millones COP)
Área (m²) Estrato Habitaciones Parqueaderos Baños Precio Estimado Límite Inferior Límite Superior
200 4 4 1 2 317.732 298.705 336.758
200 5 4 1 2 396.458 368.865 424.051
Nota: El Límite Inferior y Superior corresponden a un intervalo de confianza del 95%. Límite de crédito preaprobado: $350 Millones.

A partir del modelo de regresión estimado, se proyectó el valor comercial de una vivienda con las características solicitadas por el cliente (200 m² de área construida, 4 habitaciones, 2 baños y 1 parqueadero) en la Zona Norte. Dado que el cliente acepta propiedades de estrato 4 o 5, se evaluaron dos escenarios de predicción.

Escenario 1 – Estrato 4: El modelo estima un precio de 317.73 millones de pesos, con un intervalo de confianza al 95% entre 298.70 y 336.75 millones. Este resultado se encuentra dentro del presupuesto preaprobado de 350 millones, por lo que representa una opción viable para el cliente.

Escenario 2 – Estrato 5: El precio estimado es de 396.45 millones de pesos, con un intervalo entre 368.86 y 424.05 millones. En este caso, el valor esperado supera el presupuesto disponible, lo que limita la viabilidad de este escenario.

Conclusión: Se recomienda concentrar la búsqueda de la Vivienda 1 en propiedades de estrato 4 dentro de la Zona Norte, ya que este segmento se ajusta al presupuesto del cliente y ofrece mayor probabilidad de encontrar viviendas con las características solicitadas.

2.4.2.6 Paso 6: Mapeo y Selección de Potenciales Ofertas

Se realizará un filtrado exhaustivo en la base de datos de inmuebles disponibles en la Zona Norte, priorizando aquellas opciones en Estrato 4 (y posibles oportunidades en Estrato 5) que cumplan con la restricción presupuestal máxima de 350 millones de pesos y se acerquen a los requerimientos habitacionales de la familia. Finalmente, se georreferenciarán las 5 mejores opciones en un mapa.

# 1. Crear las ofertas de la Vivienda 1
ofertas_potenciales_v1 <- base1 %>%
  filter(preciom <= 350, 
         estrato %in% c(4, 5),
         areaconst >= 150,
         habitaciones >= 3,
         banios >= 2,
         latitud > 3.44) %>% # Nuestro filtro espacial clave
  arrange(desc(areaconst)) %>% 
  head(5)

mapa_ofertas_v1 <- ofertas_potenciales_v1 %>%
  leaflet() %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud,
                   radius = 6,
                   color = "green",
                   stroke = TRUE,
                   fillOpacity = 0.8,
                   popup = ~paste0("<b>ID Inmueble:</b> ", id,
                                  "<br><b>Barrio:</b> ", barrio,
                                  "<br><b>Precio:</b> $", preciom, " Millones",
                                  "<br><b>Área:</b> ", areaconst, " m²",
                                  "<br><b>Estrato:</b> ", estrato,
                                  "<br><b>Hab/Baños:</b> ", habitaciones, " / ", banios,
                                  "<br><b>Parqueaderos:</b> ", parqueaderos)) %>%
  addLegend("bottomright", colors = "green", labels = "Ofertas Recomendadas", title = "Vivienda 1")


#Tabla
ofertas_potenciales_v1 %>%
  select(id, barrio, estrato, preciom, areaconst, habitaciones, banios, parqueaderos) %>%
  rename(
    `Barrio` = barrio,
    `Estrato` = estrato,
    `Precio (Millones)` = preciom,
    `Área (m²)` = areaconst,
    `Habitaciones` = habitaciones,
    `Baños` = banios
  ) %>%
  mutate(Barrio = str_to_title(Barrio)) %>% # Pone la primera letra en mayúscula (ej. San Vicente)
  kable(
    align = "c",
    caption = "Tabla 5: Top 5 Oportunidades de Mercado — Casas Zona Norte (Presupuesto ≤ $350 Millones)"
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  footnote(
    general = "Nota: Las propiedades listadas representan valores atípicos (oportunidades) por debajo del precio promedio estimado por el modelo para el Estrato 5.",
    general_title = ""
  )
Tabla 5: Top 5 Oportunidades de Mercado — Casas Zona Norte (Presupuesto ≤ $350 Millones)
id Barrio Estrato Precio (Millones) Área (m²) Habitaciones Baños parqueaderos
3101 San Vicente 5 340 355 8 5 2
5031 Salomia 4 350 350 5 4 1
1943 Vipasa 5 350 346 4 2 1
4209 El Bosque 5 350 300 6 5 3
1822 Vipasa 4 340 295 4 2 2
Nota: Las propiedades listadas representan valores atípicos (oportunidades) por debajo del precio promedio estimado por el modelo para el Estrato 5.
# Visualizar el mapa
mapa_ofertas_v1

Al contrastar la predicción del modelo con la oferta disponible en el mercado de la Zona Norte, se identificaron oportunidades de compra favorables dentro del presupuesto del cliente (350 millones de pesos). Aunque el modelo estimaba que una vivienda de estrato 5 con 200 m² tendría un valor promedio cercano a los 396 millones, la revisión de la base de datos evidenció algunas propiedades con precios inferiores al promedio del mercado.

De acuerdo con los resultados presentados en la Tabla 3 y en el mapa de georreferenciación, varias de las alternativas que cumplen la restricción presupuestal se ubican en barrios de estrato 5, particularmente en San Vicente, Vipasa y El Bosque. Estas viviendas no solo se ajustan al presupuesto establecido, sino que además ofrecen áreas construidas superiores a las requeridas, con superficies entre 300 m² y 355 m².

Recomendación: Se sugiere priorizar la presentación de las propiedades ubicadas en San Vicente (355 m², $340 millones) y Vipasa (346 m², $350 millones), ya que ofrecen una relación favorable entre precio y área construida dentro de la Zona Norte. No obstante, es recomendable advertir al cliente que, debido a que estos inmuebles se encuentran por debajo del precio promedio del mercado para su estrato y tamaño, podrían requerir algunas adecuaciones o mejoras.

2.4.3 Despliegue Caso Vivienda 2 - Base 2

2.4.3.1 Paso 1: Filtrado de datos y verificación espacial

En este caso segmentaremos nuestro conjunto de datos para analizar específicamente la segunda solicitud que corresponde a Apartamentos Ubicados en la Zona Sur. Usaremos la misma metodología aplicada a una base2.

# Exploración rápida de los nombres de las columnas para asegurar la sintaxis
# names(vivienda) 

# 3. Filtrado de la base de datos (base1: casas, zona norte)
# Nota: Asumimos que las columnas se llaman 'tipo' y 'zona' basándonos en bases de datos típicas.
base2 <- vivienda_limpia %>%
  filter(tipo == "Apartamento", zona == "Zona Sur")

# 4. Mostrar los primeros 3 registros
print("Primeros 3 registros de base2:")
## [1] "Primeros 3 registros de base2:"
head(base2, 3)
# 5. Tablas de comprobación
print("Comprobación de Tipo de vivienda:")
## [1] "Comprobación de Tipo de vivienda:"
table(base2$tipo)
## 
## Apartamento 
##        2777
print("Comprobación de Zona:")
## [1] "Comprobación de Zona:"
table(base2$zona)
## 
## Zona Sur 
##     2777
# 6. Mapeo de los puntos de las bases
# Filtrar posibles valores NA en coordenadas para que el mapa no arroje error
base2_mapa <- base2 %>% filter(!is.na(longitud) & !is.na(latitud))

mapa_base2 <- leaflet(base2_mapa) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, 
                   radius = 3, 
                   color = "blue", 
                   stroke = FALSE, 
                   fillOpacity = 0.6,
                   popup = ~paste("Barrio:", barrio, "<br>Precio:", preciom))

# Visualizar el mapa
mapa_base2

Al filtrar la base de datos para identificar los apartamentos ubicados en la Zona Sur, se obtuvo un subconjunto de 2777 registros, lo cual constituye una muestra amplia para estimar un nuevo modelo predictivo.

Sin embargo, al realizar la validación espacial mediante georreferenciación, tal como con la vivienda anterior, se detectaron inconsistencias en las coordenadas registradas (latitud y longitud). Aunque todos los registros están clasificados textualmente como pertenecientes a la “Zona Sur”, el mapa de dispersión muestra varias propiedades ubicadas erróneamente en zonas del norte, centro e incluso fuera del perímetro urbano de la ciudad.

Este hallazgo evidencia problemas en la captura de información geográfica dentro de la base de datos original y resalta la necesidad de aplicar filtros espaciales adicionales en etapas posteriores del análisis. De esta manera se garantiza que las propiedades finalmente recomendadas al cliente correspondan efectivamente a la ubicación solicitada.

2.4.3.2 Paso 2: Análisis Exploratorio de Datos y Correlación

A continuación se explora de forma visual y estadística cómo se relacionan las características físicas y socioeconómicas de los apartamentos en la Zona Sur con su precio de oferta. Se utilizan gráficos interactivos con plotly para identificar patrones, valores atípicos y evaluar la fuerza de las relaciones entre variables, lo cual fundamenta la construcción del modelo predictivo para la segunda vivienda.

# 1. Seleccionar solo las variables de interés para la correlación
base2_cor <- base2 %>%
  select(preciom, areaconst, estrato, banios, habitaciones) %>%
  drop_na()

# 2. Matriz de correlación lineal de Pearson
matriz_correlacion2 <- cor(base2_cor)

# Mostrar como tabla numerada y formateada
as.data.frame(round(matriz_correlacion2, 2)) %>%
  tibble::rownames_to_column("Variable") %>%
  knitr::kable(
    caption = "Tabla 6: Matriz de Correlación de Pearson (Apartamentos - Zona Sur)",
    align = "c"
  ) %>%
  kableExtra::kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  kableExtra::footnote(
    general = "Valores entre -1 y 1. |r| > 0.5 indica correlación moderada-fuerte.",
    general_title = ""
  )
Tabla 6: Matriz de Correlación de Pearson (Apartamentos - Zona Sur)
Variable preciom areaconst estrato banios habitaciones
preciom 1.00 0.76 0.67 0.73 0.34
areaconst 0.76 1.00 0.48 0.69 0.45
estrato 0.67 0.48 1.00 0.57 0.21
banios 0.73 0.69 0.57 1.00 0.52
habitaciones 0.34 0.45 0.21 0.52 1.00
Valores entre -1 y 1. |r| > 0.5 indica correlación moderada-fuerte.
# Gráfico 5: Precio vs. Área Construida (coloreado por Estrato)
grafico_eda2 <- plot_ly(data = base2, 
                        x = ~areaconst, 
                        y = ~preciom, 
                        type = 'scatter', 
                        mode = 'markers',
                        color = ~as.factor(estrato), 
                        colors = "Set1",
                        marker = list(size = 7, opacity = 0.6),
                        hoverinfo = 'text',
                        text = ~paste("<b>Precio:</b> $", preciom, " Millones",
                                      "<br><b>Área:</b>", areaconst, "m²",
                                      "<br><b>Estrato:</b>", estrato,
                                      "<br><b>Habitaciones:</b>", habitaciones,
                                      "<br><b>Baños:</b>", banios,
                                      "<br><b>Barrio:</b>", barrio)) %>%
  plotly::layout(
    title = list(text = "Gráfico 5: Precio vs. Área Construida<br><sup>Apartamentos - Zona Sur</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Área Construida (m²)"),
    yaxis = list(title = "Precio de Oferta (Millones COP)"),
    legend = list(title = list(text = '<b>Estrato</b>')))

grafico_eda2
# Gráfico 6: Precio vs. Número de Baños (boxplot interactivo)
grafico_banios2 <- plot_ly(data = base2,
                           x = ~as.factor(banios),
                           y = ~preciom,
                           type = 'box',
                           color = ~as.factor(banios),
                           colors = "Set2",
                           hoverinfo = 'y',
                           boxpoints = 'outliers') %>%
  plotly::layout(
    title = list(text = "Gráfico 6: Distribución del Precio según N.° de Baños<br><sup>Apartamentos - Zona Sur</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Número de Baños"),
    yaxis = list(title = "Precio de Oferta (Millones COP)"),
    showlegend = FALSE)

grafico_banios2
# Gráfico 7: Precio vs. Habitaciones (boxplot interactivo)
grafico_hab2 <- plot_ly(data = base2,
                        x = ~as.factor(habitaciones),
                        y = ~preciom,
                        type = 'box',
                        color = ~as.factor(habitaciones),
                        colors = "Set3",
                        hoverinfo = 'y',
                        boxpoints = 'outliers') %>%
  plotly::layout(
    title = list(text = "Gráfico 7: Distribución del Precio según N.° de Habitaciones<br><sup>Apartamentos - Zona Sur</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Número de Habitaciones"),
    yaxis = list(title = "Precio de Oferta (Millones COP)"),
    showlegend = FALSE)

grafico_hab2
# Gráfico 8: Precio promedio por Estrato (barras interactivas)
resumen_estrato2 <- base2 %>%
  group_by(estrato) %>%
  summarise(precio_promedio = mean(preciom, na.rm = TRUE),
            n = n()) %>%
  arrange(estrato)

grafico_estrato2 <- plot_ly(data = resumen_estrato2,
                            x = ~as.factor(estrato),
                            y = ~precio_promedio,
                            type = 'bar',
                            color = ~as.factor(estrato),
                            colors = "Oranges",
                            hoverinfo = 'text',
                            text = ~paste("<b>Estrato:</b>", estrato,
                                          "<br><b>Precio Promedio:</b> $", round(precio_promedio, 1), "M",
                                          "<br><b>N registros:</b>", n)) %>%
  plotly::layout(
    title = list(text = "Gráfico 8: Precio Promedio por Estrato<br><sup>Apartamentos - Zona Sur</sup>",
                 font = list(size = 14), x = 0.5, xanchor = "center"),
    margin = list(t = 70),
    xaxis = list(title = "Estrato Socioeconómico"),
    yaxis = list(title = "Precio Promedio (Millones COP)"),
    showlegend = FALSE)

grafico_estrato2

El análisis de correlación muestra que el área construida es la variable con mayor relación con el precio de los apartamentos (\(r = 0.76\)), seguida muy de cerca por el número de baños (\(r = 0.73\)), lo que sugiere que el tamaño y el nivel de comodidad del inmueble influyen de forma significativa en su valoración. El estrato socioeconómico también presenta una correlación importante (\(r = 0.67\)), confirmando la importancia de la ubicación.

El Gráfico 5 evidencia la relación directa entre área y precio con segmentación visible por estrato y alta concentración de apartamentos entre 50 m² y 200 m². El Gráfico 6 refuerza el papel del número de baños, mostrando incrementos sostenidos en el precio mediano a medida que aumentan los baños, con mayor dispersión en apartamentos de 4 o más baños. El Gráfico 7 revela que el precio no escala linealmente con habitaciones, anticipando el coeficiente negativo que aparecerá en el modelo. El Gráfico 8 confirma el efecto escalonado del estrato, siendo especialmente pronunciado el salto entre estrato 5 y 6.

Por el contrario, el número de habitaciones muestra la relación más débil con el precio (\(r = 0.34\)), lo que indica que el mercado de apartamentos en el Sur prioriza el metraje total y las amenidades sobre la cantidad de cuartos.

2.4.3.3 Paso 3: Modelo de Regresión Lineal Múltiple

Tal como en el caso de la vivienda 1, el propósito de esta fase es estimar un modelo de regresión lineal múltiple para cuantificar el impacto de las características estructurales y de ubicación sobre el precio de oferta en el segmento de apartamentos de la Zona Sur, evaluando la capacidad explicativa del modelo en este submercado específico.

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

# 2. Extraer el resumen estadístico detallado del modelo
resumen_modelo_v2 <- summary(modelo_v2)

# 3. Imprimir el resumen en la consola para analizar coeficientes y R-cuadrado
print(resumen_modelo_v2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base2)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1120.55   -38.38    -2.81    38.27   922.91 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -259.27683   13.16926 -19.688  < 2e-16 ***
## areaconst       1.32548    0.05008  26.466  < 2e-16 ***
## estrato        57.44579    2.68557  21.391  < 2e-16 ***
## habitaciones  -19.52241    3.45457  -5.651 1.76e-08 ***
## parqueaderos   77.66743    3.90002  19.915  < 2e-16 ***
## banios         45.71708    3.10613  14.718  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 92.83 on 2771 degrees of freedom
## Multiple R-squared:  0.7639, Adjusted R-squared:  0.7635 
## F-statistic:  1793 on 5 and 2771 DF,  p-value: < 2.2e-16

El modelo estimado para la base 2 es:

\[\widehat{preciom} = -259.28 + 1.33(areaconst) + 57.45(estrato) - 19.52(habitaciones) + 77.67(parqueaderos) + 45.72(banios)\]

El modelo estimado con 2777 apartamentos de la Zona Sur presenta un buen ajuste estadístico, con un R² de 0.7639, lo que indica que las variables incluidas explican aproximadamente el 76.39% de la variación en los precios. Esto sugiere una buena capacidad predictiva del modelo para este segmento del mercado.

El área construida tiene un impacto positivo, cada metro cuadrado adicional incrementa el precio en aproximadamente 1.32 millones de pesos. En contraste, el número de habitaciones presenta un coeficiente negativo (-19.52 millones), lo que indica que, manteniendo constante el área total, dividir el espacio en más habitaciones tiende a reducir el valor del apartamento.

Por otra parte, las amenidades tienen un efecto importante en la valorización. Cada parqueadero adicional aumenta el precio en cerca de 77.66 millones de pesos, mientras que cada baño adicional incrementa el valor en aproximadamente 45.71 millones. Finalmente, el estrato socioeconómico también influye significativamente, ya que subir un nivel de estrato eleva el precio esperado en alrededor de 57.44 millones de pesos.

2.4.3.4 Paso 4: Validación de supuestos

# 2. Generar los 4 gráficos de diagnóstico estándar de R
# par(mfrow = c(2, 2)) divide la ventana de plots en una cuadrícula de 2x2
par(mfrow = c(2, 2))
plot(modelo_v2)

# 3. Calcular el Factor de Inflación de Varianza (VIF)
valores_vif2 <- vif(modelo_v2)
print("Valores VIF (Factor de Inflación de Varianza):")
## [1] "Valores VIF (Factor de Inflación de Varianza):"
print(valores_vif2)
##    areaconst      estrato habitaciones parqueaderos       banios 
##     2.177763     1.646232     1.440328     1.857722     2.678270

El análisis de los supuestos del modelo muestra resultados mixtos. En primer lugar, no se detectan problemas de multicolinealidad, ya que todos los valores del VIF se encuentran por debajo de 5 (máximo: Baños = 2.68), lo que indica que las variables explicativas aportan información independiente al modelo.

El supuesto de linealidad se cumple de forma general, dado que los residuos se distribuyen alrededor de cero. Sin embargo, los gráficos diagnósticos evidencian heterocedasticidad, ya que la dispersión de los errores aumenta a medida que crecen los valores predichos del precio.

Asimismo, el gráfico Q-Q muestra desviaciones en las colas, lo que indica que los residuos no siguen perfectamente una distribución normal, especialmente en apartamentos muy baratos o de alto valor.

Finalmente, el gráfico de Residuals vs Leverage identifica algunas observaciones altamente influyentes, particularmente el registro 2373, que podría estar distorsionando la estimación del modelo.No obstante, los diagnósticos muestran un ajuste coherente con el modelo.

2.4.3.5 Paso 5: Predicción de Precio Vivienda 2

# 1. Creación del dataframe con el perfil exacto de la Vivienda 2
perfil_vivienda2 <- data.frame(
  areaconst = c(300, 300),
  estrato = c(5, 6),
  habitaciones = c(5, 5),
  parqueaderos = c(3, 3),
  banios = c(3, 3)
)

# 2. Generar predicciones usando el modelo del Sur
prediccion_v2 <- predict(modelo_v2, newdata = perfil_vivienda2, interval = "confidence")

# 3. Formateo y renderizado de la Tabla
resultados_prediccion2 <- cbind(perfil_vivienda2, prediccion_v2) %>%
  mutate(
    fit = round(fit, 2),
    lwr = round(lwr, 2),
    upr = round(upr, 2)
  ) %>%
  rename(
    `Área (m²)` = areaconst,
    `Estrato` = estrato,
    `Habitaciones` = habitaciones,
    `Parqueaderos` = parqueaderos,
    `Baños` = banios,
    `Precio Estimado` = fit,
    `Límite Inferior` = lwr,
    `Límite Superior` = upr
  )

resultados_prediccion2 %>%
  kable(
    align = "c",
    caption = "Tabla 7: Predicción de precio para Vivienda 2 (Cifras en Millones COP)"
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  ) %>%
  footnote(
    general = "Nota: Intervalo de confianza del 95%. Límite de crédito preaprobado: $850 Millones.",
    general_title = ""
  )
Tabla 7: Predicción de precio para Vivienda 2 (Cifras en Millones COP)
Área (m²) Estrato Habitaciones Parqueaderos Baños Precio Estimado Límite Inferior Límite Superior
300 5 5 3 3 698.14 677.31 718.97
300 6 5 3 3 755.58 734.59 776.57
Nota: Intervalo de confianza del 95%. Límite de crédito preaprobado: $850 Millones.

A partir del modelo de regresión estimado, se proyectó el valor comercial de un apartamento con las características solicitadas por el cliente (300 m², 5 habitaciones, 3 baños y 3 parqueaderos) en la Zona Sur. Se evaluaron dos escenarios según el estrato socioeconómico.

Para estrato 5, el modelo estima un precio promedio de 698.14 millones de pesos, con un límite superior de confianza cercano a 718.97 millones. En el caso de estrato 6, el precio estimado asciende a 755.58 millones, con un límite superior aproximado de 776.57 millones.

Recomendación: Ambos escenarios se encuentran dentro del presupuesto preaprobado de 850 millones de pesos, lo que indica una alta viabilidad financiera. No obstante, se recomienda priorizar la búsqueda en estrato 6, ya que permite ofrecer mayores niveles de exclusividad y calidad residencial sin superar la capacidad de pago establecida.

2.4.3.6 Paso 6: Mapeo y Selección de Potenciales Ofertas

# 1. Filtrar la base de datos para buscar ofertas reales en el Sur
# Buscamos apartamentos de Estrato 5 o 6, máximo 850M, y que sean muy amplios.
ofertas_potenciales_v2 <- base2 %>%
  filter(preciom <= 850, 
         estrato %in% c(5, 6),
         areaconst >= 250, # Damos flexibilidad pero buscando espacios enormes
         habitaciones >= 4,
         banios >= 3,
         parqueaderos >= 2,
         latitud < 3.42) %>% # Filtro de calidad espacial para asegurar que sí estén en el Sur
  arrange(desc(areaconst)) %>% # Ordenamos por los más grandes
  head(5)

# 2. Generar el Mapa Interactivo (Vivienda 2)
mapa_ofertas_v2 <- ofertas_potenciales_v2 %>%
  leaflet() %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud,
                   radius = 6,
                   color = "blue", # Usamos azul para diferenciar de la Vivienda 1
                   stroke = TRUE,
                   fillOpacity = 0.8,
                   popup = ~paste0("<b>ID Inmueble:</b> ", id,
                                  "<br><b>Barrio:</b> ", str_to_title(barrio),
                                  "<br><b>Precio:</b> $", preciom, " Millones",
                                  "<br><b>Área:</b> ", areaconst, " m²",
                                  "<br><b>Estrato:</b> ", estrato,
                                  "<br><b>Hab/Baños:</b> ", habitaciones, " / ", banios,
                                  "<br><b>Parqueaderos:</b> ", parqueaderos)) %>%
  addLegend("bottomright", colors = "blue", labels = "Ofertas Recomendadas", title = "Vivienda 2")

# 3. Formateo de la Tabla Formal 5 para el informe
tabla_ofertas_v2 <- ofertas_potenciales_v2 %>%
  select(id, barrio, estrato, preciom, areaconst, habitaciones, banios, parqueaderos) %>%
  rename(
    `ID` = id,
    `Barrio` = barrio,
    `Estrato` = estrato,
    `Precio (Millones)` = preciom,
    `Área (m²)` = areaconst,
    `Habitaciones` = habitaciones,
    `Baños` = banios,
    `Parq.` = parqueaderos
  ) %>%
  mutate(Barrio = str_to_title(Barrio)) %>%
  kable(
    align = "c",
    caption = "Tabla 8: Top 5 Oportunidades de Mercado — Apartamentos Zona Sur (Presupuesto ≤ $850 Millones)"
  ) %>%
  
  kable_styling(
    bootstrap_options = c("striped", "hover", "bordered", "condensed"),
    full_width = FALSE,
    position = "center"
  )

# Mostrar el mapa en RStudio
tabla_ofertas_v2
Tabla 8: Top 5 Oportunidades de Mercado — Apartamentos Zona Sur (Presupuesto ≤ $850 Millones)
ID Barrio Estrato Precio (Millones) Área (m²) Habitaciones Baños Parq.
4952 El Ingenio 5 650 600 5 4 2
7182 Guadalupe 5 730 573 5 8 3
4394 El Ingenio 5 690 486 4 4 2
7658 Cuarto De Legua 5 520 320 4 4 2
7512 Seminario 5 670 300 6 5 3
mapa_ofertas_v2

La búsqueda final en la base de datos depurada identificó varias oportunidades favorables en la Zona Sur, particularmente en barrios de alto perfil residencial como El Ingenio, Guadalupe, Cuarto de Legua y Seminario.

Las cinco propiedades seleccionadas cumplen con los requisitos establecidos por el cliente en términos de área, número de habitaciones, baños y nivel socioeconómico. Además, todas se mantienen por debajo del presupuesto preaprobado de 850 millones de pesos. La opción más costosa alcanza aproximadamente 730 millones, lo que representa un margen considerable frente al límite disponible.

Adicionalmente, algunas de estas propiedades ofrecen áreas significativamente superiores a las inicialmente solicitadas, alcanzando superficies cercanas a 600 m², lo que incrementa el nivel de confort para el ejecutivo.

Recomendación: priorizar la programación de visitas a los inmuebles ubicados en el barrio El Ingenio, ya que presentan una combinación favorable de ubicación, área y precio dentro del mercado de la Zona Sur.

2.5 Anexos

2.5.1 Anexo 1: Plan de Trabajo y Metodología

El presente análisis sigue una metodología estructurada de regresión lineal múltiple aplicada al mercado inmobiliario de Cali, organizada en cinco etapas secuenciales:

Etapa 1 — Filtrado y validación espacial de datos: Se segmentó la base de datos vivienda del paquete paqueteMODELOS según el tipo de inmueble y zona de interés para cada solicitud (Base 1: casas Zona Norte; Base 2: apartamentos Zona Sur). Se verificó la consistencia espacial de los registros mediante mapas interactivos con leaflet, identificando coordenadas atípicas y aplicando filtros geográficos correctivos.

Etapa 2 — Análisis Exploratorio de Datos (EDA): Se calcularon matrices de correlación de Pearson y se construyeron gráficos interactivos con plotly para evaluar la relación entre el precio de oferta y las variables explicativas: área construida, estrato, número de baños, número de habitaciones y parqueaderos. Esta etapa orientó la selección de predictores para el modelo.

Etapa 3 — Estimación del modelo de Regresión Lineal Múltiple: Se estimó un modelo de regresión lineal múltiple para cada base de datos mediante la función lm() de R, incluyendo como predictores: área construida, estrato, habitaciones, parqueaderos y baños. Se interpretaron los coeficientes estadísticamente significativos en contexto y se evaluó el ajuste global mediante el coeficiente de determinación R².

Etapa 4 — Validación de supuestos: Se evaluaron los principales supuestos del modelo de regresión lineal (linealidad, normalidad de residuos, homocedasticidad y ausencia de multicolinealidad) a través de los gráficos diagnósticos estándar de R (plot(modelo)) y el Factor de Inflación de Varianza (vif() del paquete car).

Etapa 5 — Predicción y selección de ofertas: Con los modelos estimados se calcularon predicciones de precio para los perfiles de cada vivienda solicitada, evaluando escenarios por estrato. Se filtraron las ofertas reales disponibles en la base de datos que cumplen con las características habitacionales y los límites de crédito preaprobado, presentándolas en mapas georreferenciados interactivos.


2.5.2 Anexo 2: Resumen de la Modelación y Validación Técnica

2.5.2.1 Cargue y Limpieza de Datos (Base Original)

Ver sección Datos del documento principal, donde se documenta:

  • Instalación y carga del paquete paqueteMODELOS
  • Análisis de valores nulos por variable (Tabla 2)
  • Eliminación de registros estructuralmente vacíos
  • Corrección de inconsistencias lógicas (habitaciones = 0, baños = 0)
  • Imputación de parqueaderos con mediana por estrato y tipo
  • Recodificación de piso para viviendas tipo Casa

2.5.2.2 Resultados Modelo Vivienda 1 (Casas - Zona Norte)

  • Ecuación estimada: \(\widehat{preciom} = -237.39 + 0.765(areaconst) + 78.73(estrato) + 3.58(habitaciones) + 17.81(parqueaderos) + 27.51(banios)\)
  • R² = 0.6589 | R² ajustado = 0.6564 | F = 268.1 (p < 0.001)
  • Variables significativas: areaconst, estrato, banios, parqueaderos
  • Variable no significativa: habitaciones
  • VIF máximo: Baños = 2.13 → sin multicolinealidad severa
  • Supuestos: linealidad cumplida; heterocedasticidad detectada; normalidad aproximada con desviaciones en colas

2.5.2.3 Resultados Modelo Vivienda 2 (Apartamentos - Zona Sur)

  • Ecuación estimada: \(\widehat{preciom} = -259.28 + 1.33(areaconst) + 57.45(estrato) - 19.52(habitaciones) + 77.67(parqueaderos) + 45.72(banios)\)
  • R² = 0.7639 | R² ajustado = 0.7633 | F estadísticamente significativo (p < 0.001)
  • Todas las variables son estadísticamente significativas
  • VIF máximo: Baños = 2.68 → sin multicolinealidad severa
  • Supuestos: linealidad general cumplida; heterocedasticidad presente; cola superior con desviación de normalidad; observación 2373 influyente

2.5.2.4 Comparación de Modelos

Indicador Modelo Vivienda 1 (Casas Norte) Modelo Vivienda 2 (Aptos Sur)
0.6589 0.7639
R² Ajustado 0.6564 0.7633
Heterocedasticidad Presente Presente
Multicolinealidad Ausente (VIF < 3) Ausente (VIF < 3)
Variables sig. 4 de 5 5 de 5

El modelo de apartamentos en la Zona Sur presenta un mejor ajuste global (R² = 0.76 vs. 0.66), lo que puede atribuirse a la mayor homogeneidad del segmento de apartamentos frente a las casas, y al mayor tamaño de la muestra (2777 vs. ~700 registros). En ambos modelos se sugiere explorar transformaciones logarítmicas del precio y el área, o la inclusión de variables adicionales (como el barrio o el piso), para corregir la heterocedasticidad detectada y mejorar el ajuste.

2.6 Referencias Bibliográficas

  • Kutner, M. H., Nachtsheim, C. J., Neter, J., & Li, W. (2004). Applied Linear Statistical Models (5th ed.). McGraw-Hill/Irwin

  • Wooldridge, J. M. (2012). Introductory Econometrics: A Modern Approach (5th ed.). Cengage Learning.

Información tomada del enlace: https://rpubs.com/rflorezb/1397871