1. Problema

Para responder al requerimiento de su empresa y facilitar la comprensión del proceso de análisis de la compra de las dos viviendas, vamos a desarrollar un código en R paso a paso. Este código incluirá comentarios para cada sección y línea de código, explicando el propósito y la función de cada uno. Como primera medida, dado que la base de datos permitirá establecer un correcto proceso de selección, se hará un proceso de imputación a la variable parqueaderos, y suponer, que aquellos registros con información faltante, es porque no registran parqueaderos (0).

Adicionalmente, se eliminará las variables Piso y Barrio, dado que no son funcionales para el análisis y contienen una cantidad significativa de datos faltantes. Una vez implementado esto, los demás datos faltantes serán removidos de la base, para poder recomendarle un inmueble con características ciertas, y no supuestas.

#Carga de librerías a utilizar en el desarrollo del informe ejecutivo
# devtools::install_github("dgonxalex80/paqueteMODELOS", force = TRUE)
library(paqueteMET)
suppressMessages(library(paqueteMET))
suppressMessages(library(knitr))
suppressMessages(library(dplyr))
suppressMessages(library(ggplot2))
knitr::opts_chunk$set(echo = TRUE)
suppressMessages(library(tidyverse))
suppressMessages(library(sp)) 
suppressMessages(library(maps)) 
suppressMessages(library(plotly)) 

#  Eliminar columnas piso y barrio
vivienda <- vivienda[, !(names(vivienda) %in% c("barrio","piso"))]

# Imputación de variable parqueaderos
vivienda <- vivienda %>%
mutate(parqueaderos = replace_na(parqueaderos, 0))

# Descarte de registro con N.A.
vivienda_sin_na <- na.omit(vivienda)
na_count <- vivienda_sin_na %>% 
summarise(across(everything(), ~sum(is.na(.))))

# Ver los resultados
print(na_count)
## # A tibble: 1 × 11
##      id  zona estrato preciom areaconst parqueaderos banios habitaciones  tipo
##   <int> <int>   <int>   <int>     <int>        <int>  <int>        <int> <int>
## 1     0     0       0       0         0            0      0            0     0
## # ℹ 2 more variables: longitud <int>, latitud <int>

Es importante mencionar, que como primera medida, se hará una revisión de la información general de la ubicación de las viviendas de la base de datos brindada para su análisis:

Información General de ubicación de las viviendas

A continuación, se detallan los valores promedios de longitud y latitud por Zona de la ciudad de Cali, para tener una referencia, al momento de entrar a evaluar cada requerimiento en particular:

Los rangos promedio de longitud y latitud por cada zona son los siguientes:

  • Zona Centro:

Longitud promedio: -76.5200
Latitud promedio: 3.4427

  • Zona Norte:

Longitud promedio: -76.5283
Latitud promedio: 3.4154

  • Zona Oeste:

Longitud promedio: -76.5257
Latitud promedio: 3.4269

  • Zona Oriente:

Longitud promedio: -76.5134
Latitud promedio: 3.4170

  • Zona Sur:

Longitud promedio: -76.5150
Latitud promedio: 3.4149

Una vez referenciado los puntos, se presentará un gráfico de densidad y de ubicación, para poder visualizar, en donde se encuentran ubicados los inmuebles, y donde se concentran la mayor cantidad:

ggplot(vivienda_sin_na, aes(x = longitud, y = latitud)) + 
  geom_point(alpha = 0.5) +  # Puntos semitransparentes para visualizar la densidad
  stat_density_2d(aes(fill = ..level..), geom = "polygon") + 
  scale_fill_viridis_c() +  # Utilizar una escala de color
  labs(fill = "Densidad") +  # Etiqueta para la barra de color
  theme_minimal() +  # Un tema minimalista para el gráfico
  ggtitle("Densidad de Viviendas por Zona")  # Título del gráfico

A continuación, se detalla el análisis de la gráfica:

  • Puntos Negros: Representan la ubicación de una vivienda individual según su longitud (eje x) y latitud (eje y).

  • Áreas de Color: Muestra las regiones con mayor o menor número de viviendas.

  • Paleta de Colores: El púrpura oscuro representa áreas de baja densidad, mientras que el amarillo representa las áreas de mayor densidad.

Una vez presentada la ubicación general de todos los registros, procedemos a evaluar cada requerimiento particular:

Requerimiento No. 1.1

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

Características del inmueble:

  • Tipo: Casa
  • Área construida: 200
  • Parqueaderos: 1
  • Baños: 2
  • Habitaciones: 4
  • Estrato: 4 o 5
  • Zona: Norte
  • Crédito preaprobado: 350 Millones de pesos

Como primera medida, se realizará una proceso de filtrado a la base de datos original, para establecer un alcance, acorde a los requerimientos presentados:

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

# Filtrar las casas en la zona norte
base1 <- vivienda_sin_na %>% 
  filter(tipo == 'Casa' & zona == 'Zona Norte')

# Mostrar los primeros 3 registros
head(base1, 3)
## # A tibble: 3 × 11
##      id zona    estrato preciom areaconst parqueaderos banios habitaciones tipo 
##   <dbl> <chr>     <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl> <chr>
## 1  1209 Zona N…       5     320       150            2      4            6 Casa 
## 2  1592 Zona N…       5     780       380            2      3            3 Casa 
## 3  4057 Zona N…       6     750       445            0      7            6 Casa 
## # ℹ 2 more variables: longitud <dbl>, latitud <dbl>
print(base1,3)
## # A
## #   tibble:
## #   722
## #   ×
## #   11
## # ℹ 712 more rows
## # ℹ 11 more variables: id <dbl>, zona <chr>, estrato <dbl>, preciom <dbl>, areaconst <dbl>, parqueaderos <dbl>, banios <dbl>, habitaciones <dbl>, tipo <chr>, longitud <dbl>, latitud <dbl>
# Generar un mapa con los puntos de las bases
# Suponiendo que tenemos las coordenadas geográficas
ggplot(base1, aes(x = longitud, y = latitud)) +
  geom_point(color = "red") +
  ggtitle("Ubicación de las casas en la Zona Norte") +
  theme_minimal()

library(leaflet)

# Coordenadas aproximadas del centro de Cali, Colombia
cali_lat <- 3.4516
cali_lon <- -76.53198

# Crear un mapa con leaflet centrado en Cali
leaflet() %>%
  addTiles() %>%  # Añadir mapa base
  setView(lng = cali_lon, lat = cali_lat, zoom = 12) %>%  # Centrar en Cali con un nivel de zoom adecuado
  addMarkers(lng = base1$longitud, lat = base1$latitud, popup = "Zona norte")

Con base en el gráfico presentado, le presentamos el siguiente análisis:

  • La descripción de la Zona Norte muestra que la longitud varía entre -76.58915 y -76.46745 y la latitud entre 3.33308 y 3.49770. Estos rangos deben ser consistentes con la ubicación geográfica de la Zona Norte dentro de la ciudad.

  • Comparando estos rangos con los de otras zonas, parece que hay una superposición en los rangos de longitud y latitud entre las diferentes zonas. Por ejemplo, la Zona Centro, Oeste, Oriente y Sur tienen rangos de longitud y latitud que se superponen con los de la Zona Norte. Esto significa que algunos de los puntos mostrados en la gráfica podrían estar ubicados en zonas adyacentes si consideramos solo las coordenadas geográficas.

Por último, presentamos el gráfico de densidad de la ubicación: Zona Norte:

ggplot(base1, aes(x = longitud, y = latitud)) + 
  geom_point(alpha = 0.5) +  # Puntos semitransparentes para visualizar la densidad
  stat_density_2d(aes(fill = ..level..), geom = "polygon") + 
  scale_fill_viridis_c() +  # Utilizar una escala de color
  labs(fill = "Densidad") +  # Etiqueta para la barra de color
  theme_minimal() +  # Un tema minimalista para el gráfico
  ggtitle("Densidad de Viviendas por Zona")  # Título del gráfico

Requerimiento No. 1.2

-Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.

A continuación, procedemos a realizar un análisis exploratorio de datos enfocado en la correlación entre el precio de la casa, en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda:

#PASO2: Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.

matriz_correlacion <- base1 %>%
  select(preciom, areaconst, estrato, banios, habitaciones) %>%
  cor()

plot_ly(z = matriz_correlacion, x = colnames(matriz_correlacion), y = rownames(matriz_correlacion), type = "heatmap", colorscale = "Viridis") %>%
  layout(title = "Matriz de Correlación de Precio y Características de Viviendas")

A continuación, presentamos el análisis del gráfico de correlación:

  • Correlación Positiva Fuerte: Las celdas con colores más cercanos al amarillo indican una correlación positiva fuerte. Si alguna de estas celdas corresponde al par (preciom, areaconst) o (preciom, estrato), esto sugeriría que a medida que el área construida o el estrato de la vivienda aumenta, también lo hace el precio, lo cual es una tendencia esperada en el mercado inmobiliario.

  • Correlación Moderada: Colores intermedios, como el verde, podrían indicar una correlación moderada. Esto podría sugerir que variables como el número de baños y habitaciones tienen un impacto notable, pero no tan significativo como el área construida o el estrato, en el precio de la vivienda.

-Correlaciones Bajas o Nulas: Las celdas con colores más oscuros indican una correlación baja o nula.

  • Autocorrelación: En la diagonal principal, donde se compara cada variable consigo misma, la correlación es igual a 1 (Color amarillo).

Una vez observada la correlación entre variables, se procede a presentar los gráficos de correlación de la variable precio en función de cada una de las características del inmueble:

# Genera los subgráficos
p1 <- plot_ly(base1, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers', name = "Área Construida") %>%
  layout(title = 'Área Construida vs Precio', margin = list(b = 40))

p2 <- plot_ly(base1, x = ~estrato, y = ~preciom, type = 'scatter', mode = 'markers', name = "Estrato") %>%
  layout(title = 'Estrato vs Precio', margin = list(b = 40))

p3 <- plot_ly(base1, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers', name = "Número de Baños") %>%
  layout(title = 'Número de Baños vs Precio', margin = list(t = 40))

p4 <- plot_ly(base1, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers', name = "Número de Habitaciones") %>%
  layout(title = 'Número de Habitaciones vs Precio', margin = list(t = 40))

# Combinar los gráficos en un solo gráfico con 4 subgráficos
subplot(
  p1, p2, p3, p4,
  nrows = 2,
  shareX = FALSE, 
  shareY = FALSE, 
  titleX = TRUE, 
  titleY = TRUE,
  margin = 0.09,
  heights = c(0.5, 0.5)
) %>% layout(title = 'Comparación de Características vs Precio')

Análisis de correlación por característica:

  • Área Construida vs Precio: Relación positiva entre el área construida de las viviendas y sus precios. Las viviendas con mayor área tienden a tener precios más altos. Por lo tanto, el área construida es un factor significativo en la valoración de las viviendas. Sin embargo, hay una gran dispersión en los datos, lo que sugiere que otros factores también influyen en el precio.

  • Estrato vs Precio: El precio de la vivienda aumenta con el estrato, lo cual es consistente con la expectativa de que las viviendas en estratos más altos tienen precios más altos. Los puntos se agrupan según el estrato, lo que indica niveles de precios distintos para cada estrato

  • Número de Baños vs Precio: Las viviendas con más baños tienden a tener precios más altos, aunque la relación no es tan fuerte como con el área construida o el estrato

  • Número de Habitaciones vs Precio: Similar al número de baños, las viviendas con más habitaciones tienden a ser más caras. La relación es más dispersa para viviendas con un número mayor de habitaciones.

A continuación, procedemos a realizar una estimación de un modelo de regresión lineal múltiple, para validar si la valoración estadística del mismo, permite determinar la posible acertividad y eficiencia en la estimación de posibles precios de viviendas:

Requerimiento No. 1.3

- Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).
#PASO3: Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

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

# Resumen del modelo para interpretación de coeficientes y R2
summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -964.04  -80.10  -17.08   50.06 1069.45 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -236.47551   30.36582  -7.788 2.40e-14 ***
## areaconst       0.82677    0.04368  18.926  < 2e-16 ***
## estrato        86.42579    7.39747  11.683  < 2e-16 ***
## habitaciones    1.44443    4.16411   0.347    0.729    
## parqueaderos   -1.67672    4.31505  -0.389    0.698    
## banios         26.97978    5.34384   5.049 5.65e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 159.1 on 716 degrees of freedom
## Multiple R-squared:  0.6508, Adjusted R-squared:  0.6484 
## F-statistic: 266.9 on 5 and 716 DF,  p-value: < 2.2e-16

A continuación, presentamos la interpretación de los estadísticos del modelo de regresión lineal múltiple obtenido:

  • Interpretación de coeficientes:

    • Intercept (-236.47551): Valor estimado del precio de la vivienda cuando todas las variables independientes son cero, lo cual no es lógico en el contexto real porque no se puede tener una vivienda con área cero, estrato cero, etc. Este valor es estadísticamente significativo con un valor p muy bajo, lo que indica que es diferente de cero.

    • areaconst (0.82677): Por cada metro cuadrado adicional de área construida, el precio de la vivienda aumenta en promedio 0.82677 millones de pesos. Este coeficiente es estadísticamente significativo y lógico, ya que se espera que una vivienda más grande tenga mayor precio.

    • estrato (86.42579): Por cada nivel adicional de estrato, el precio de la vivienda aumenta en promedio 86.4 millones de pesos. Este resultado es estadísticamente significativo y tiene sentido, ya que los estratos más altos suelen asociarse con mejores servicios y localizaciones más deseables.

    • habitaciones (1.4443): El número de habitaciones tiene un coeficiente positivo, lo que sugiere que a medida que aumenta el número de habitaciones, también lo hace el precio de la vivienda. Sin embargo, este coeficiente no es estadísticamente significativo (p > 0.05), lo que indica que no hay suficiente evidencia para afirmar que el número de habitaciones afecta el precio de la vivienda en esta muestra.

    • parqueaderos (-1.67672): Por cada parqueadero adicional, el precio disminuye en promedio 1.6762 unidades. A pesar de que este efecto no es lo esperado, no es estadísticamente significativo. (p > 0.05)

    • banios (26.97978): Cada baño adicional parece aumentar el precio de la vivienda en 26.9798 millones de pesos.

  • Interpretación del Ajuste del Modelo:

    • Multiple R-squared (0.6508): Alrededor del 65.08% de la variabilidad en el precio de la vivienda puede ser explicada por el modelo. Lo que indica que el modelo tiene un buen ajuste.

    • Adjusted R-squared (0.6484): Este valor ajusta el R-squared basándose en el número de predictores en el modelo y el tamaño de la muestra, y sigue siendo alto, lo que confirma que el modelo es adecuado.

    • F-statistic: El valor de la prueba F es muy alto y el valor p asociado es menor que 2.2e-16, lo que indica que el modelo es estadísticamente significativo en su conjunto.

  • Implicaciones y Mejoras:

Los resultados indican que el área construida, el estrato y el número de parqueaderos son factores importantes que influyen en el precio de una vivienda. Para mejorar el modelo, se podría:

  • Incluir más variables: Pueden existir otros factores no considerados en el modelo que influyen en el precio, como la antigüedad de la vivienda, la ubicación exacta o las comodidades cercanas.
  • Los residuos sugieren que hay algunas predicciones que están muy lejos de los valores reales. Revisar y posiblemente excluir outliers podría mejorar el modelo.
  • Investigar si existen interacciones significativas entre las variables o si las relaciones entre las variables y el precio no son lineales.

Requerimiento No. 1.4

-Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

A continuación, se presenta el diagnóstico del modelo para la validación de supuestos:

#PASO4: Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

# Diagnóstico del modelo para verificar supuestos
par(mfrow = c(2, 2))
plot(modelo)

Aquí está la interpretación de cada uno:

  • Residuales vs Valores Ajustados: No se identifica un patrón claro y definido, lo cual es bueno, ya que indica que no hay estructuras obvias no capturadas por el modelo. Sin embargo, hay algunos puntos con residuos altos, lo que podría indicar valores atípicos o que el modelo no es perfecto para esos casos. Sugerencia: Investigar los casos con residuos altos para entender si se deben a datos anómalos o si hay un patrón no capturado por el modelo. Considerar incluir otras variables explicativas si es necesario.

  • Q-Q Plot de los Residuos: Los residuos siguen de cerca la línea recta en el medio del gráfico, pero desvían en los extremos. Esto sugiere que los residuos tienen colas más pesadas que una distribución normal, lo que puede indicar presencia de datos atípicos o que la relación no es completamente lineal.Sugerencia: Si los residuos tienen colas pesadas, se podría considerar la posibilidad de que haya datos atípicos significativos que afecten al modelo. Estos datos podrían ser examinados más detenidamente para ver si deben ser excluidos o si se necesita un modelo diferente que los trate mejor.

  • Gráfico de Ubicación-Escala: Hay un ligero incremento en la dispersión de los residuos estandarizados a medida que aumentan los valores ajustados, lo que podría indicar heterocedasticidad. Esto significa que la varianza de los errores no es constante. Sugerencia: Si se confirma la heterocedasticidad, se podrían aplicar transformaciones a la variable de respuesta (como la logarítmica) o se podrían utilizar errores estándar robustos o modelos ponderados para abordar este problema

  • Residuos vs Apalancamiento (Leverage): La mayoría de los puntos tienen un bajo apalancamiento, pero hay unos pocos puntos fuera de las líneas de distancia de Cook, lo que sugiere que podrían ser puntos de influencia. Sugerencia: Identificar y examinar los puntos con alto apalancamiento y residuos grandes para decidir si representan datos válidos o si son anomalías. Si son errores o datos atípicos no representativos, podrían ser removidos.

Requerimiento No. 1.5

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

Teniendo en cuenta el modelo descrito, se procede a establecer una predicción del precio acorde a las características del primer requerimiento:

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

# Predicción usando el modelo estimado
prediccion1 <- predict(modelo, newdata = data.frame(areaconst = 200, estrato = 4, habitaciones = 4, parqueaderos = 1, banios = 2))

# Mostrar la predicción
prediccion1
##       1 
## 332.643

El valor de la predicción corresponde a 332.643 Millones de pesos. El cual, está cubierto a través del crédito preaprobado que maneja actualmente.

Requerimiento No. 1.6

- A continuación, se procede a filtrar la base de datos acorde a todos las características del primer requerimiento:
#PASO6: Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

# Paso 1: Predecir precios usando el modelo
base1$precio_predicho <- predict(modelo, newdata = base1)

# Paso 2: Filtrar viviendas que cumplen con los criterios de la vivienda 1 y están dentro del presupuesto
ofertas_potenciales <- base1 %>%
  filter(tipo == "Casa", 
         areaconst >= 200, 
         parqueaderos >= 1, 
         banios >= 2, 
         habitaciones >= 4, 
         estrato %in% c(4, 5), 
         preciom <= 350) %>%
  arrange((preciom)) # Ordenar por precio de menor a mayor

# Paso 3: Seleccionar 5 ofertas potenciales
print(ofertas_potenciales, n = Inf)
## # A tibble: 34 × 12
##       id zona   estrato preciom areaconst parqueaderos banios habitaciones tipo 
##    <dbl> <chr>    <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl> <chr>
##  1  1020 Zona …       4     230      250             2      3            5 Casa 
##  2  1009 Zona …       5     250      243             1      4            5 Casa 
##  3  7432 Zona …       4     260      280             2      4            6 Casa 
##  4  1914 Zona …       5     300      205             2      5            6 Casa 
##  5  4458 Zona …       4     315      270             2      4            4 Casa 
##  6  1343 Zona …       5     320      200             2      4            4 Casa 
##  7  3053 Zona …       5     320      230             2      4            4 Casa 
##  8  1144 Zona …       4     320      200             2      4            4 Casa 
##  9  1151 Zona …       5     320      210             2      3            5 Casa 
## 10   766 Zona …       5     321      249             1      5            5 Casa 
## 11   952 Zona …       4     330      275             2      3            5 Casa 
## 12  1108 Zona …       4     330      260             1      3            4 Casa 
## 13  3043 Zona …       5     330      275             2      3            5 Casa 
## 14  1849 Zona …       5     330      246             2      4            4 Casa 
## 15  4267 Zona …       5     335      202             1      4            5 Casa 
## 16  3352 Zona …       4     335      300             3      4            4 Casa 
## 17  4800 Zona …       5     340      250             2      4            4 Casa 
## 18  3453 Zona …       5     340      240             2      5            6 Casa 
## 19  3101 Zona …       5     340      355             2      5            8 Casa 
## 20  1887 Zona …       5     340      203             2      3            4 Casa 
## 21  2544 Zona …       4     340      264.            2      4            4 Casa 
## 22  7470 Zona …       4     340      264             2      5            7 Casa 
## 23  1822 Zona …       4     340      295             2      2            4 Casa 
## 24  4483 Zona …       5     342      250             1      4            6 Casa 
## 25  4210 Zona …       5     350      200             3      3            4 Casa 
## 26  4209 Zona …       5     350      300             3      5            6 Casa 
## 27  4422 Zona …       5     350      240             2      3            6 Casa 
## 28  1270 Zona …       5     350      203             2      2            5 Casa 
## 29   819 Zona …       5     350      264             2      3            4 Casa 
## 30   937 Zona …       4     350      280             2      3            4 Casa 
## 31  1163 Zona …       5     350      216             2      2            4 Casa 
## 32  5031 Zona …       4     350      350             1      4            5 Casa 
## 33  1842 Zona …       5     350      240             2      3            4 Casa 
## 34  1943 Zona …       5     350      346             1      2            4 Casa 
## # ℹ 3 more variables: longitud <dbl>, latitud <dbl>, precio_predicho <dbl>

Se observa, que existen un total de 34 inmuebles en la base de datos que cumplen con los requerimientos establecidos. Por lo tanto, y teniendo en cuenta que la predicción del modelo estableció un valor aproximado del inmueble de 332.6 Millones de pesos, recomendamos las 5 ofertas de inmuebles que están más cercanos (por debajo) a este valor y cumplen con todos los requerimientos:

# Asumiendo que 'ofertas_potenciales' es tu dataframe y ya contiene la columna 'preciom'
valor_referencia <- 335.7

# Añadir una nueva columna con la diferencia absoluta entre 'preciom' y el valor de referencia
ofertas_potenciales <- ofertas_potenciales %>%
  mutate(diferencia_abs = abs(preciom - valor_referencia))

# Ordenar el dataframe por la diferencia absoluta y seleccionar los 5 registros superiores
ofertas_cercanas <- ofertas_potenciales %>%
  arrange(diferencia_abs) %>%
  head(5)

# Mostrar los resultados
print(ofertas_cercanas)
## # A tibble: 5 × 13
##      id zona    estrato preciom areaconst parqueaderos banios habitaciones tipo 
##   <dbl> <chr>     <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl> <chr>
## 1  4267 Zona N…       5     335       202            1      4            5 Casa 
## 2  3352 Zona N…       4     335       300            3      4            4 Casa 
## 3  4800 Zona N…       5     340       250            2      4            4 Casa 
## 4  3453 Zona N…       5     340       240            2      5            6 Casa 
## 5  3101 Zona N…       5     340       355            2      5            8 Casa 
## # ℹ 4 more variables: longitud <dbl>, latitud <dbl>, precio_predicho <dbl>,
## #   diferencia_abs <dbl>

Teniendo en cuenta la selección de las 5 sugerencias potenciales que cumplen con su total requerimiento, procedemos a mostrar su ubicación para mayyor información:

ggplot(ofertas_cercanas, aes(x = longitud, y = latitud)) +
  geom_point(color = "red") +
  ggtitle("Ubicación de las casas en la Zona Norte") +
  theme_minimal()

library(leaflet)

# Coordenadas aproximadas del centro de Cali, Colombia
cali_lat <- 3.4516
cali_lon <- -76.53198

# Crear un mapa con leaflet centrado en Cali
leaflet() %>%
  addTiles() %>%  # Añadir mapa base
  setView(lng = cali_lon, lat = cali_lat, zoom = 12) %>%  # Centrar en Cali con un nivel de zoom adecuado
  addMarkers(lng = ofertas_cercanas$longitud, lat = ofertas_cercanas$latitud, popup = "Oferta cercana")  # Añadir marcadores para ofertas_cercanas

Requerimiento No. 2.1

-Realice un filtro a la base de datos e incluya solo las ofertas de : base2: apartamento, de la zona sur de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).
#Carga de librerías a utilizar en el desarrollo del informe ejecutivo
# devtools::install_github("dgonxalex80/paqueteMODELOS", force = TRUE)
library(paqueteMET)
suppressMessages(library(paqueteMET))
suppressMessages(library(knitr))
suppressMessages(library(dplyr))
suppressMessages(library(ggplot2))
knitr::opts_chunk$set(echo = TRUE)
suppressMessages(library(tidyverse))
suppressMessages(library(sp)) 
suppressMessages(library(maps)) 
suppressMessages(library(plotly)) 

#  Eliminar columnas piso y barrio
vivienda <- vivienda[, !(names(vivienda) %in% c("piso", "barrio"))]

# Imputación de variable parqueaderos
vivienda <- vivienda %>%
mutate(parqueaderos = replace_na(parqueaderos, 0))

# Descarte de registro con N.A.
vivienda_sin_na <- na.omit(vivienda)
na_count <- vivienda_sin_na %>% 
summarise(across(everything(), ~sum(is.na(.))))

# Ver los resultados
print(na_count)
## # A tibble: 1 × 11
##      id  zona estrato preciom areaconst parqueaderos banios habitaciones  tipo
##   <int> <int>   <int>   <int>     <int>        <int>  <int>        <int> <int>
## 1     0     0       0       0         0            0      0            0     0
## # ℹ 2 more variables: longitud <int>, latitud <int>

Características del inmueble:

  • Tipo: Apartamento
  • Área construida: 300
  • Parqueaderos: 3
  • Baños: 3
  • Habitaciones: 5
  • Estrato: 5 o 6
  • Zona: Sur
  • Crédito preaprobado: 850 Millones de pesos

Como primera medida, se realizará una proceso de filtrado a la base de datos original, para establecer un alcance, acorde a los requerimientos presentados:

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

# Filtrar las casas en la zona norte
base1 <- vivienda_sin_na %>% 
  filter(tipo == 'Apartamento' & zona == 'Zona Sur')

# Mostrar los primeros 3 registros
head(base1, 3)
## # A tibble: 3 × 11
##      id zona    estrato preciom areaconst parqueaderos banios habitaciones tipo 
##   <dbl> <chr>     <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl> <chr>
## 1  5098 Zona S…       4     290        96            1      2            3 Apar…
## 2   698 Zona S…       3      78        40            1      1            2 Apar…
## 3  8199 Zona S…       6     875       194            2      5            3 Apar…
## # ℹ 2 more variables: longitud <dbl>, latitud <dbl>
print(base1,3)
## # A
## #   tibble:
## #   2,787
## #   ×
## #   11
## # ℹ 2,777 more rows
## # ℹ 11 more variables: id <dbl>, zona <chr>, estrato <dbl>, preciom <dbl>, areaconst <dbl>, parqueaderos <dbl>, banios <dbl>, habitaciones <dbl>, tipo <chr>, longitud <dbl>, latitud <dbl>
# Generar un mapa con los puntos de las bases
# Suponiendo que tenemos las coordenadas geográficas
ggplot(base1, aes(x = longitud, y = latitud)) +
  geom_point(color = "blue") +
  ggtitle("Ubicación de las casas en la Zona Sur") +
  theme_minimal()

library(leaflet)

# Coordenadas aproximadas del centro de Cali, Colombia
cali_lat <- 3.4516
cali_lon <- -76.53198

# Crear un mapa con leaflet centrado en Cali
leaflet() %>%
  addTiles() %>%  # Añadir mapa base
  setView(lng = cali_lon, lat = cali_lat, zoom = 12) %>%  # Centrar en Cali con un nivel de zoom adecuado
  addMarkers(lng = base1$longitud, lat = base1$latitud, popup = "Zona Sur")

Con base en el gráfico presentado, le presentamos el siguiente análisis:

  • Las áreas periféricas parecen tener una menor densidad de casas.
  • Las agrupaciones de puntos pueden señalar barrios residenciales o desarrollos habitacionales. Las áreas con pocos o ningún punto podrían indicar zonas de potencial crecimiento o áreas no residenciales.
  • La mayor concentración de viviendas en el centro de la gráfica puede indicar un centro de actividad económica y social, lo que podría hacer estas áreas particularmente atractivas para la compra de vivienda debido a la proximidad a servicios y comercios
  • Para proyectos inmobiliarios, las áreas con menor densidad de viviendas podrían ser objetivo de futuros desarrollos y mejoras en infraestructura
  • Las áreas de alta densidad pueden requerir análisis adicionales sobre movilidad y accesibilidad, considerando la posible congestión y la necesidad de opciones de transporte eficientes.

Por último, presentamos el gráfico de densidad de la ubicación: Zona Sur:

ggplot(base1, aes(x = longitud, y = latitud)) + 
  geom_point(alpha = 0.5) +  # Puntos semitransparentes para visualizar la densidad
  stat_density_2d(aes(fill = ..level..), geom = "polygon") + 
  scale_fill_viridis_c() +  # Utilizar una escala de color
  labs(fill = "Densidad") +  # Etiqueta para la barra de color
  theme_minimal() +  # Un tema minimalista para el gráfico
  ggtitle("Densidad de Viviendas por Zona")  # Título del gráfico

Requerimiento No. 2.2

-Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.

A continuación, procedemos a realizar un análisis exploratorio de datos enfocado en la correlación entre el precio de la casa, en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda:

#PASO2: Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.

matriz_correlacion <- base1 %>%
  select(preciom, areaconst, estrato, banios, habitaciones) %>%
  cor()

plot_ly(z = matriz_correlacion, x = colnames(matriz_correlacion), y = rownames(matriz_correlacion), type = "heatmap", colorscale = "Viridis") %>%
  layout(title = "Matriz de Correlación de Precio y Características de Viviendas")

A continuación, presentamos el análisis del gráfico de correlación:

  • Correlación Positiva Fuerte: Las celdas con colores más cercanos al amarillo indican una correlación positiva fuerte. Si alguna de estas celdas corresponde al par (preciom, areaconst) o (preciom, estrato), esto sugeriría que a medida que el área construida o el estrato de la vivienda aumenta, también lo hace el precio, lo cual es una tendencia esperada en el mercado inmobiliario.

  • Correlación Moderada: Colores intermedios, como el verde, podrían indicar una correlación moderada. Esto podría sugerir que variables como el número de baños y habitaciones tienen un impacto notable, pero no tan significativo como el área construida o el estrato, en el precio de la vivienda.

-Correlaciones Bajas o Nulas: Las celdas con colores más oscuros indican una correlación baja o nula.

  • Autocorrelación: En la diagonal principal, donde se compara cada variable consigo misma, la correlación es igual a 1 (Color amarillo).

Una vez observada la correlación entre variables, se procede a presentar los gráficos de correlación de la variable precio en función de cada una de las características del inmueble:

# Genera los subgráficos
p1 <- plot_ly(base1, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers', name = "Área Construida") %>%
  layout(title = 'Área Construida vs Precio', margin = list(b = 40))

p2 <- plot_ly(base1, x = ~estrato, y = ~preciom, type = 'scatter', mode = 'markers', name = "Estrato") %>%
  layout(title = 'Estrato vs Precio', margin = list(b = 40))

p3 <- plot_ly(base1, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers', name = "Número de Baños") %>%
  layout(title = 'Número de Baños vs Precio', margin = list(t = 40))

p4 <- plot_ly(base1, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers', name = "Número de Habitaciones") %>%
  layout(title = 'Número de Habitaciones vs Precio', margin = list(t = 40))

# Combinar los gráficos en un solo gráfico con 4 subgráficos
subplot(
  p1, p2, p3, p4,
  nrows = 2,
  shareX = FALSE, 
  shareY = FALSE, 
  titleX = TRUE, 
  titleY = TRUE,
  margin = 0.09,
  heights = c(0.5, 0.5)
) %>% layout(title = 'Comparación de Características vs Precio')

Análisis de correlación por característica:

  • Área Construida vs Precio: Fuerte correlación positiva entre el precio y el área construida, como lo indica el color más claro en la celda. Esto significa que, generalmente, cuanto mayor es el área construida de una vivienda, más alto es su precio.

  • Estrato vs Precio: Correlación positiva entre el precio y el estrato de la vivienda. Indinca que inmuebles en estratos más altos tienden a tener precios más altos, lo cual es lógico ya que estratos más altos suelen asociarse con mejores servicios y ubicaciones deseables

  • Número de Baños vs Precio: La correlación entre el precio y el número de baños es menos fuerte que la del área construida o el estrato, pero aún es positiva. Esto sugiere que más baños pueden incrementar el precio de la vivienda, pero no tanto como el área construida o el estrato

  • Número de Habitaciones vs Precio: La correlación es relativamente débil, lo que sugiere que el número de habitaciones no es un predictor tan fuerte del precio como el área construida o el estrato.

A continuación, procedemos a realizar una estimación de un modelo de regresión lineal múltiple, para validar si la valoración estadística del mismo, permite determinar la posible acertividad y eficiencia en la estimación de posibles precios de viviendas:

Requerimiento No. 2.3

- Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).
#PASO3: Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

# Estimación del modelo de regresión lineal
modelo2 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base1)

# Resumen del modelo para interpretación de coeficientes y R2
summary(modelo2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1252.31   -42.15    -2.06    36.32   934.06 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -221.04614   13.47771 -16.401  < 2e-16 ***
## areaconst       1.46061    0.04876  29.956  < 2e-16 ***
## estrato        57.00608    2.79648  20.385  < 2e-16 ***
## habitaciones  -22.71789    3.39549  -6.691 2.68e-11 ***
## parqueaderos   48.36353    3.02343  15.996  < 2e-16 ***
## banios         48.60871    3.04050  15.987  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 95.17 on 2781 degrees of freedom
## Multiple R-squared:  0.7536, Adjusted R-squared:  0.7531 
## F-statistic:  1701 on 5 and 2781 DF,  p-value: < 2.2e-16

A continuación, presentamos la interpretación de los estadísticos del modelo de regresión lineal múltiple obtenido:

  • Interpretación de coeficientes:

    • Intercept (-221.04614): Valor estimado del precio de la vivienda cuando todas las variables independientes son cero, lo cual no es lógico en el contexto real porque no se puede tener una vivienda con área cero, estrato cero, etc. Este valor es estadísticamente significativo con un valor p muy bajo, lo que indica que es diferente de cero.

    • areaconst (1.46061): Por cada metro cuadrado adicional de área construida, el precio de la vivienda aumenta en promedio 1.46061 millones de pesos. Este coeficiente es estadísticamente significativo y lógico, ya que se espera que una vivienda más grande tenga mayor precio, y en mayor proporción que el requerimiento No. 1, dado que este análisis se realiza para un estrato más alto.

    • estrato (57.00608): Por cada nivel adicional de estrato, el precio de la vivienda aumenta en promedio 57.00608 millones de pesos. Este resultado es estadísticamente significativo y tiene sentido, ya que los estratos más altos suelen asociarse con mejores servicios y localizaciones más deseables.

    • habitaciones (-22.71789): Por cada habitación adicional, el precio disminuye en promedio 22.71789 unidades. A pesar de que este efecto no es lo esperado, es estadísticamente significativo.

    • parqueaderos (48.6353): Por cada parqueadero adicional, el precio de la vivienda aumenta en promedio 48.6353 millones de pesos. Este coeficiente es estadísticamente significativo y es razonable, ya que los parqueaderos adicionales son una comodidad valorada.

    • banios (48.60871): Cada baño adicional parece aumentar el precio de la vivienda en 48.60871 millones de pesos.

  • Interpretación del Ajuste del Modelo:

    • Multiple R-squared (0.7536): Alrededor del 75.36% de la variabilidad en el precio de la vivienda puede ser explicada por el modelo. Lo que indica que el modelo tiene un buen ajuste.

    • Adjusted R-squared (0.7531): Este valor ajusta el R-squared basándose en el número de predictores en el modelo y el tamaño de la muestra, y sigue siendo alto, lo que confirma que el modelo es adecuado.

    • F-statistic: El valor de la prueba F es muy alto y el valor p asociado es menor que 2.2e-16, lo que indica que el modelo es estadísticamente significativo en su conjunto.

  • Implicaciones y Mejoras:

Los resultados indican que el área construida, el estrato y el número de parqueaderos son factores importantes que influyen en el precio de una vivienda. Para mejorar el modelo, se podría:

  • Para mejorar el modelo, se recomienda considerar la posibilidad de añadir más variables que puedan influir en el precio, como la antigüedad de la vivienda, las mejoras realizadas y las comodidades cercanas.
  • También podría ser útil examinar y, si es necesario, eliminar valores atípicos que podrían estar afectando la calidad del modelo, dada la amplia gama de residuos observados.

Requerimiento No. 2.4

-Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

A continuación, se presenta el diagnóstico del modelo para la validación de supuestos:

#PASO4: Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

# Diagnóstico del modelo para verificar supuestos
par(mfrow = c(2, 2))
plot(modelo2)

Aquí está la interpretación de cada uno:

  • Residuales vs Valores Ajustados: No se identifica un patrón claro y definido, lo cual es bueno, ya que indica que no hay estructuras obvias no capturadas por el modelo. Sin embargo, hay algunos puntos con residuos altos, lo que podría indicar outliers o que el modelo no es perfecto para esos casos. Sugerencia: Investigar los casos con residuos altos para entender si se deben a datos anómalos o si hay un patrón no capturado por el modelo. Considerar incluir otras variables explicativas si es necesario.

  • Q-Q Plot de los Residuos: Los residuos siguen de cerca la línea recta en el medio del gráfico, pero desvían en los extremos. Esto sugiere que los residuos tienen colas más pesadas que una distribución normal, lo que puede ser un signo de outliers o que la relación no es completamente lineal.Sugerencia: Si los residuos tienen colas pesadas, se podría considerar la posibilidad de que haya outliers significativos que afecten al modelo. Estos datos podrían ser examinados más detenidamente para ver si deben ser excluidos o si se necesita un modelo diferente que maneje mejor los outliers.

  • Gráfico de Ubicación-Escala: Hay un ligero incremento en la dispersión de los residuos estandarizados a medida que aumentan los valores ajustados, lo que podría indicar heterocedasticidad. Esto significa que la varianza de los errores no es constante. Sugerencia: Si se confirma la heterocedasticidad, se podrían aplicar transformaciones a la variable de respuesta (como el logaritmo) o se podrían utilizar errores estándar robustos o modelos ponderados para abordar este problema

  • Residuos vs Apalancamiento (Leverage): La mayoría de los puntos tienen un bajo apalancamiento, pero hay unos pocos puntos fuera de las líneas de distancia de Cook, lo que sugiere que podrían ser puntos de influencia. Sugerencia: Identificar y examinar los puntos con alto apalancamiento y residuos grandes para decidir si representan datos válidos o si son anomalías. Si son errores o datos atípicos no representativos, podrían ser removidos. Si son válidos, se puede considerar un modelo de regresión robusta que minimice su influencia.

Requerimiento No. 2.5

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

Teniendo en cuenta el modelo descrito, se procede a establecer una predicción del precio acorde a las características del primer requerimiento:

#PASO5: Con el modelo identificado debe predecir el precio de la vivienda con las características de la segunda solicitud.

# Predicción usando el modelo estimado
prediccion2 <- predict(modelo2, newdata = data.frame(areaconst = 300, estrato = 5, habitaciones = 5, parqueaderos = 3, banios = 3))

# Mostrar la predicción
prediccion2
##        1 
## 679.4951

El valor de la predicción correspoden a 679.4951 Millones de pesos. El cual, está cubierto a través del crédito preaprobado que maneja actualmente.

Requerimiento No. 2.6

- A continuación, se procede a filtrar la base de datos acorde a todos las características del primer requerimiento:
#PASO6: Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 2. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 850 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

# Paso 1: Predecir precios usando el modelo
base1$precio_predicho <- predict(modelo2, newdata = base1)

# Paso 2: Filtrar viviendas que cumplen con los criterios de la vivienda 1 y están dentro del presupuesto
ofertas_potenciales2 <- base1 %>%
  filter(tipo == "Apartamento", 
         areaconst >= 300, 
         parqueaderos >= 3, 
         banios >= 5, 
         habitaciones >= 5, 
         estrato %in% c(5, 6), 
         preciom <= 850) %>%
  arrange((preciom)) # Ordenar por precio de menor a mayor

# Paso 3: Seleccionar 5 ofertas potenciales
print(ofertas_potenciales2, n = Inf)
## # A tibble: 2 × 12
##      id zona    estrato preciom areaconst parqueaderos banios habitaciones tipo 
##   <dbl> <chr>     <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl> <chr>
## 1  7512 Zona S…       5     670       300            3      5            6 Apar…
## 2  7182 Zona S…       5     730       573            3      8            5 Apar…
## # ℹ 3 more variables: longitud <dbl>, latitud <dbl>, precio_predicho <dbl>

Se observa, que existen un total de 2 inmuebles en la base de datos que cumplen con los requerimientos establecidos. Por lo tanto, y teniendo en cuenta que la predicción del modelo estableció un valor aproximado del inmueble de 679.4951 Millones de pesos, estos dos inmuebles serían los recomendados acorde a sus requsisitos:

# Asumiendo que 'ofertas_potenciales' es tu dataframe y ya contiene la columna 'preciom'
valor_referencia2 <- 679.4951

# Añadir una nueva columna con la diferencia absoluta entre 'preciom' y el valor de referencia
ofertas_potenciales2 <- ofertas_potenciales2 %>%
  mutate(diferencia_abs = abs(preciom - valor_referencia2))

# Ordenar el dataframe por la diferencia absoluta y seleccionar los 5 registros superiores
ofertas_cercanas2 <- ofertas_potenciales2 %>%
  arrange(diferencia_abs) %>%
  head(5)

# Mostrar los resultados
print(ofertas_cercanas2)
## # A tibble: 2 × 13
##      id zona    estrato preciom areaconst parqueaderos banios habitaciones tipo 
##   <dbl> <chr>     <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl> <chr>
## 1  7512 Zona S…       5     670       300            3      5            6 Apar…
## 2  7182 Zona S…       5     730       573            3      8            5 Apar…
## # ℹ 4 more variables: longitud <dbl>, latitud <dbl>, precio_predicho <dbl>,
## #   diferencia_abs <dbl>

Teniendo en cuenta la selección de las 2 sugerencias potenciales que cumplen con su total requerimiento, procedemos a mostrar su ubicación para mayor información:

ggplot(ofertas_cercanas2, aes(x = longitud, y = latitud)) +
  geom_point(color = "blue") +
  ggtitle("Ubicación de las casas en la Zona Sur") +
  theme_minimal()

library(leaflet)

# Coordenadas aproximadas del centro de Cali, Colombia
cali_lat <- 3.4516
cali_lon <- -76.53198

# Crear un mapa con leaflet centrado en Cali
leaflet() %>%
  addTiles() %>%  # Añadir mapa base
  setView(lng = cali_lon, lat = cali_lat, zoom = 12) %>%  # Centrar en Cali con un nivel de zoom adecuado
  addMarkers(lng = ofertas_cercanas2$longitud, lat = ofertas_cercanas2$latitud, popup = "Oferta cercana")  # Añadir marcadores para ofertas_cercanas