Informe Ejecutivo Bogotá, 01 de Septiembre de 2025
Señores INMOBILIARIA C&A
Referencia: Informe Selección de inmueble partiendo de modelo lineal multivariado.
Respetados Señores,
A continuación, el informe de las conclusiones en la elaboracion del modelo de precios de inmuebles de la ciudad de cali:
Requerimiento: Con base en la informacions de ofertas de vivienda descargadas de la base de datos, requieren el apoyo en la construcción de un modelo que les oriente sobre los precios de los inmuebles para la compañia C&A que desea ubicar a dos de sus empleados con sus familias en la ciudad de Cali.
Revisión de la data Disponible: Se recibe un dataset (o base de datos) en formato R con 8.322 filas y 13 variables disponibles para evaluar entre ellas: Zona , Estrato, Precio M2, Área Construida, Tipo de Inmueble, etc.
Frente a los requermientos del cliente evaluamos estas como las mejores opciones:
Solicitud del Cliente
Vivienda No. 1: Tipo CASA, Precio de Venta < $350 Millones, area construida 200 m2, parqueaderos 1, baños 2, habitaciones 4, estrato 4 o 5, zona Norte
Vivienda No. 2: Tipo APARTAMENTO, Precio de Venta < $850 Millones, area construida 300 m2, parqueaderos 3, baños 3, habitaciones 5, estrato 5 o 6, zona Sur
Se hace análisis de la data identificando que habian inmuebles marcados en zonas que no correspondía, para lo cual se realizo un cre de información con un shp de cali que contiene los barrio y las comunas, de esta manera se remarco la zonas de cada casa y apartamento.
Conclusiones del Modelo Evaluado.
Frente a la definición del problema inicial en la construcción de un modelo que les oriente sobre los precios de los inmuebles con la data evaluada y los diferentes modelos se puede concluir que se sugiere que se debe buscar otro tipo de modelo diferentes a los evaluados que permitan explicar esa variable de precio debido a que esta no es explicada en buena medida solo por el área construida y estrato en su gran medida.
Se adjuntan documento R-Mark Down con las líneas de código de las variables y funciones evaluadas que acompañan cada una de las interpretaciones de los gráficos y tablas relacionadas en este informe, todas realizadas en el programa R estudio.
Quedo atento a sus comentarios,
Mario Fernando Barbosa Rodriguez Cientifico de Datos.
## | |Vivienda 1 |Vivienda 2 |
## |:-------------------|:------------|:------------|
## |Tipo |Casa |Apartamento |
## |Área construida |200 |300 |
## |Parqueaderos |1 |3 |
## |Baños |2 |3 |
## |Habitaciones |4 |5 |
## |Estrato |4 o 5 |5 o 6 |
## |Zona |Norte |Sur |
## |Crédito preaprobado |350 millones |850 millones |
Proceso:
Se carga la base de datos, se verifica si hay “NA” y pone como dato faltante.
data("vivienda")
vivienda <- as.data.frame(vivienda)
Tabla con Faltantes
tabla_na <- data.frame(Variable = names(vivienda), NAs = colSums(is.na(vivienda)))
tabla_na %>% gt() %>% tab_header(title = "Valores Faltantes por Cada Variable")
| Valores Faltantes por Cada Variable | |
| Variable | NAs |
|---|---|
| id | 3 |
| zona | 3 |
| piso | 2638 |
| estrato | 3 |
| preciom | 2 |
| areaconst | 3 |
| parqueaderos | 1605 |
| banios | 3 |
| habitaciones | 3 |
| tipo | 3 |
| barrio | 3 |
| longitud | 3 |
| latitud | 3 |
Se verifica si hay “NA” y pone como dato faltante.
Se quita el campo Piso porque presenta muchos faltantes y no puede ser deducible por ningun calculo adicional.
vivienda_1 <- vivienda[,-3]
Se rellena el campo del numero de paqueaderos con 0 indicando que no tiene
vivienda_1$parqueaderos <- ifelse(is.na(vivienda_1$parqueaderos),
0,
as.numeric(vivienda_1$parqueaderos))
vivienda_1 <- na.omit(vivienda_1)
Con el fin de identificar si esta correctamente marcado la zona donde se ubica el inmueble se descargo un archivo en formato de datos vectoriales de los barrios de Cali, tomado de https://datos.cali.gov.co/es/dataset/capa-de-barrios-de-santiago-de-cali?utm_source=chatgpt.com y se carga para ser confrontado con la base a estudiar.
# Ruta al archivo .shp
shapefile_path <- "C:/Users/Admin/Downloads/barrios_cali/mc_barrios.shp"
barrios <- st_read(shapefile_path)
## Reading layer `mc_barrios' from data source
## `C:\Users\Admin\Downloads\barrios_cali\mc_barrios.shp' using driver `ESRI Shapefile'
## Simple feature collection with 337 features and 5 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 1054098 ymin: 860192.1 xmax: 1068492 ymax: 879000.7
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
vivienda_sf <- st_as_sf(vivienda_1, coords = c("longitud", "latitud"), crs = 4326)
vivienda_sf <- st_transform(vivienda_sf, st_crs(barrios))
Se crea un data.frame que contiene toda la información de las viviendas, los nombres de barrios originales y del join, la comuna, y las coordenadas longitud y latitud, listo para análisis o mapas sin mantener la geometría de sf.
vivienda_join <- st_join(vivienda_sf, barrios[, c("barrio", "comuna")])
vivienda_geo <- st_transform(vivienda_join, 4326)
vivienda_1 <- vivienda_geo %>%
mutate(
longitud = st_coordinates(.)[,1],
latitud = st_coordinates(.)[,2],
barrio_old = barrio.x,
barrio = barrio.y
) %>%
st_drop_geometry()
vivienda_1 <- vivienda_1[, -c(10, 11)]
Se consulta la url https://www.cali.gov.co/planeacion/publicaciones/115924/mapas-comunas-idesc/ para identificar que comunas se encuentran al norte, sur, oriente, occidente y centro, y se marca cada inmueble del data.frame en la columna barrio, comuna y zona_n.
vivienda_1 <- vivienda_1 %>%
mutate(
zona_n = case_when(
comuna %in% c("03", "08", "09", "10", "11", "12") ~ "CENTRO",
comuna %in% c("02", "04", "05", "06") ~ "NORTE",
comuna %in% c("07", "13", "14", "15", "21") ~ "ORIENTE",
comuna %in% c("01") ~ "OCCIDENTE",
comuna %in% c("16", "17", "18", "19", "20", "22") ~ "SUR",
TRUE ~ "OTRO" # por si alguna comuna no está en la lista
)
)
vivienda_1[] <- lapply(vivienda_1, function(x) {
if (is.character(x)) enc2utf8(x) else x
})
glimpse_tbl <- data.frame(
Variable = names(vivienda_1),
Tipo = sapply(vivienda_1, class),
Ejemplo = sapply(vivienda_1, function(x) paste0(head(x, 3), collapse = ", "))
)
glimpse_tbl %>%
gt() %>%
tab_header(title = "Estructura resumida de la base 'vivienda'")
| Estructura resumida de la base 'vivienda' | ||
| Variable | Tipo | Ejemplo |
|---|---|---|
| id | numeric | 1147, 1169, 1350 |
| zona | character | Zona Oriente, Zona Oriente, Zona Oriente |
| estrato | numeric | 3, 3, 3 |
| preciom | numeric | 250, 320, 350 |
| areaconst | numeric | 70, 120, 220 |
| parqueaderos | numeric | 1, 1, 2 |
| banios | numeric | 3, 2, 2 |
| habitaciones | numeric | 6, 3, 4 |
| tipo | character | Casa, Casa, Casa |
| comuna | character | 11, 11, 11 |
| longitud | numeric | -76.51168, -76.51237, -76.51537 |
| latitud | numeric | 3.43382, 3.43369, 3.43566 |
| barrio_old | character | 20 de julio, 20 de julio, 20 de julio |
| barrio | character | 20 de Julio, 20 de Julio, El Prado |
| zona_n | character | CENTRO, CENTRO, CENTRO |
library(DataExplorer)
## Warning: package 'DataExplorer' was built under R version 4.4.3
introduce(vivienda_1)
## rows columns discrete_columns continuous_columns all_missing_columns
## 1 8319 15 6 9 0
## total_missing_values complete_rows total_observations memory_usage
## 1 0 8319 124785 1054376
plot_intro(vivienda_1)
Aproximadamente el 40% de las columnas son discretas (estrato, barrio,
tipo), es decir, categorías o variables cualitativas.
El 60% restante son columnas continuas (preciom, areaconst, longitud, latitud), variables numéricas que pueden tomar cualquier valor dentro de un rango.
Ninguna columna está completamente vacía.
Todas las filas están completas, no hay filas totalmente vacías. Esto es muy bueno para modelado y análisis. Se considera como una data limpia.
cbind(table(vivienda_1$zona),prop.table(table(vivienda_1$zona))*100)
## [,1] [,2]
## Zona Centro 124 1.490564
## Zona Norte 1920 23.079697
## Zona Oeste 1198 14.400769
## Zona Oriente 351 4.219257
## Zona Sur 4726 56.809713
Se identifica que la mayor parte de los datos se concentran en Zona Sur, seguida por Zona Norte y Zona Oeste. Las zonas con menor representación son Oriente y Centro. Pero nos objeto de estudio porque no se haran comparaciones entre zonas.
base1 <- vivienda_1 %>%
filter(zona == "Zona Norte")
head(base1, 3)
## id zona estrato preciom areaconst parqueaderos banios habitaciones
## 1 1212 Zona Norte 5 260 90 1 2 3
## 2 1724 Zona Norte 5 240 87 1 3 3
## 3 2326 Zona Norte 4 220 52 2 2 3
## tipo comuna longitud latitud barrio_old barrio zona_n
## 1 Apartamento 04 -76.51350 3.45891 acopi Porvenir NORTE
## 2 Apartamento 17 -76.51700 3.36971 acopi Lili SUR
## 3 Apartamento 11 -76.51974 3.42627 acopi El Jard\xedn CENTRO
Estadisctca Unifica datos Zona Norte
tabla_zona <- base1 %>%
group_by(zona, tipo, estrato) %>%
summarise(n_registros = n()) %>%
arrange(desc(n_registros))
## `summarise()` has grouped output by 'zona', 'tipo'. You can override using the
## `.groups` argument.
tabla_zona
## # A tibble: 8 × 4
## # Groups: zona, tipo [2]
## zona tipo estrato n_registros
## <chr> <chr> <dbl> <int>
## 1 Zona Norte Apartamento 5 498
## 2 Zona Norte Apartamento 3 337
## 3 Zona Norte Casa 5 271
## 4 Zona Norte Apartamento 4 246
## 5 Zona Norte Casa 3 235
## 6 Zona Norte Casa 4 161
## 7 Zona Norte Apartamento 6 117
## 8 Zona Norte Casa 6 55
Con el fin de identificar visualmente los datos filtrados, se procede a ubicarlos en un mapa de Cali
base1[] <- lapply(base1, function(x) {
if (is.character(x)) {
iconv(x, from = "latin1", to = "UTF-8", sub = "")
} else {
x
}
})
# Crear el mapa
leaflet(base1) %>%
addProviderTiles("CartoDB.Positron") %>%
setView(lng = -76.532, lat = 3.4516, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud, lat = ~latitud,
popup = ~paste0(
"<b>Barrio:</b> ", barrio, "<br>",
"<b>Tipo:</b> ", tipo, "<br>",
"<b>Estrato:</b> ", estrato, "<br>",
"<b>Precio (millones):</b> ", preciom
),
radius = 6,
color = "red",
fillOpacity = 0.7
)
Se identifica que hay puntos por todos lados, apesar que se aplico e filtro en el campo original Zona, y se dejaron solo los que tenian Zona Norte, esta variacion se puede deber a mala clasificación en la fuente y se hace necesario hacer una reclasificacion partiendo del campo Zona_N que fue el reclasificado con el el archivo shp que contenia los barrios.
shapefile_path <- "C:/Users/Admin/Downloads/barrios_cali/mc_barrios.shp"
barrios <- st_read(shapefile_path)
## Reading layer `mc_barrios' from data source
## `C:\Users\Admin\Downloads\barrios_cali\mc_barrios.shp' using driver `ESRI Shapefile'
## Simple feature collection with 337 features and 5 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 1054098 ymin: 860192.1 xmax: 1068492 ymax: 879000.7
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
head(barrios)
## Simple feature collection with 6 features and 5 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 1060939 ymin: 876841.6 xmax: 1066056 ymax: 879000.7
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
## id_barrio barrio comuna shape_leng shape_area
## 1 0610 Ciudadela Floralia 06 4062.458 768879.6
## 2 0216 Menga 02 3209.059 510671.1
## 3 0603 Paso del Comercio 06 3573.425 395204.9
## 4 0608 Los Guaduales 06 2572.876 364831.8
## 5 0298 Senderos de La Flora 02 2543.263 383903.1
## 6 0295 Urbanizaci\xf3n La Flora 02 3508.308 764278.0
## geometry
## 1 POLYGON ((1065621 878388, 1...
## 2 POLYGON ((1061113 878524.7,...
## 3 POLYGON ((1065906 878375.7,...
## 4 POLYGON ((1064226 877369.6,...
## 5 POLYGON ((1062233 878014.3,...
## 6 POLYGON ((1063068 877720.7,...
plot(barrios["geometry"])
Crea data.frame nueva solo con barrios del norte, clasificando solo las comunas 2, 4, 5 y 6 ubicadas al norte del municpio de Cali.
puntos_sf <- st_as_sf(base1, coords = c("longitud", "latitud"), crs = 4326)
puntos_sf_trans <- st_transform(puntos_sf, st_crs(barrios))
puntos_sf_trans <- st_transform(puntos_sf, st_crs(barrios))
base1_con_barrios <- st_join(puntos_sf_trans, barrios)
base_comunas_sel <- base1_con_barrios %>%
filter(comuna.x %in% c("02", "04", "05", "06"))
head(base_comunas_sel)
## Simple feature collection with 6 features and 18 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 1062325 ymin: 874247.4 xmax: 1065290 ymax: 877376.8
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
## id zona estrato preciom areaconst parqueaderos banios habitaciones
## 1 1212 Zona Norte 5 260 90 1 2 3
## 2 1209 Zona Norte 5 320 150 2 4 6
## 3 1592 Zona Norte 5 780 380 2 3 3
## 4 509 Zona Norte 6 820 377 1 4 4
## 5 238 Zona Norte 5 430 105 0 3 3
## 6 504 Zona Norte 3 180 120 0 3 3
## tipo comuna.x barrio_old barrio.x zona_n id_barrio
## 1 Apartamento 04 acopi Porvenir NORTE 0403
## 2 Casa 02 acopi Urbanización La Merced NORTE 0293
## 3 Casa 02 acopi Urbanización La Flora NORTE 0295
## 4 Apartamento 05 acopi Los Parques Barranquilla NORTE 0594
## 5 Apartamento 05 acopi Villa del Prado - El Guabito NORTE 0599
## 6 Casa 05 acopi Los Andes NORTE 0502
## barrio.y comuna.y shape_leng shape_area
## 1 Porvenir 04 2216.520 292584.9
## 2 Urbanizaci\xf3n La Merced 02 2388.010 365166.2
## 3 Urbanizaci\xf3n La Flora 02 3508.308 764278.0
## 4 Los Parques Barranquilla 05 2527.581 292401.6
## 5 Villa del Prado - El Guabito 05 3913.389 786440.3
## 6 Los Andes 05 2587.242 358874.9
## geometry
## 1 POINT (1062685 874247.4)
## 2 POINT (1062695 876544.1)
## 3 POINT (1062325 877376.8)
## 4 POINT (1064429 876206.9)
## 5 POINT (1065290 875273.6)
## 6 POINT (1064443 875540.1)
……………………………..
barrios <- st_read("C:/Users/Admin/Downloads/barrios_cali/mc_barrios.shp")
## Reading layer `mc_barrios' from data source
## `C:\Users\Admin\Downloads\barrios_cali\mc_barrios.shp' using driver `ESRI Shapefile'
## Simple feature collection with 337 features and 5 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 1054098 ymin: 860192.1 xmax: 1068492 ymax: 879000.7
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
puntos_sf <- st_as_sf(base1, coords = c("longitud", "latitud"), crs = 4326)
puntos_sf <- st_transform(puntos_sf, st_crs(barrios))
base1_con_barrios <- st_join(puntos_sf, barrios)
base1_con_barrios$comuna.x <- as.character(base1_con_barrios$comuna.x)
base_comunas_sel <- base1_con_barrios %>%
filter(comuna.x %in% c("02", "04", "05", "06"))
nrow(base_comunas_sel) # Cantidad de puntos filtrados
## [1] 1488
head(base_comunas_sel) # Primeras filas
## Simple feature collection with 6 features and 18 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 1062325 ymin: 874247.4 xmax: 1065290 ymax: 877376.8
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
## id zona estrato preciom areaconst parqueaderos banios habitaciones
## 1 1212 Zona Norte 5 260 90 1 2 3
## 2 1209 Zona Norte 5 320 150 2 4 6
## 3 1592 Zona Norte 5 780 380 2 3 3
## 4 509 Zona Norte 6 820 377 1 4 4
## 5 238 Zona Norte 5 430 105 0 3 3
## 6 504 Zona Norte 3 180 120 0 3 3
## tipo comuna.x barrio_old barrio.x zona_n id_barrio
## 1 Apartamento 04 acopi Porvenir NORTE 0403
## 2 Casa 02 acopi Urbanización La Merced NORTE 0293
## 3 Casa 02 acopi Urbanización La Flora NORTE 0295
## 4 Apartamento 05 acopi Los Parques Barranquilla NORTE 0594
## 5 Apartamento 05 acopi Villa del Prado - El Guabito NORTE 0599
## 6 Casa 05 acopi Los Andes NORTE 0502
## barrio.y comuna.y shape_leng shape_area
## 1 Porvenir 04 2216.520 292584.9
## 2 Urbanizaci\xf3n La Merced 02 2388.010 365166.2
## 3 Urbanizaci\xf3n La Flora 02 3508.308 764278.0
## 4 Los Parques Barranquilla 05 2527.581 292401.6
## 5 Villa del Prado - El Guabito 05 3913.389 786440.3
## 6 Los Andes 05 2587.242 358874.9
## geometry
## 1 POINT (1062685 874247.4)
## 2 POINT (1062695 876544.1)
## 3 POINT (1062325 877376.8)
## 4 POINT (1064429 876206.9)
## 5 POINT (1065290 875273.6)
## 6 POINT (1064443 875540.1)
base_comunas_sel_df <- base_comunas_sel %>% st_set_geometry(NULL)
print(dim(base_comunas_sel))
## [1] 1488 19
Se crea un mapa nuevo para verificar si la corrección que se realizó por barrio y por comuna es correcto.
base_comunas_sel_wgs <- st_transform(base_comunas_sel, crs = 4326)
base_comunas_sel_wgs <- base_comunas_sel_wgs %>%
mutate(
barrio.y = iconv(barrio.y, from = "", to = "UTF-8", sub = ""),
tipo = iconv(tipo, from = "", to = "UTF-8", sub = "")
)
pal <- colorFactor(palette = "Set1", domain = base_comunas_sel_wgs$comuna.x)
leaflet(base_comunas_sel_wgs) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(
radius = 5,
color = ~pal(comuna.x),
fillOpacity = 0.8,
popup = ~paste0(
"ID: ", id, "<br>",
"Tipo: ", tipo, "<br>",
"Barrio: ", barrio.y, "<br>",
"Comuna: ", comuna.x
)
) %>%
addLegend(
"bottomright",
pal = pal,
values = ~comuna.x,
title = "Comuna",
opacity = 1
)
Listados de barrios del Norte de Cali que se encuentra en la base.
base_comunas_sel$barrio.y <- iconv(base_comunas_sel$barrio.y,
from = "latin1", to = "UTF-8")
conteo_barrios <- base_comunas_sel %>%
st_set_geometry(NULL) %>% # quitamos geometría para simplificar
group_by(barrio = barrio.y) %>%
summarise(n_registros = n()) %>%
arrange(desc(n_registros))
conteo_barrios
## # A tibble: 69 × 2
## barrio n_registros
## <chr> <int>
## 1 La Flora 127
## 2 Senderos de La Flora 125
## 3 Urbanización La Flora 110
## 4 Prados del Norte 92
## 5 Santa Mónica 76
## 6 Villa del Prado - El Guabito 68
## 7 Brisas de Los Alamos 66
## 8 San Vicente 65
## 9 Torres de Comfandi 60
## 10 Ciudad de Los Alamos 51
## # ℹ 59 more rows
datos_corr <- vivienda_1 %>%
select(preciom, areaconst, estrato, banios, habitaciones, zona)
datos_corr$zona_num <- as.numeric(factor(datos_corr$zona))
matriz_corr <- cor(datos_corr %>% select(preciom, areaconst, estrato, banios, habitaciones),
use = "complete.obs")
nombres_amigables <- c("Precio_Casa", "Area_Construida", "Estrato", "Banios", "Habitaciones")
colnames(matriz_corr) <- nombres_amigables
rownames(matriz_corr) <- nombres_amigables
print(matriz_corr)
## Precio_Casa Area_Construida Estrato Banios Habitaciones
## Precio_Casa 1.0000000 0.6873520 0.60980664 0.6691456 0.26409121
## Area_Construida 0.6873520 1.0000000 0.27432332 0.6484165 0.51691292
## Estrato 0.6098066 0.2743233 1.00000000 0.4203218 -0.07137615
## Banios 0.6691456 0.6484165 0.42032178 1.0000000 0.58990641
## Habitaciones 0.2640912 0.5169129 -0.07137615 0.5899064 1.00000000
corrplot(matriz_corr, method = "color", addCoef.col = "black", number.cex = 0.7)
Analisis de la data:
Precio_Casa: Se relaciona bastante con Area_Construida (0.69) y de manera moderada con Baños (0.67) y Estrato (0.61). Tiene poca relación con Habitaciones (0.26). El precio aumenta más según el tamaño y los baños que por el número de habitaciones.
Area_Construida: Se relaciona moderadamente con Baños (0.65) y Habitaciones (0.52). Relación baja con Estrato (0.27). Casas más grandes suelen tener más baños y habitaciones, pero no necesariamente un estrato más alto.
Estrato: Relación moderada con Precio_Casa (0.61) y Baños (0.42).Prácticamente no se relaciona con Habitaciones (-0.07). El estrato influye en el precio y los baños, pero no en las habitaciones.
Baños: Relación moderada con Habitaciones (0.59). Más baños suelen ir acompañados de más habitaciones.
Habitaciones: Se relaciona más con Baños (0.59) y Area_Construida (0.52).
Se identifican en el momento que las variables más importantes para explicar el Precio_Casa son Area_Construida, Baños y Estrato.
Tambien las habitaciones tiene menor correlación con el precio, aunque se relaciona con área y baños.
No hay correlaciones extremadamente altas (>0.9), (No hay problema de multicolinealidad).
library(dplyr)
vivienda_1 %>%
group_by(zona) %>%
summarise(precio_prom = mean(preciom, na.rm = TRUE))
## # A tibble: 5 × 2
## zona precio_prom
## <chr> <dbl>
## 1 Zona Centro 310.
## 2 Zona Norte 346.
## 3 Zona Oeste 678.
## 4 Zona Oriente 229.
## 5 Zona Sur 427.
La Zona Oeste tiene el precio promedio más alto (678), mientras que la Zona Oriente es la más económica (229).
Las demás zonas (Centro, Norte y Sur) tienen precios intermedios, siendo la Zona Sur más cara, como se esperaba.
library(dplyr)
library(plotly)
plot_ly(
data = vivienda_1,
x = ~zona,
y = ~preciom,
type = "box",
color = ~zona
) %>%
layout(
title = "Distribucion del Precio por Zona",
xaxis = list(title = "Zona"),
yaxis = list(title = "Precio (millones)")
)
La zona Norte tiene muchos outliers, teniendo en cuenta que la mediana es de 300 millones, se visualizan viviendas de mas de 1800 millones.
Casi lo mismo le pasa en la zona sur, pero la mediana esta cerca de los 430 millones siendo mas costoso que el norte.
La zona oriente concentra los precios más bajos, mientras el centro esta en una promedio entre todas.
#vivienda_casas_N <-subset(base1, tipo=='Casa')
vivienda_casas_N <- subset(base1, tipo == "Casa" & zona_n == "NORTE")
mod_p1 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data= vivienda_casas_N)
summary(mod_p1)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda_casas_N)
##
## Residuals:
## Min 1Q Median 3Q Max
## -924.18 -66.95 -16.60 35.06 1107.53
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -170.84010 35.64048 -4.793 2.14e-06 ***
## areaconst 0.77882 0.05318 14.645 < 2e-16 ***
## estrato 71.49706 8.78042 8.143 2.87e-15 ***
## habitaciones 5.93136 5.12237 1.158 0.24742
## parqueaderos 12.58900 4.77655 2.636 0.00865 **
## banios 14.28141 6.53460 2.186 0.02930 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 149.1 on 521 degrees of freedom
## Multiple R-squared: 0.6413, Adjusted R-squared: 0.6379
## F-statistic: 186.3 on 5 and 521 DF, p-value: < 2.2e-16
Intercepto es de -170.81010, p < 0.001 (significativo), indicaria que si todas las variables al iniciar fueran 0 (cero) el valor seria -170 millones, que no tendria sentido, pero su finalidad es indicar un ajuste.
areaconst es el Área Construida de 0.77882 con un p < 0.001 (muy significativo), se podria interpretar como la pendiente de la variable de area, es decir por cada metro de area que aumente la construccion aumentaria 0.778 millones de pesos el valor del inmueble. Tiene a t con 14.645 siendo el predcitro mas fuerte.
estrato, con una estimador de 71.50 y p < 0.001 (muy significativo), indicaría que al aumentar el estrato del inmueble aumentaría su valor en 71.5 millones.
habitaciones, con un coeficiente de 5.93, p = 0.247 (no significativo), indicaría que por cada habitación que aumente, debería aumentar 5.93 millones su valor. Sin embargo, por ser poco significativo, se podria decir que el valor real esta es en el área y no en la cantidad de habitaciones aunque lo uno implique lo otro.
parqueaderos, coeficiente de 12.59, p = 0.0086 (significativo), indicaría que cada parqueadero adicional aumentaría el valor en 12.6 millones el valor del inmueble.
Baños, coeficiente 14.28, p = 0.029, (significativo), aumentaria el valor del inmueble 14.28 millones por cada baño adicional.
R² = 0.6413: Indica que aproximadamente el 64.13% de la variabilidad del precio se explica con las variables incluidas: areaconst (Area Construida), estrato, habitaciones, parqueaderos, banios (Baños).
R² ajustado = 0.6379, la diferencia entre el y R² es pequeña indicando que el modelo no está sobre ajustado.
Siendo asi, se puede decir que aun hay un 36% de la variablidad del precio que el modelo no explica.
Se podría estudiar mejoras al modelo ingresando mas variables com por ejemplo antiguedad de la construccion, los terminados, vias de acceso, parques.
summary(mod_p1)$sigma
## [1] 149.0795
Las predicciones del modelo se equivocan alrededor de 149 millones de pesos respecto al valor real. Mostraria que el modelo no es muy eficiente, teniendo en cuenta que la mayoría de las casas tienen precios entre 100 y 300 millones
library(Metrics)
## Warning: package 'Metrics' was built under R version 4.4.3
rmse(vivienda_casas_N$preciom, mod_p1$fitted.values)
## [1] 148.2284
Las predicciones del modelo para las casas del Norte se desvían alrededor de 148 millones de pesos frente al precio real
graficos <- plot(mod_p1, which = 1:2)
La mayoría de los residuos están cerca de 0, entonces el modelo predice razonablemente bien para la mayoría de casas.
Hay pocos outliers con residuos grandes, que podrían influir mucho en los coeficientes.
Hay unos índices de la observación en los datos que tiene ese residuo específico alto, correspondientes a son posiblemente valores atípicas o outliers
La mayoría de los puntos siguen bastante bien la línea, entonces los residuales se comportan aproximadamente normales en el centro de la distribución.
Se ve que los residuales no cumplen perfectamente la normalidad, sobre todo en los extremos.
shapiro.test(mod_p1$residuals)
##
## Shapiro-Wilk normality test
##
## data: mod_p1$residuals
## W = 0.78594, p-value < 2.2e-16
Se confirma lo que ya se veía en el Q-Q plot, los residuales no son normales, sobre todo por colas pesadas y outliers, pero como el objetivo es predicción, no es necesario hacer mas ajustes (Transformaciones, elimnar valores atipicos, etc.).
bptest(mod_p1)
##
## studentized Breusch-Pagan test
##
## data: mod_p1
## BP = 108.46, df = 5, p-value < 2.2e-16
Indicaría que rechaza la hipótesis nula de homocedasticidad, es decir, los errores de tu modelo no tienen varianza constante, entonces existe heterocedasticidad.
La heterocedasticidad no sesga los coeficientes, afecta la precisión de los errores estándar, afectando solamente la inferencia.
Se podria trabajar una transformación logarítmica que estabilice la varianza.
Con los datos requeridos por el cliente se predice el precio de una vivienda al Norte con las siguientes caracteristicas: $ , Area =200 ,| ,parqueaderos=1,|,estrato = 4 ,o, 5,|, baños=2,|,habitaciones = 4 $.
## Prediccion
new_dat <- data.frame(
areaconst = 200,
parqueaderos = 1,
estrato = c(4, 5),
banios = 2,
habitaciones = 4
)
predict(mod_p1,new_dat, level = 0.95, interval = "confidence")
## fit lwr upr
## 1 335.7888 316.2518 355.3258
## 2 407.2858 378.6837 435.8880
Valor estimado (fit) = 335.8
Intervalo de confianza al 95%: entre 316.3 y 355.3
Es decir: el modelo estima un precio alrededor de 335.8, y con 95% de confianza estaría en ese rango.
Valor estimado (fit) = 407.3
Intervalo de confianza al 95%: entre 378.7 y 435.9
Estimación más alta que la primera, pero también con un rango de incertidumbre.
| Casas Valoradas según el Modelo | ||||||||||||
| Estratos 4 y 5, con predicción > 350 y precio ≤ 350 | ||||||||||||
| id | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | comuna | longitud | latitud | barrio_old | barrio | prediccion |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4458 | 4 | 315.00 | 270.0 | 2 | 4 | 4 | 02 | -76.53176 | 3.48780 | el bosque | El Bosque | 431.46 |
| 2544 | 4 | 340.00 | 264.5 | 2 | 4 | 4 | 02 | -76.52096 | 3.47665 | vipasa | Prados del Norte | 427.17 |
| 952 | 4 | 330.00 | 275.0 | 2 | 3 | 5 | 04 | -76.50647 | 3.47516 | la merced | Evaristo Garcia | 427.00 |
| 937 | 4 | 350.00 | 280.0 | 2 | 3 | 4 | 04 | -76.50603 | 3.46643 | la merced | Salomia | 424.96 |
| 1822 | 4 | 340.00 | 295.0 | 2 | 2 | 4 | 02 | -76.51777 | 3.48060 | vipasa | Vipasa | 422.37 |
| 3101 | 5 | 340.00 | 355.0 | 2 | 5 | 8 | 02 | -76.52377 | 3.46384 | san vicente | San Vicente | 607.16 |
| 4209 | 5 | 350.00 | 300.0 | 3 | 5 | 6 | 02 | -76.53010 | 3.48577 | el bosque | El Bosque | 565.05 |
| 1943 | 5 | 350.00 | 346.0 | 1 | 2 | 4 | 02 | -76.51847 | 3.47503 | vipasa | Prados del Norte | 520.99 |
| 3453 | 5 | 340.00 | 240.0 | 2 | 5 | 6 | 02 | -76.52640 | 3.48211 | la campiña | La Paz | 505.73 |
| 3043 | 5 | 330.00 | 275.0 | 2 | 3 | 5 | 02 | -76.52350 | 3.48329 | la merced | La Flora | 498.50 |
mapa <- st_read("C:/Users/Admin/Downloads/barrios_cali/mc_barrios.shp")
## Reading layer `mc_barrios' from data source
## `C:\Users\Admin\Downloads\barrios_cali\mc_barrios.shp' using driver `ESRI Shapefile'
## Simple feature collection with 337 features and 5 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 1054098 ymin: 860192.1 xmax: 1068492 ymax: 879000.7
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
propuesta1 <- rbind(estrato4[1:5, ], estrato5[1:5, ])
puntos_sf <- st_as_sf(
propuesta1,
coords = c("longitud", "latitud"), # 👈 pon aquí los nombres exactos
crs = 4326
)
mapa <- st_transform(mapa, 4326)
ggplot() +
geom_sf(data = mapa, fill = "white", color = "black", size = 0.2, alpha = 0.4) +
geom_sf(data = puntos_sf, color = "red", size = 3) +
ggtitle("Propuesta de casas en Zona norte")
library(tibble)
## Warning: package 'tibble' was built under R version 4.4.3
##
## Adjuntando el paquete: 'tibble'
## The following object is masked from 'package:summarytools':
##
## view
viviendas <- tibble::tibble(
Caracteristicas = c("Tipo", "Área construida", "Parqueaderos", "Baños",
"Habitaciones", "Estrato", "Zona", "Crédito preaprobado"),
# Vivienda_1 = c("Casa", "200", "1", "2", "4", "4 o 5", "Norte", "350 millones"),
Vivienda_2 = c("Apartamento", "300", "3", "3", "5", "5 o 6", "Sur", "850 millones")
)
print(viviendas)
## # A tibble: 8 × 2
## Caracteristicas Vivienda_2
## <chr> <chr>
## 1 Tipo Apartamento
## 2 Área construida 300
## 3 Parqueaderos 3
## 4 Baños 3
## 5 Habitaciones 5
## 6 Estrato 5 o 6
## 7 Zona Sur
## 8 Crédito preaprobado 850 millones
Se aplica FIltro ZOna Sur
base2 <- vivienda_1 %>%
filter(zona == "Zona Sur")
head(base2, 3)
## id zona estrato preciom areaconst parqueaderos banios habitaciones
## 1 5992 Zona Sur 4 400 280 3 5 3
## 2 5098 Zona Sur 4 290 96 1 2 3
## 3 698 Zona Sur 3 78 40 1 1 2
## tipo comuna longitud latitud barrio_old barrio zona_n
## 1 Casa 19 -76.54000 3.43500 3 de julio 3 de Julio SUR
## 2 Apartamento 03 -76.53464 3.44987 acopi La Merced CENTRO
## 3 Apartamento 15 -76.50100 3.40000 aguablanca El Morichal ORIENTE
tabla_zona <- base2 %>%
group_by(zona, tipo, estrato) %>%
summarise(n_registros = n()) %>%
arrange(desc(n_registros))
## `summarise()` has grouped output by 'zona', 'tipo'. You can override using the
## `.groups` argument.
tabla_zona
## # A tibble: 8 × 4
## # Groups: zona, tipo [2]
## zona tipo estrato n_registros
## <chr> <chr> <dbl> <int>
## 1 Zona Sur Apartamento 4 1091
## 2 Zona Sur Apartamento 5 1033
## 3 Zona Sur Casa 5 652
## 4 Zona Sur Casa 6 581
## 5 Zona Sur Casa 4 525
## 6 Zona Sur Apartamento 6 462
## 7 Zona Sur Apartamento 3 201
## 8 Zona Sur Casa 3 181
Mapeo de la Zona Sur
# Normalizar base
base_clean <- base2
base_clean[] <- lapply(base_clean, function(x) {
if (is.character(x)) {
# Forzar a UTF-8,
enc2utf8(iconv(x, from = "", to = "UTF-8", sub = ""))
} else {
x
}
})
# Crear el mapa
leaflet(base_clean) %>%
addProviderTiles("CartoDB.Positron") %>%
setView(lng = -76.532, lat = 3.4516, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud, lat = ~latitud,
popup = ~paste0(
"<b>Barrio:</b> ", barrio, "<br>",
"<b>Tipo:</b> ", tipo, "<br>",
"<b>Estrato:</b> ", estrato, "<br>",
"<b>Precio (millones):</b> ", preciom
),
radius = 6,
color = "green",
fillOpacity = 0.7
)
puntos_sf <- st_as_sf(base2, coords = c("longitud", "latitud"), crs = 4326)
puntos_sf_trans <- st_transform(puntos_sf, st_crs(barrios))
puntos_sf_trans <- st_transform(puntos_sf, st_crs(barrios))
base2_con_barrios <- st_join(puntos_sf_trans, barrios)
base_comunas_sel <- base2_con_barrios %>%
filter(comuna.x %in% c("16", "17", "18", "22" ))
head(base_comunas_sel)
## Simple feature collection with 6 features and 18 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 1058295 ymin: 864637.1 xmax: 1060407 ymax: 868286.1
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
## id zona estrato preciom areaconst parqueaderos banios habitaciones
## 1 7139 Zona Sur 3 240 75 0 3 5
## 2 6975 Zona Sur 4 220 75 1 2 3
## 3 7396 Zona Sur 3 115 58 1 2 2
## 4 6949 Zona Sur 4 220 84 0 2 3
## 5 7946 Zona Sur 3 230 63 1 2 2
## 6 4941 Zona Sur 5 500 320 2 8 9
## tipo comuna.x barrio_old barrio.x zona_n
## 1 Casa 18 alférez real Francisco Eladio Ram\xedrez SUR
## 2 Apartamento 18 alférez real Alf\xe9rez Real SUR
## 3 Apartamento 18 alférez real Alf\xe9rez Real SUR
## 4 Apartamento 18 alferez real Alf\xe9rez Real SUR
## 5 Apartamento 18 alto jordán Polvorines SUR
## 6 Casa 17 bella suiza alta Primero de Mayo SUR
## id_barrio barrio.y comuna.y shape_leng shape_area
## 1 1807 Francisco Eladio Ram\xedrez 18 1560.608 121173.3
## 2 1813 Alf\xe9rez Real 18 2612.684 225908.0
## 3 1813 Alf\xe9rez Real 18 2612.684 225908.0
## 4 1813 Alf\xe9rez Real 18 2612.684 225908.0
## 5 1891 Polvorines 18 4831.996 860023.6
## 6 1702 Primero de Mayo 17 2400.660 308867.3
## geometry
## 1 POINT (1058869 866452.8)
## 2 POINT (1059043 866748)
## 3 POINT (1058713 866761.3)
## 4 POINT (1059073 866627.5)
## 5 POINT (1058295 864637.1)
## 6 POINT (1060407 868286.1)
print(dim(base_comunas_sel))
## [1] 3259 19
Se crea un mapa nuevo para verificar si la corrección que se realizó por barrio y por comuna es correcto.
base_comunas_sel_wgs <- st_transform(base_comunas_sel, crs = 4326)
base_comunas_sel_wgs <- base_comunas_sel_wgs %>%
mutate(
barrio.y = iconv(barrio.y, from = "", to = "UTF-8", sub = ""),
tipo = iconv(tipo, from = "", to = "UTF-8", sub = "")
)
pal <- colorFactor(palette = "Set1", domain = base_comunas_sel_wgs$comuna.x)
leaflet(base_comunas_sel_wgs) %>%
addProviderTiles("CartoDB.Positron") %>%
addCircleMarkers(
radius = 5,
color = ~pal(comuna.x),
fillOpacity = 0.8,
popup = ~paste0(
"ID: ", id, "<br>",
"Tipo: ", tipo, "<br>",
"Barrio: ", barrio.y, "<br>",
"Comuna: ", comuna.x
)
) %>%
addLegend(
"bottomright",
pal = pal,
values = ~comuna.x,
title = "Comuna",
opacity = 1
)
vivienda_casas_S <- subset(base2, tipo == "Apartamento" & zona_n == "SUR")
mod_p2 <- lm(preciom ~ areaconst + parqueaderos + estrato + banios + habitaciones, data= vivienda_casas_S)
summary(mod_p2)
##
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + estrato + banios +
## habitaciones, data = vivienda_casas_S)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1140.93 -45.25 -2.62 36.71 943.17
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -226.3976 15.3773 -14.723 < 2e-16 ***
## areaconst 1.3310 0.0536 24.831 < 2e-16 ***
## parqueaderos 56.7177 3.5222 16.103 < 2e-16 ***
## estrato 57.2788 3.1609 18.121 < 2e-16 ***
## banios 50.6701 3.4345 14.753 < 2e-16 ***
## habitaciones -23.0842 3.8126 -6.055 1.64e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 97.61 on 2328 degrees of freedom
## Multiple R-squared: 0.7467, Adjusted R-squared: 0.7462
## F-statistic: 1373 on 5 and 2328 DF, p-value: < 2.2e-16
Intercepto es de -226.40, p < 0.001 (significativo), indicaria que si todas las variables al iniciar fueran 0 (cero) el valor seria -226.4 millones, que no tendria sentido, pero su finalidad es indicar un ajuste.
areaconst es el Área Construida de 1.33 con un p < 0.001 (muy significativo), se podria interpretar como la pendiente de la variable de area, es decir por cada metro de area que aumente la construcción aumentaría 1.33 millones de pesos el valor del inmueble. Tiene a t con 24.831 siendo el coeficiente mas fuerte.
estrato, con una estimador de 57.28 y p < 0.001 (muy significativo), indicaría que al aumentar el estrato del inmueble aumentaría su valor en 56.28 millones.
habitaciones, con un coeficiente de -23.08, p = 0.001 (significativo), indicaría que por cada habitación que disminuye, debería bajar 23.08 millones su valor. Sin embargo, se podría decir que el valor real baja si mantiene la misma area y hacer mas habitacines.
parqueaderos, coeficiente de 56.79, p = 0.001 (significativo), indicaría que cada parqueadero adicional aumentaría el valor en 56.79 millones el valor del inmueble.
Baños, coeficiente 50.67, p = 0.001, (significativo), aumentaria el valor del inmueble 50.67 millones por cada baño adicional.
R² = 0.747: Indica que aproximadamente el 74.7% de la variabilidad del precio se explica con las variables incluidas: areaconst (Area Construida), estrato, habitaciones, parqueaderos, banios (Baños).
R² ajustado = 0.7462, la diferencia entre el y R² es pequeña indicando que el modelo no está sobre ajustado.
Siendo asi, se puede decir que aun hay un 26% de la variablidad del precio que el modelo no explica.
Se podría estudiar mejoras al modelo ingresando mas variables com por ejemplo antiguedad de la construccion, los terminados, vias de acceso, parques.
summary(mod_p2)$sigma
## [1] 97.60691
Las predicciones del modelo se equivocan alrededor de 97.6 millones de pesos respecto al valor real. Mostraria que el modelo no es muy eficiente, teniendo en cuenta que la mayoria de las casas tienen precios entre 100 y 300 millones
library(Metrics)
rmse(vivienda_casas_N$preciom, mod_p2$fitted.values)
## Warning in actual - predicted: longitud de objeto mayor no es múltiplo de la
## longitud de uno menor
## [1] 318.5021
Las predicciones del modelo para las casas del Norte se desvían alrededor de 318 millones de pesos frente al precio real
graficos <- plot(mod_p2, which = 1:2)
Se ve que para valores ajustados pequeños (izquierda) los residuos están bien distribuidos, pero a medida que el valor ajustado aumenta, aparece cierta curvatura y dispersión creciente. Esto sugiere heterocedasticidad (la varianza de los errores no es constante).
La leve curvatura ascendente al final, lo que indica que el modelo podría no estar captando toda la relación lineal en los precios más altos.
Hay pocos outliers con residuos grandes, que podrían influir mucho en los coeficientes.
Hay unos índices de la observación en los datos que tiene ese residuo específico alto, correspondientes a son posiblemente valores atípicas o outliers
En el centro (valores intermedios) los puntos siguen bastante bien la línea, lo que es positivo.
Las colas (extremos izquierdo y derecho), los puntos se alejan mucho de la recta, esto indica que los residuos tienen una distribución con colas más pesadas que la normal (probablemente curtosis alta).
shapiro.test(mod_p2$residuals)
##
## Shapiro-Wilk normality test
##
## data: mod_p2$residuals
## W = 0.78755, p-value < 2.2e-16
La hipótesis nula del test es que los residuos siguen una distribución normal.
Como el p-valor es extremadamente bajo (< 0.05), rechazamos la normalidad → los residuos no son normales.
Esto confirma lo del gráfico Q-Q: los residuos se desvían de la línea recta en las colas, entonces hay colas pesadas y outliers.
Se debería hacer Transformacion de la variable dependiente
bptest(mod_p2)
##
## studentized Breusch-Pagan test
##
## data: mod_p2
## BP = 796.04, df = 5, p-value < 2.2e-16
La hipótesis nula es que los residuos tienen varianza constante (homocedasticidad).
Como el p-valor es muy bajo, rechazamos H₀ → hay heterocedasticidad en tu modelo.
Se podria mejorar haciendo una transformación de la variable dependiente, usualmente se hace con unlogaritmo.
Con los datos requeridos por el cliente se predice el precio de una vivienda (apartamento) al Sur con las siguientes caracteristicas: $ , Area =300 ,| ,parqueaderos= 3,|,estrato = 5 ,o, 6,|, baños=3,|,habitaciones = 5 $.
## Prediccion 2
new_dat <- data.frame(
areaconst = 300,
parqueaderos = 3,
estrato = c(5, 6),
banios = 3,
habitaciones = 5
)
predict(mod_p2,new_dat, level = 0.95, interval = "confidence")
## fit lwr upr
## 1 666.0273 643.6098 688.4447
## 2 723.3061 700.6062 746.0059
Valor estimado (fit) = 666.02
Intervalo de confianza al 95%: entre 643.6 y 688.4
Es decir: el modelo estima un precio alrededor de 666, y con 95% de confianza estaría en ese rango.
Valor estimado (fit) = 723.3
Intervalo de confianza al 95%: entre 700.6 y 746.0
El intervalo es más informativo que el valor puntual, porque refleja la incertidumbre en la estimación.
Intervalos relativamente estrechos (como estos) sugieren que el modelo tiene buena precisión para esas predicciones.
vivienda_casas_S$prediccion <- mod_p2$fitted.values
estrato5a <- vivienda_casas_S %>%
filter(preciom <= 850, prediccion > 850, estrato == 5, parqueaderos > 0) %>%
select(-zona, -zona_n, -tipo) %>%
arrange(desc(prediccion))
estrato6 <- vivienda_casas_S %>%
filter(preciom <= 850, prediccion > 850, estrato == 6, parqueaderos > 0) %>%
select(-zona, -zona_n, -tipo) %>%
arrange(desc(prediccion))
top_estrato5a <- head(estrato5a, 5)
top_estrato6 <- head(estrato6, 5)
tabla_final <- rbind(top_estrato5a, top_estrato6)
tabla_final %>%
gt() %>%
tab_header(
title = "Casas Valoradas según el Modelo Sur",
subtitle = "Estratos 5 y 6, con predicción > 850 y precio ≤ 850"
) %>%
fmt_number(
columns = c(preciom, prediccion),
decimals = 2
) %>%
tab_style(
style = cell_fill(color = "lightblue", alpha = 0.3),
locations = cells_body(columns = prediccion)
)
| Casas Valoradas según el Modelo Sur | ||||||||||||
| Estratos 5 y 6, con predicción > 850 y precio ≤ 850 | ||||||||||||
| id | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | comuna | longitud | latitud | barrio_old | barrio | prediccion |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 6121 | 5 | 299.00 | 932 | 1 | 3 | 3 | 17 | -76.54087 | 3.37348 | valle del lili | Unicentro Cali | 1,439.93 |
| 7182 | 5 | 730.00 | 573 | 3 | 8 | 5 | 19 | -76.54800 | 3.40800 | guadalupe | Cuarto de Legua - Guadalupe | 1,282.73 |
| 4952 | 5 | 650.00 | 600 | 2 | 4 | 5 | 17 | -76.53400 | 3.38100 | el ingenio | El Ingenio | 1,059.27 |
| 6472 | 5 | 170.00 | 605 | 1 | 2 | 2 | 17 | -76.54294 | 3.39992 | el limonar | El Gran Limonar | 977.12 |
| 4394 | 5 | 690.00 | 486 | 2 | 4 | 4 | 17 | -76.53111 | 3.38292 | el ingenio | El Ingenio | 930.62 |
| 5574 | 6 | 850.00 | 352 | 4 | 3 | 3 | 22 | -76.53729 | 3.34265 | pance | Parcelaciones Pance | 895.40 |
mapa <- st_read("C:/Users/Admin/Downloads/barrios_cali/mc_barrios.shp")
## Reading layer `mc_barrios' from data source
## `C:\Users\Admin\Downloads\barrios_cali\mc_barrios.shp' using driver `ESRI Shapefile'
## Simple feature collection with 337 features and 5 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 1054098 ymin: 860192.1 xmax: 1068492 ymax: 879000.7
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
propuesta2 <- rbind(estrato5a[1:5, ], estrato6[1:5, ])
propuesta2 <- propuesta2 %>%
filter(!is.na(longitud), !is.na(latitud))
puntos_sf <- st_as_sf(
propuesta2,
coords = c("longitud", "latitud"),
crs = 4326
)
mapa <- st_transform(mapa, 4326)
ggplot() +
geom_sf(data = mapa, fill = "white", color = "black", size = 0.2, alpha = 0.4) +
geom_sf(data = puntos_sf, color = "red", size = 3) +
ggtitle("Propuesta de casas en Zona Sur")