1. Introducción.

María comenzó como agente de bienes raíces en Cali hace 10 años. Después de laborar dos años para una empresa nacional, se traslado a Bogotá y trabajó para otra agencia de bienes raíces. Sus amigos y familiares la convencieron de que con su experiencia y conocimientos del negocio debía abrir su propia agencia. Terminó por adquirir la licencia de intermediario y al poco tiempo fundó su propia compañía, C&A (Casas y Apartamentos) en Cali. Santiago y Lina, dos vendedores de la empresa anterior aceptaron trabajar en la nueva compaña. En la actualidad ocho agentes de bienes raíces colaboran con ella en C&A.

2. Resumen.

Este informe tiene como objetivo presentar una selección de opciones de vivienda que cumplan con los criterios específicos establecidos por el cliente, una compañía internacional que busca opciones residenciales adecuadas para sus empleados. Utilizando un enfoque detallado y comparativo, se han evaluado diversas propiedades en las zonas solicitadas para garantizar que cumplan con las expectativas culturales, de confort, y estilo de vida de los empleados de la compañía.

Para la elaboración de este informe, se emplearon métodos de análisis comparativo que incluyen la revisión de características de las propiedades, la comparación con las especificaciones requeridas y el análisis de las estadísticas descriptivas de las zonas evaluadas. Las recomendaciones se basan en la disponibilidad actual de viviendas que más se alinean con los requisitos establecidos por el cliente.

Las principales recomendaciones incluyen opciones de viviendas que, aunque no cumplen exactamente con todos los criterios, ofrecen características que se aproximan significativamente a las necesidades del cliente. Además, se exploran posibles ajustes o compromisos que el cliente podría considerar para maximizar la adecuación de las propiedades seleccionadas.

2. Zona Norte.

A continuación, se encuentra un análisis detallado de las mejores opciones de viviendas en la Zona Norte de la ciudad, basado en un análisis estadístico de las características y precios de las propiedades disponibles. Este análisis busca asesorarlo, una compañía internacional, en la selección de dos viviendas para sus empleados, considerando requisitos específicos y un presupuesto máximo de $350 millones.

2.1. Análisis.

La zona Norte se caracteriza por ser una zona residencial consolidada con un conjunto de viviendas que varían en tamaño, precio, y demás características. Las propiedades en esta área son predominantemente de estrato 3 a 5, ubicadas mayormente en las comunas 2, 4, 5, y 6. Estas comunas ofrecen una combinación de accesibilidad a servicios, tranquilidad y seguridad, lo que las hace atractivas para familias.

2.2. Catálogo de viviendas.

Para este análisis, se utilizó una base de datos de viviendas filtradas por tipo (Casa) y localización (Zona Norte). Se ajustaron variables relevantes como área construida, número de baños, habitaciones, estrato, y disponibilidad de parqueaderos para asegurar que las propiedades cumplan con los requisitos solicitados.

2.3. Ofertas potenciales de vivienda.

A partir de las características solicitadas para la primera vivienda (área construida de 200 \(m^2\), 1 parqueadero, 2 baños, 4 habitaciones, estrato 4 o 5, y un precio máximo de $350 millones), no se encontraron propiedades que cumplieran exactamente con estos criterios. Sin embargo, al ajustar los parámetros para considerar viviendas con características superiores o equivalentes, se identificaron dos opciones destacadas:

  1. Vivienda ID 852: Precio de $340 millones, área de 208 \(m^2\), 6 baños, 4 habitaciones, ubicada en el barrio “El Bosque”, estrato 5, en el piso 3.

  2. Vivienda ID 4727: Precio de $296 millones, área de 232 \(m^2\), 6 baños, 4 habitaciones, ubicada en el barrio “Granada”, estrato 4, en el piso 2.

2.4. Estadísticas descriptivas de la Zona Norte.

Se realizó un análisis descriptivo de las viviendas en la Zona Norte con un precio de hasta $350 millones para entender mejor el mercado y comparar las opciones disponibles. Los resultados mostraron que las viviendas en esta zona tienen una mediana de área construida de 131 \(m^2\), con una media de 2.74 baños, 4 habitaciones y un máximo de 1 parqueadero. Las propiedades ofertadas con mejores características que las demás están a un precio accesible.

Resumen de estadísticas variables cuantitativas
Estadísticas descriptivas
Minimo Mediana Media Maximo CV
preciom 100 237.5 238.65 350 0.32
areaconst 30 131.0 146.68 450 0.47
banios 0 3.0 2.74 6 0.37
habitaciones 0 4.0 4.03 9 0.35
parqueaderos_imp 0 0.0 0.48 1 1.04

2.5. Visualización de las mejores ofertas.

Se generó un mapa interactivo que visualiza las ubicaciones de las mejores ofertas de viviendas en la Zona Norte, destacando las propiedades seleccionadas para facilitar la toma de decisiones.

2.6. Conclusiones y recomendaciones.

Con base en el análisis realizado, recomendamos las viviendas con ID 852 y 4727 como las mejores opciones para su consideración. Ambas ofrecen características superiores y se encuentran dentro del presupuesto especificado. La vivienda con ID 4727, en particular, presenta una excelente relación calidad-precio y se encuentra en una zona estratégica de la ciudad.

Es importante considerar tanto el estrato como la ubicación dentro de las comunas seleccionadas para maximizar la satisfacción de los empleados que residirán en estas viviendas.

3. Zona Sur.

Ahora, se encuentra un análisis detallado de las mejores opciones de viviendas en la Zona Sur de la ciudad, basado en un análisis estadístico de las características y precios de las propiedades disponibles. Este análisis busca asesorarlo, una compañía internacional, en la selección de dos viviendas para sus empleados, considerando requisitos específicos y un presupuesto máximo de $850 millones.

3.1. Análisis.

El análisis inicial se enfocó en apartamentos con un área construida de 300 m², con 3 parqueaderos, 3 baños, 5 habitaciones y en estratos 5 o 6. Después de aplicar estos filtros a nuestra base de datos, encontramos que no hay viviendas que cumplan exactamente con todos los criterios requeridos. Sin embargo, esto nos ha permitido explorar otras opciones que podrían ser igualmente atractivas y ajustadas al presupuesto preaprobado de $850 millones de pesos.

3.2. Catálogo de viviendas

Para este análisis, se utilizó una base de datos de viviendas filtradas por tipo (Apartamento) y localización (Zona Sur). Se ajustaron variables relevantes como área construida, número de baños, habitaciones, estrato, y disponibilidad de parqueaderos para asegurar que las propiedades cumplan con los requisitos solicitados.

3.3. Ofertas potenciales de vivienda.

Opción 1: Dado que no se encontraron apartamentos que cumplan con todos los parámetros específicos inicialmente solicitados, se ampliaron los criterios de búsqueda. Se filtraron apartamentos en la Zona Sur de estratos 5 o 6, con más de 300 \(m^2\) de área construida, más de 3 parqueaderos, más de 3 baños, y que no superen los $850 millones. Lamentablemente, tampoco se encontraron viviendas que cumplieran con estos requisitos ampliados.

Opción 2: El siguiente paso fue buscar apartamentos en estratos 5 o 6 que tengan hasta 300 \(m^2\) de área construida, hasta 3 parqueaderos, hasta 3 baños, y hasta 5 habitaciones, asegurándonos de que el precio no excediera los $850 millones. Este enfoque permitió identificar algunas propiedades interesantes que podrían ser consideradas excelentes oportunidades de inversión. Las mejores opciones que se encontraron son:

  1. Apartamento ID 6723: Estrato 6, con un precio de 840 millones de pesos, un área construida de 185 \(m^2\), 2 habitaciones y 2 baños, ubicado en el barrio Pance.

  2. Apartamento ID 3603: Estrato 6, con un precio de 833 millones de pesos, un área construida de 213 \(m^2\), 3 habitaciones y 3 baños, ubicado en Ciudad Jardín Pance.

  3. Apartamento ID 3827: Estrato 6, con un precio de 820 millones de pesos, un área construida de 213 \(m^2\), 3 habitaciones y 3 baños, también en Pance.

  4. Apartamento ID 5693: Estrato 6, con un precio de 780 millones de pesos, un área construida de 168 \(m^2\), 3 habitaciones y 3 baños, en Ciudad Jardín.

  5. Apartamento ID 3848: Estrato 6, con un precio de 760 millones de pesos, un área construida de 200 \(m^2\), 3 habitaciones y 3 baños, ubicado en Ciudad Jardín.

Aunque las propiedades encontradas no cuentan con todos los parqueaderos requeridos, se considerada que estos apartamentos pueden estar situados en complejos residenciales con parqueaderos comunitarios disponibles, ofreciendo así una flexibilidad adicional para los residentes. Estos apartamentos cumplen con la mayoría de las características solicitadas y presentan una excelente relación calidad-precio, estando todos por debajo del presupuesto preaprobado de $850 millones de pesos.

3.4. Estadísticas descriptivas de la Zona Sur.

Para proporcionar una visión más completa del mercado inmobiliario en la Zona Sur, analizamos las estadísticas descriptivas de los apartamentos en esta área con un precio máximo de 850 millones de pesos.

En términos de estrato, la mayoría de los apartamentos disponibles en la Zona Sur pertenecen al estrato 5, lo que indica una zona con un buen nivel de calidad de vida. La mayoría de las propiedades también se encuentran en la Comuna 17, que es una de las áreas más populares y bien valoradas de la Zona Sur.

3.5. Visualización de las mejores ofertas.

Para facilitar la decisión, se ha preparado un mapa interactivo que muestra la ubicación de las mejores ofertas de apartamentos en la Zona Sur. Este mapa destaca tanto la variedad de opciones como la accesibilidad de cada una en relación con las principales vías y servicios de la ciudad.

3.6. Conclusiones y recomendaciones.

Con base en el análisis realizado, se recomienda considerar las opciones de apartamentos en estrato 6 en el barrio Ciudad Jardín y Pance. Estas propiedades no solo cumplen con la mayoría de los criterios solicitados, sino que también se encuentran en áreas muy deseadas de la Zona Sur. Ofrecen un buen equilibrio entre costo y calidad, con precios que se ajustan cómodamente al presupuesto disponible.

4. Contacto.

Invitamos a nuestros clientes a programar una visita para conocer estas propiedades personalmente y explorar más a fondo las ventajas que cada una ofrece. Estamos seguros de que encontrarán una vivienda que no solo cumpla con sus necesidades sino que también les brinde una excelente oportunidad de inversión a largo plazo.

——————————————————————————-

Anexos.

0. General.

0.1. Base de datos.

Se tiene la base de datos inicial con información de las casas y apartamentos en Cali.

# Base de datos

library(paqueteMODELOS)
data("vivienda")
head(vivienda)
cat("La cantidad de viviendas de la base de datos inicial es de", nrow(vivienda), "\n")
## La cantidad de viviendas de la base de datos inicial es de 8322

Siguiendo lo anterior, la base de datos está conformada por las variables id, zona, piso, estrato, precio de la vivienda, area construida, parqueaderos, cantidad de parqueaderos, cantidad de baños, cantidad de habitaciones, tipo de la vivienda, barrio en el que se encuentra y coordenadas de georreferenciación de longitud y latitud. De igual manera, se puede notar la ausencia de datos en la variable de piso.

0.2. Filtro de la base de datos.

Se realiza un filtro a la base de datos con tipo de vivienda de casa y zona norte de la ciudad. Se muestran los tres primeros registros para conocer el comportamiento de las variables.

# Filtrar base de datos

library(dplyr)
base1 <- vivienda %>% filter(tipo == "Casa", zona == "Zona Norte")
head(base1, 3)

Puede observarse entonces que hay presencia de datos faltantes en la variable de parqueaderos. Por tanto, dado que anteriormente sólo se expuso un preliminar de tres viviendas, es necesario revisar cada una de las variables para conocer su cantidad de datos faltantes.

# Gráfico de datos faltantes

library(naniar)
vis_miss(base1)

La visualización de los datos faltantes permitió observarque aquellas variables que los tienen son piso y parqueaderos con un porcentaje por encima del 40% en donde eliminar esta cantidad de registros no es opción para dar solución. Por lo que se hace necesario realizar una imputación a estos datos.

Ahora, se necesita conocer el comportamiento de cada una de las variables, por lo que se realiza un resumen de frecuencias absolutas para las variables categóricas.

# Estadísticas descriptivas variables categóricas

base1 %>% group_by(zona) %>% count(zona)
base1 %>% group_by(piso) %>% count(piso)
base1 %>% group_by(estrato) %>% count(estrato)
base1 %>% group_by(tipo) %>% count(tipo)

Las tablas descriptivas exponen que la base de datos realizó el filtro correctamente en la zona Norte y que también lo hizo con las viviendas tipo Casa, pues todas se encuentran allí.Con respecto a las demás variables categóricas, el piso de las casas llega desde el primero hasta el séptimo, por lo que se hace conveniente conocer la definición de este tipo de vivienda. Por último, la distribución del estrato va de 3 a 6.

En cuanto a las variables cuantitativas, se realizan medidas de tendencia central para conocer su comportamiento.

# Estadísticas descriptivas variables cuantitativas

min_varcuant <- apply(base1[, 5:9], 2, min, na.rm = TRUE)
max_varcuant <- apply(base1[, 5:9], 2, max, na.rm = TRUE)
median_varcuant <- apply(base1[, 5:9], 2, median, na.rm = TRUE)
media_varcuant <- apply(base1[, 5:9], 2, mean, na.rm = TRUE)
cv_varcuant <- apply(base1[, 5:9], 2, function(x) sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE))

tab_varcuant <- data.frame(
  "Minimo" = round(min_varcuant, 2),
  "Mediana" = round(median_varcuant, 2),
  "Media" = round(media_varcuant, 2),
  "Maximo" = round(max_varcuant, 2),
  "CV" = round(cv_varcuant, 2)
)


library(knitr)
library(kableExtra)
t <- kable(tab_varcuant, format = "html", align = "c",
           caption = "Resumen de estadísticas variables cuantitativas") %>%
  kable_styling(full_width = FALSE) %>%
  add_header_above(c(" " = 1, "Estadísticas descriptivas" = 5))

t
Resumen de estadísticas variables cuantitativas
Estadísticas descriptivas
Minimo Mediana Media Maximo CV
preciom 89 390 445.91 1940 0.60
areaconst 30 240 264.85 1440 0.63
parqueaderos 1 2 2.18 10 0.64
banios 0 3 3.56 10 0.43
habitaciones 0 4 4.51 10 0.41

Por tanto, en las variables cuantitativas se observan casas con precios bajos y muy altos, al iguak que en su tamaño, donde hay áreas de tan solo \(30m^2\) hasta \(1440m^2\). Se observa además, casas con 1 parqueadero mínimo hasta 10 y viviendas con 0 baños y 0 habitaciones, lo cual podría ser incongruente.

Luego, la longitud y latitud se grafican para conocer la distribución de estas casas en la zona Norte.

library(ggplot2)
ggplot(base1, aes(longitud, latitud, colour=factor(zona))) + 
  geom_point() +
  labs(title="Distribución de los barrios en Cali por zona") +
  scale_colour_discrete(name  ="Zona") +
  theme_minimal()

A pesar que la base1 sólamente contiene casas ubicadas en la zona Norte de Cali, las ubicaciones de ellas están indicando que hay este tipo de vivienda distribuidas por toda la ciudad y no sólamente en la zona objetivo que se tenía.

Finalmente, con el análisis descriptivo expuesto, se es necesario realizar una limpieza de la base de datos original para realiza el cambio de la zona según su ubicación, la imputación de las variables piso y parqueaderos y definir el tipo de vivienda Casa para realizar correcciones pertinentes.

0.3. Limpieza de los datos.

Dadas las incongruencias en la base de datos filtrada base1, se realizará una limpieza de la base de datos original (vivienda) para después cuando ésta esté corregida, realizar de nuevo el filtro para dar respuesta a cada una de las preguntas del cliente.

0.3.1. Contexto y piso.

En el contexto del análisis de viviendas en la ciudad de Cali, es fundamental entender las definiciones de vivienda que permitan realizar una correcta limpieza y análisis de los tipos de propiedades; Apartamento y Casa.

Con el objetivo de obtener una comprensión sólida de estas definiciones, se llevó a cabo una una búsqueda de definiciones en la página oficial del Departamento Administrativo Nacional de Estadística (DANE)(https://www.dane.gov.co/index.php?option=com_content&view=article&id=168&itemid=117), las cuales se describen a continuación:

  1. Vivienda: Es un espacio independiente y separado, habitado o destinado para ser habitado por una o más personas. Independiente, porque tiene acceso directo desde la vía pública, caminos, senderos o a través de espacios de circulación común (corredores o pasillos, escaleras, ascensores, patios).

  2. Casa: Es la edificación constituida por una sola unidad cuyo uso es el de vivienda, con acceso directo desde la vía pública o desde el exterior de la edificación. El servicio sanitario y la cocina pueden estar o no dentro de ella. También se consideran casas aquellas en donde el garaje, la sala o alguna habitación se destinan para uso económico.

  3. Apartamento: Es una unidad de vivienda que hace parte de una edificación, en la cual hay otra(s) unidad(es) que generalmente es (son) de vivienda. Tiene acceso directo desde el exterior o por pasillos, patios, corredores, escaleras o ascensores. Dispone de servicio sanitario y cocina en su interior. Por ejemplo, los bloques multifamiliares generalmente están constituidos por apartamentos; una casa que se reforma para construir varias unidades de vivienda con sanitario y cocina para cada nueva unidad, se convierte en varios apartamentos.

Por las definiciones anteriores y de acuerdo al análisis descriptivo previo, se encontraron casas con más de 3 pisos, por lo que se corregirá esta variable poniendo de condición que si la vivienda es de tipo Casa y la cantidad de pisos es mayor que 3, entonces se clasifique como Apartamento, siguiendo así las definiciones del DANE.

# Casas con pisos > 3, se convierten en apartamentos

vivienda$tipo_modif <- vivienda$tipo

vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "04")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "05")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "06")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "07")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "08")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "09")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "10")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "11")] <- "Apartamento" 
vivienda$tipo_modif[which(vivienda$tipo == "Casa" & vivienda$piso == "12")] <- "Apartamento" 

table(vivienda$piso, vivienda$tipo_modif)
##     
##      Apartamento Casa
##   01         430  430
##   02         512  938
##   03         573  524
##   04         607    0
##   05         567    0
##   06         245    0
##   07         204    0
##   08         211    0
##   09         146    0
##   10         130    0
##   11          84    0
##   12          83    0

0.3.2. Corrección de ubicaciones geográficas.

Se decide corregir la variable de zona debido a que, al pertenecer las viviendas en una zona que no corresponden, puede dar un análisis no cercano a lo que es en realidad, tales como precios, áreas construidas o barrios. Por tanto, se hará análisis georreferenciado con manipulación de archivos shapefile del mapa de Cali.

Por lo anterior, se buscó en la página de la Alcaldía de Cali cómo se distribuía las zonas geográficas en la ciudad de Cali (https://www.cali.gov.co/planeacion/publicaciones/169423/zonas_geograficas_idesc/). Luego, se descargó el archivo shapefile del mapa de las comunas de Cali y tomando como base el mapa de las zonas geográficas, se agruparon las comunas que pertenecían a cada una de ellas. Finalmente se grafica para corroborar si efectivamente las viviendas no coinciden con las zonas geográficas.

# Corrección de la zona

#---------------------------------------------------------------------------------------------

# Generación en formato de coordenadas de la longitud y latitud

library(readxl)
coordenadas <- read_excel("C:/Users/Usuario/Documents/Universidad Javeriana/SEMESTRE 2/MODELOS ESTADISTICOS PARA LA TOMA DE DESICIONES/S2_MODELOS/coordenadas.xlsx")

library(sp)
coordinates(coordenadas) <- c("longitud", "latitud")
proj4string(coordenadas) <- CRS("+proj=longlat +datum=WGS84")  #se define la proyección

library(sf)
sf_objeto <- st_as_sf(coordenadas)

#st_write(sf_objeto, "C:/Users/Usuario/Documents/Universidad Javeriana/SEMESTRE 2/MODELOS ESTADISTICOS PARA LA TOMA DE DESICIONES/S2_MODELOS/coordenadas_shape.xlsx")

#---------------------------------------------------------------------------------------------

# Creación de una nueva columna 'zona' según las comunas de la ciudad

mapa_cali <- st_read("C:/Users/Usuario/Documents/Universidad Javeriana/SEMESTRE 1/METODOS Y SIMULACION ESTADISTICA/UNIDAD 1/Comunas/bcs_lim_comunas.shp")
## Reading layer `bcs_lim_comunas' from data source 
##   `C:\Users\Usuario\Documents\Universidad Javeriana\SEMESTRE 1\METODOS Y SIMULACION ESTADISTICA\UNIDAD 1\Comunas\bcs_lim_comunas.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 22 features and 6 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 1054098 ymin: 860192.1 xmax: 1068492 ymax: 879441.5
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
mapa_cali$zona_alcaldia <- c() 

mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 2", "Comuna 4", 
                                                "Comuna 5", "Comuna 6")] <- "Zona Norte"

mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 7", "Comuna 13", 
                                                "Comuna 14","Comuna 15", 
                                                "Comuna 16","Comuna 21")] <- "Zona Oriente"

mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 22", "Comuna 17")] <- "Zona Sur"

mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 18", "Comuna 19", 
                                                "Comuna 20", "Comuna 1")] <- "Zona Oeste"

mapa_cali$zona_alcaldia[mapa_cali$NOMBRE %in% c("Comuna 3", "Comuna 9", 
                                                "Comuna 10", "Comuna 11", 
                                                "Comuna 12", "Comuna 8")] <- "Zona Centro"

#st_write(mapa_cali, "C:/Users/Usuario/Documents/Universidad Javeriana/SEMESTRE 2/MODELOS ESTADISTICOS PARA LA TOMA DE DESICIONES/S2_MODELOS/mapa_cali_zonasalcaldia.shp")


#---------------------------------------------------------------------------------------------

# Mapa donde se puede ver las los polígonos de las zonas y la ubicación de las viviendas

ggplot() +
  geom_sf(data = mapa_cali, aes(fill = zona_alcaldia)) +
  geom_sf(data = sf_objeto, aes(color = zona)) +
  scale_color_manual(values = c("blue", "red", "green", "orange", "purple")) +
  scale_fill_manual(values = c("blue", "red", "green", "orange", "purple")) +
  ggtitle("Distribución de viviendas por zona") +
  guides(fill=guide_legend(title="Zona")) +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme_minimal() 

En el mapa anterior, se observa más claramente, que al estar el gráfico discriminado por zonas y teniendo las viviendas con su respectivo color por zona de la base de datos original, se presentan viviendas con zonas erróneas asignadas, pues su ubicación difiere de la zona real.

Se realiza entonces la intersección entre el mapa y las viviendas, así cada vivienda que se encuentre en respectiva zona del mapa, quedará catalogado como esa región en la que está y no como se describe en la base de datos original.

#Intersección de la capa de polígono y la de viviendas

library(sf)
sf_objeto <- st_transform(sf_objeto, st_crs(mapa_cali))
out <- st_intersection(sf_objeto, mapa_cali)

# Mapa con las zonas de las ubicaciones de vivienda corregidas

ggplot() +
  geom_sf(data = mapa_cali, aes(fill = zona_alcaldia)) +
  geom_sf(data = out, aes(color = zona_alcaldia)) +
  scale_color_manual(values = c("blue", "red", "green", "orange", "purple")) +
  scale_fill_manual(values = c("blue", "red", "green", "orange", "purple")) +
  ggtitle("Distribución de viviendas por zona ajustado") +
  guides(fill=guide_legend(title="Zona")) +
  theme(plot.title = element_text(hjust = 0.5)) +
  theme_minimal() 

Finalmente, se agrega a la base de datos original vivienda, las variables de comuna y la zona verdadera (zona_alcaldia) que vienen descritas en la base de datos que se utilizó para realizar los mapas.

# Se convierte el resultado de la intersección a un data frame para facilitar la unión
out_df <- st_drop_geometry(out)

vivienda <- vivienda %>%
  left_join(out_df[, c("id", "NOMBRE", "zona_alcaldia")], by = "id")

vivienda <- vivienda %>% rename(COMUNA = NOMBRE)


# Mapa de base de datos original con viviendas corregidad

library(ggplot2)
ggplot(vivienda, aes(longitud, latitud, colour=factor(zona_alcaldia))) + 
  geom_point() +
  labs(title="Distribución de los barrios en Cali por zona") +
  scale_colour_discrete(name  ="Zona") +
  theme_minimal()

0.3.3. Imputación variables parqueaderos y piso.

Se imputa la variable de piso, considerando que es cualitativa ordinal, por la Comuna, el estrato y el tipo de la vivienda.

# Imputación de la variable piso por la moda

mode <- function(x, na.rm = FALSE) {
  if (na.rm) {
    x <- x[!is.na(x)]
  }
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

vivienda = vivienda %>%
  group_by(COMUNA, estrato, tipo_modif) %>%
  mutate(piso_2 = ifelse(is.na(piso), 
                       mode(piso, na.rm = TRUE),
                       piso)) %>%
  ungroup()

Se realiza imputación de la variable parqueaderos por el método de K Nearest Nehihbor (KNN) considerando un k=5 siendo este valor que considera un buen compromiso entre bias y la varianza, pues es lo suficientemente bajo como para tener en cuenta patrones locales, pero no tan bajo como para ser demasiado sensible al ruido.

# Imputación de la variable parqueaderos por knn

library(VIM)

vivienda <- kNN(vivienda, variable = "parqueaderos", k = 5)

0.3.4. Eliminación de variables.

Dado que se corrigieron ciertas variables en nuevas columnas, se eliminan las originales para tener una base de datos más limpia, al igual de la eliminación de los tres registros sin latitud ni longitud.

#Eliminación de variables duplicadas

vivienda <- vivienda %>% select(-tipo, -piso, -parqueaderos, -zona)


# Eliminación de datos faltantes
# Aquellas variables que tuvieron sólamente 3 valores faltantes

vivienda <- vivienda %>% filter(!is.na(longitud), !is.na(latitud))

1. Zona Norte.

1.1 Base de datos.

Una vez realizado la correlación del tipo de vivienda y piso, la re asignación de las zonas de las viviendas teniendo en cuenta su ubicación y la imputación de las variables de piso y parqueaderos, se realiza el filtro inicial con tipo de vivienda Casa y zona Norte.

base1 <- vivienda %>% filter(tipo_modif == "Casa", zona_alcaldia == "Zona Norte")
head(base1)

1.2 Análisis exploratorio

Se realiza un análisis exploratorio de los 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. Como las variables a comparar tienen diferentes tipos de datos, se calculan las correlaciones según en coeficiente de correlación que corresponda.

Correlación: Precio vs área contruida

Al ser ambas variables de tipo cuantitativo continuo, se prueba el supuesto de normalidad de cada una de ellas para determinar el coeficiente de correlación a usar.

sh_precio <- shapiro.test(base1$preciom)
sh_areac <- shapiro.test(base1$areaconst)

cat("El valor-p del test de shapiro wilk para precio es de:", sh_precio$p.value, "\n")
## El valor-p del test de shapiro wilk para precio es de: 2.566014e-23
cat("El valor-p del test de shapiro wilk para área es de:", sh_areac$p.value, "\n")
## El valor-p del test de shapiro wilk para área es de: 1.406968e-24

Siguiendo los valores-p calculados, el precio y el área construida no cumplen con el supuesto de normalidad, por tanto se realizará el cálculo del coeficiente de Spearman.

# Gráfico de correlación con plotly: Precio vs área construida

library(plotly)
cor_test <- cor.test(base1$areaconst, base1$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base1$areaconst and base1$preciom
## S = 5662891, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.8362333
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

plot_areac <- plot_ly(
  data = base1,
  x = ~areaconst,
  y = ~preciom,
  type = 'scatter',
  mode = 'markers',
  marker = list(size = 10, color = 'rgba(0, 112, 255, 0.5)')
) %>%
  layout(
    title = 'Correlación entre área construida y precio',
    xaxis = list(title = 'Área Construida'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_areac

Se observa una correlación de 0.84, el cual es alta. Por tanto, existe una alta correclación y además se tiene un valor-p de 0, por lo que existe una alta correlación entre la variable respuesta y el área construida.

Correlación: Precio vs estrato

En este caso, al ser el estrato una variable cualitativa ordinal, se calcula el coeficiente de correlación de spearman.

# Gráfico de correlación con plotly: Precio vs área estrato

library(plotly)

cor_test <- cor.test(as.numeric(base1$estrato), base1$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  as.numeric(base1$estrato) and base1$preciom
## S = 9719992, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.7189049
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

plot_est <- plot_ly(
  data = base1,
  x = ~estrato,
  y = ~preciom,
  type = 'box',
  marker = list(color = "#CDC673")
) %>%
  layout(
    title = 'Distribución de precios por estrato',
    xaxis = list(title = 'Estrato'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_est

El coeficiente de correlación entre estas dos variables es de 0.72, por lo que puede considerarse alta, además que el valor-p es cero estaría indicando que el estrato tiene alta correlación con la variable respuesta. Gráficamente en el bosplot se observa en la notable diferencia que hay en los precios según el estrato de la vivienda.

Correlación: Precio vs baños

Al ser ambas variables de tipo cuantitativo, se prueba el supuesto de normalidad de cada una de ellas para determinar el coeficiente de correlación a usar.

sh_banios <- shapiro.test(base1$banios)

cat("El valor-p del test de shapiro wilk para baños es de:", sh_banios$p.value, "\n")
## El valor-p del test de shapiro wilk para baños es de: 1.099915e-15

Siguiendo los valores-p calculados, el precio y el los baños no cumplen con el supuesto de normalidad, por tanto se realizará el cálculo del coeficiente de Spearman.

# Gráfico de correlación con plotly: Precio vs baños

library(plotly)

cor_test <- cor.test(base1$banios, base1$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base1$banios and base1$preciom
## S = 12673254, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.6334987
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

plot_ban <- plot_ly(
  data = base1,
  x = ~banios,
  y = ~preciom,
  type = 'box',
  marker = list(color = "#EE9572")
) %>%
  layout(
    title = 'Distribución de precios por número de baños',
    xaxis = list(title = 'Número de Baños'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_ban

Con un coeficiente de correlación de 0.63, hay una relación moderada entre el precio de la casa y la cantidad de baños y se puede identificar en el boxplot, donde aunque se note una ligera tendencia creciente en los precios de la vivienda entre tener 2 baños a 8 baños, las cantidades fuera de este rango no reflejan tener el mismo comportamiento y por ende, se presenta una correlación baja.

Correlación: Precio vs parqueaderos

Al ser ambas variables de tipo cuantitativo, se prueba el supuesto de normalidad de cada una de ellas para determinar el coeficiente de correlación a usar.

base1$parqueaderos_imp <- as.numeric(base1$parqueaderos_imp)

sh_parq <- shapiro.test(base1$parqueaderos_imp)

cat("El valor-p del test de shapiro wilk para habitaciones es de:", sh_parq$p.value, "\n")
## El valor-p del test de shapiro wilk para habitaciones es de: 4.761907e-35

Siguiendo los valores-p calculados, el precio y los parqueaderos no cumplen con el supuesto de normalidad, por tanto se realizará el cálculo del coeficiente de Spearman.

library(plotly)

cor_test <- cor.test(base1$parqueaderos_imp, base1$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base1$parqueaderos_imp and base1$preciom
## S = 47514453, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##        rho 
## -0.3740834
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

# Crear el gráfico de boxplot
plot_parq <- plot_ly(
  data = base1,
  x = ~as.factor(parqueaderos_imp),  # Convertir a factor para el boxplot
  y = ~preciom,
  type = 'box',
  marker = list(color = "#548B54")
) %>%
  layout(
    title = 'Distribución del Precio según el Número de Parqueaderos',
    xaxis = list(title = 'Número de Parqueaderos'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_parq

Se puede observar que la relación entre el número de parqueaderos y el precio es baja, al tener un coeficiente de correlación de -0.37, pues en el comportamiento del precio entre tener 1 parqueadero y no tener es muy similar.

Correlación: Precio vs habitaciones

Al ser ambas variables de tipo cuantitativo, se prueba el supuesto de normalidad de cada una de ellas para determinar el coeficiente de correlación a usar.

sh_hab <- shapiro.test(base1$habitaciones)

cat("El valor-p del test de shapiro wilk para habitaciones es de:", sh_hab$p.value, "\n")
## El valor-p del test de shapiro wilk para habitaciones es de: 1.20499e-20

Siguiendo los valores-p calculados, el precio y las habitaciones no cumplen con el supuesto de normalidad, por tanto se realizará el cálculo del coeficiente de Spearman.

library(plotly)

# Realizar la prueba de correlación
cor_test <- cor.test(base1$habitaciones, base1$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base1$habitaciones and base1$preciom
## S = 20034256, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.4206239
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

# Crear el gráfico de boxplot
plot_hab <- plot_ly(
  data = base1,
  x = ~as.factor(habitaciones),  # Convertir a factor para el boxplot
  y = ~preciom,
  type = 'box',
  marker = list(color = "#EEA2AD")
) %>%
  layout(
    title = 'Distribución del Precio según el Número de Habitaciones',
    xaxis = list(title = 'Número de Habitaciones'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_hab

Se puede observar que la relación entre el número de habitaciones y el precio es baja, al tener un coeficiente de correlación de 0.42, pues en el boxplot puede observarse un comportamiento similar entre la vivienda tener de 4 a 9 habitaciones.

Correlación: Precio vs zona

Al ser la variable zona de tipo cualitativo nominal, su relación con la variable precio se calcula con una ANOVA en el caso paramétrico o con el test de Kruskal Wallis en el caso contrario. Debido a que la variable respuesta precio no cumplió con el supuesto de normalidad como se calculó previamente, se realiza el test de Kruskal Wallis.

Sin embargo, dado que en este caso la base de datos está filtrada por la zona norte, no es posible calcular esta asociación. por tanto, se realiza esta asociación con la comunas que conforman la zona Norte de la ciudad.

base1$COMUNA <- factor(base1$COMUNA)

# Test de Kruskal Wallis

kruskal.test(preciom ~ COMUNA, data=base1)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  preciom by COMUNA
## Kruskal-Wallis chi-squared = 210.09, df = 3, p-value < 2.2e-16

Se tiene un valor-p muy cercano a cero, por lo que se rechaza la hipótesis nula de que el rango medio de los grupos es el mismo, y así la variable de comuna tener una relación con el precio de la casa.

1.3 Modelo de regresión lineal múltiple

Se estima un modelo de regresión múltiple comn las variables analizadas en el punto anterior. La función vendría dada por precio = f(área construida, estrato, parqueaderos, habitaciones, banios).

base1$estrato <- factor(base1$estrato)

# Modelo de regresión lineal múltiple

mod_1 <- lm(preciom ~ areaconst+estrato+parqueaderos_imp+habitaciones+banios, data=base1)
summary(mod_1)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + parqueaderos_imp + 
##     habitaciones + banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -945.96  -72.59  -19.54   45.19 1082.50 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       61.32782   24.10283   2.544  0.01120 *  
## areaconst          0.81735    0.04938  16.551  < 2e-16 ***
## estrato4          88.16491   20.97494   4.203 3.04e-05 ***
## estrato5         133.92233   20.17665   6.637 7.30e-11 ***
## estrato6         381.65243   32.38108  11.786  < 2e-16 ***
## parqueaderos_imp  -2.46307   16.13210  -0.153  0.87870    
## habitaciones      -0.05429    5.15886  -0.011  0.99161    
## banios            19.54790    6.72274   2.908  0.00378 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 163.2 on 584 degrees of freedom
## Multiple R-squared:  0.6637, Adjusted R-squared:  0.6596 
## F-statistic: 164.6 on 7 and 584 DF,  p-value: < 2.2e-16

En los resultados se observa que para predecir el precio de la casa, las variables que influyen es el área construida y el estrato, pues dieron significativas en el modelo, al igual que la cantidad de baños. Al interpretar estos coeficientes, se evidencia que por cada aumento en una unidad de \(m^2\) del área construida, se puede esperar que el precio de la casa aumente en promedio en 800 mil pesos colombianos ($0.82). Para el caso de los estratos, se espera que entre mayor sea el cambio entre los estratos, más costoso es la casa, pues el precio en el estrato 4 es de $88 millones en promedio más alto que el del estrato 3, para el estrato 5 es de $133 millones en promedio que el mismo estrato 3 y por último, para el estrato 6 el precio es $381 millones en promedio más que el estrato de referencia 3. Luego, para la cantidad de baños, cada que se aumente este número en la casa, se esperará que el precio de la vivienda aumente en promedio de $19 millones.

Analizando las interpretaciones, el área construida, el estrato y los baños muestran ser que son congruentes, pues a mayor cantidad de cada uno, el precio aumenta.

Teniendo en cuenta las correlaciones calculadas previamente, aquellas variables que más estuvieron relacionadas con el precio en orden descendente son: área construida (\(\rho=0.84\)), estrato (\(\rho = 0.72\)) y baños (\(\rho = 0.63\)), lo que se estaría mostrando que las características que guardan relación de manera individual con la variable respuesta, también lo manifestaron al realizar un modelo múltiple junto con otras características.

Puede decirse entonces que el modelo, donde sólo se analizan los coeficientes, parecen ser congruentes. En cuanto a la capacidad explicativa del modelo, éste evidencia tener un \(R^2_{adj}=0.65\), el cual pudiera mejorarse más al no ser muy alto. Como sugerencia para mejorar el modelo se tienen:

  1. Considerar la inclusión de interacciones entre variables significativas, como por ejemplo, entre estrato y área construida, esto podría ayudar a capturar efectos combinados que un modelo lineal simple no detecta.

  2. Revisar la posible colinealidad entre las variables explicativas, especialmente entre variables que pueden estar relacionadas, como el número de baños y el número de habitaciones. Reducir la colinealidad podría mejorar la precisión del modelo.

  3. Considerar transformaciones logarítmicas o polinomiales para variables como el precio de la vivienda o el área construida, en caso de que éstas tengan distribuciones sesgadas, lo que podría llevar a un mejor ajuste y a un modelo más robusto.

  4. Evaluar la incorporación de nuevas variables que puedan tener un impacto en el precio de la vivienda como características adicionales de la vivienda que actualmente no están representadas en el modelo.

  5. Explorar modelos alternativos que puedan capturar relaciones no lineales o interacciones más complejas, como árboles de decisión, Random Forest, o modelos de Boosting. Estos modelos podrían manejar mejor las no linealidades y los posibles datos atípicos presentes en los datos.

1.4. Validación de supuestos.

Aún cuando los resultados anteriores reflejan que coeficientes razonables, éste no tiene validez si los tres supuestos de los residuales no se cumplen.

Entre ellos se encuentran:

  1. Supuesto de Normalidad: \(\varepsilon_{i} \sim N(0, \sigma^2)\)

\(H_{0}:\) los residuales siguen una distribución normal.

\(H_{1}\): los residuales no siguen una distribución normal.

  1. Supuesto de Homocedasticidad: \(V[\varepsilon] = \sigma^2\)

\(H_{0}\): la varianza de los residuales es constante. \(H_{1}\): la varianza de los residuales no es constante.

  1. Supuesto de Linealidad.

\(H_{0}:\) existe una relación lineal entre el precio y el área. \(H_{1}:\) no existe una relación lineal entre el precio y el área.

  1. Supuesto de no autocorrelación: \(Cov[\varepsilon_{i}, \varepsilon_{j}] = 0\)

\(H_{0}:\) los residuos son independientes. \(H_{1}:\) los residuos no son independientes.

Dado que los supuestos están basados en los errores, se extraen los residuales del modelo generado.

# Residuales

residuales_1 <- residuals(mod_1)

1.4.1. Supuesto de Normalidad

# Gráficos

par(mfrow=c(1,3))
hist(residuales_1, col="#d6a692")
qqnorm(residuales_1) ; qqline(residuales_1, col="red")
plot(residuales_1)
Gráficos supuesto de Normalidad

Gráficos supuesto de Normalidad

# Prueba de Shapiro Wilk

shapiro.test(residuales_1)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuales_1
## W = 0.81652, p-value < 2.2e-16

De lo anterior, analizando el histograma, se observa se observa que no hay una buena distribución de los residuales y en cuanto al qqplot, éstos no se ajustan de buena manera a la curva teórica del modelo. Y por último en los gráficos de residuales no pareciera verse un patrón de comportamiento.

Ahora, corroborando la información anterior, la prueba de Shapiro Wilk no refleja el cumplimiento del supuesto de Normalidad, pues se tiene un valor p muy cercano a cero (valor-p<0.001).

1.4.2. Supuesto de Homocedasticidad

# Prueba de homocedasticidad

lmtest::bptest(mod_1)
## 
##  studentized Breusch-Pagan test
## 
## data:  mod_1
## BP = 93.967, df = 7, p-value < 2.2e-16

El test confirma que se rechaza la hipótesis nula (\(H_{0}\)) por lo que no se cumpliría el supuesto de homocedasticidad (valor-p<0.001).

1.4.3 Supuesto de no autocorrelación

# Prueba de no autocorrelación

lmtest::dwtest(mod_1)
## 
##  Durbin-Watson test
## 
## data:  mod_1
## DW = 1.928, p-value = 0.1705
## alternative hypothesis: true autocorrelation is greater than 0

El test confirma que no se rechaza la hipótesis nula (\(H_{0}\)) y se cumple el supuesto de independencia de los residuales (valor-p=0.18).

1.4.4 Supuesto de multicolinealidad

# Prueba de multicolinealidad

library(car)

vif(mod_1)
##                      GVIF Df GVIF^(1/(2*Df))
## areaconst        1.688522  1        1.299432
## estrato          1.863232  3        1.109288
## parqueaderos_imp 1.270934  1        1.127357
## habitaciones     1.856239  1        1.362439
## banios           2.139946  1        1.462855

Analizando la multicolinealidad de las variables, se observa que al ser el VIF ajustado en todos los casos por debajo de 2, indica que no existe multicolinealidad significativa entre las variables independientes.

Como se observa en la validación de supuestos, la normalidad y la homocedasticidad no se cumplen en el modelo planteado. Algunas de las alternativas a realizar son las siguientes:

  1. Transformaciones de las variables: aplicar transformaciones a la variable de respuesta precio, ya sea logarítmica, la raíz cuadrada, o la inversa. Esto ayudaría a normalizar la distribución de los residuales si la variable original tiene una distribución sesgada y a su vez estabilizaría la varianza.

  2. Considerar otros modelos: si la transformación de la variable dependiente no mejora la normalidad de los residuales, se puede considerar un modelo que no asuma normalidad de los residuales, como una regresión robusta o modelos como Random Forest o Gradient Boosting Machines o también un modelo de regresión ponderada (WLS), que mitiga el problema de la homocedasticidad asignando un peso a cada observación basado en la varianza de los residuales.

1.5. Predicción vivienda 1.

La solicitud de asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad con requisitos de la vivienda 1, viene dada por las siguientes características:

tabla <- data.frame(
  
  Caracteristicas = c("tipo", "area construida", "parqueaderos", "banios", "habitaciones", "estrato",
                      "zona", "credito preaprobado"),
  Vivienda_1 = c("Casa", 200, 1, 2, 4, "4 o 5", "Norte", "350 millones")
  )

library(gt)
tabla %>%
  gt()
Caracteristicas Vivienda_1
tipo Casa
area construida 200
parqueaderos 1
banios 2
habitaciones 4
estrato 4 o 5
zona Norte
credito preaprobado 350 millones

Ahora, tomando en cuenta la solicitud, se realiza la predicción del modelo ajustado. Se realizan dos modelos de predicción dado que se requiere dos estratos; 4 y 5.

# Predicción solicitud vivienda 1 para estrato 4

data_pred_1 <- data.frame(
  areaconst = 200,      
  parqueaderos_imp = 1,  
  banios = 2    ,
  habitaciones = 4,
  estrato = "4"
)

pred_1 <- predict(mod_1, newdata = data_pred_1)

cat("La predicción del precio de la casa de la solicitud vivienda 1 para estrato 4 es de", pred_1 , "millones","\n")
## La predicción del precio de la casa de la solicitud vivienda 1 para estrato 4 es de 349.3784 millones
# Predicción solicitud vivienda 1 para estrato 5

data_pred_2 <- data.frame(
  areaconst = 200,      
  parqueaderos_imp = 1,  
  banios = 2    ,
  habitaciones = 4,
  estrato = "5"
)

pred_2 <- predict(mod_1, newdata = data_pred_2)

cat("La predicción del precio de la casa de la solicitud vivienda 1 para estrato 5 es de", pred_2 , "millones","\n")
## La predicción del precio de la casa de la solicitud vivienda 1 para estrato 5 es de 395.1358 millones

Teniendo en cuenta el crédito preaprobado, la predicción de las características de la casa en estrato 4 parace que pudiera ajustarse al presupuesto que tiene el cliente, aunque no se cumple al no poderse encontrar una vivienda en el estrato 5 con estas mismas condiciones y que no supere el dinero permitido en invertir.

1.6. Ofertas potenciales.

De acuerdo con las características solicitadas de la vivienda, se busca qué casa se le puede ofrecer al cliente que esté dentro de sus parámetros.

# Caracteríticas de la vivienda 1

viviendas_1 <- base1 %>%
  filter(areaconst==200, parqueaderos_imp==1, banios==2, habitaciones==4, estrato %in% c("4", "5"))

viviendas_1

Sin embargo, no se encontró en el catálogo viviendas con estas características en específico, por lo que se buscará si hay viviendas en el estrato 4 o 5, que tengan más de 200\(m^2\), más de 1 parqueaqdero, más de 2 baños y 4 habitaciones y además que su precio no supere los $350 millones para así tener la oefrta con mejores características al mismo valor.

# Caracteríticas de la vivienda 1

viviendas_1 <- base1 %>%
  filter(areaconst>=200, parqueaderos_imp>=1, banios>=2, habitaciones>=4, estrato %in% c("4", "5"),
         preciom<=350)

viviendas_1

Se encontraron dos viviendas que cumplen con los requisitos; la vivienda con id=852, que tiene un precio de $340 millones, un área construida de 208\(m^2\), cantidad de baños 6 y de habitaciones 4, además de que se encuentra en el barrio “El bosque” en la comuna 4, estrato 5 y se encuentra en el piso 3. De igual manera, se encontró que la mejor oferta del estrato 4, fue la vivienda con id=4727, con un área construida mucho mayor que la encontrada en el estrato 5 y a un precio más bajo. Tiene la misma cantidad de baños, habitaciones y parqueaderos que la anterior oferta y se encuentra en el barrio “Granada” en la comuna 2, encontrándose en el piso 2.

Para conocer el comportamiento de las casas en la zona Norte con un precio de hasta $350 millones, se realizan descriptivas de la zona y se compararán con las características de las mejores viviendas para ofrecer al cliente.

# Estadísticas descriptivas de viviendas con precios de hasta $350 millones; var cuantitativas

base1_350 <- base1 %>% filter(preciom <= 350)

var_cuant <- c("preciom", "areaconst", "banios", "habitaciones", "parqueaderos_imp")

min_base1_350 <- apply(base1_350[, var_cuant], 2, min, na.rm = TRUE)
max_base1_350 <- apply(base1_350[, var_cuant], 2, max, na.rm = TRUE)
median_base1_350 <- apply(base1_350[, var_cuant], 2, median, na.rm = TRUE)
media_base1_350 <- apply(base1_350[, var_cuant], 2, mean, na.rm = TRUE)
cv_base1_350 <- apply(base1_350[, var_cuant], 2, function(x) sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE))

tab_varcuant <- data.frame(
  "Minimo" = round(min_base1_350, 2),
  "Mediana" = round(median_base1_350, 2),
  "Media" = round(media_base1_350, 2),
  "Maximo" = round(max_base1_350, 2),
  "CV" = round(cv_base1_350, 2)
)


library(knitr)
library(kableExtra)
t1 <- kable(tab_varcuant, format = "html", align = "c",
           caption = "Resumen de estadísticas variables cuantitativas") %>%
  kable_styling(full_width = FALSE) %>%
  add_header_above(c(" " = 1, "Estadísticas descriptivas" = 5))

t1
Resumen de estadísticas variables cuantitativas
Estadísticas descriptivas
Minimo Mediana Media Maximo CV
preciom 100 237.5 238.65 350 0.32
areaconst 30 131.0 146.68 450 0.47
banios 0 3.0 2.74 6 0.37
habitaciones 0 4.0 4.03 9 0.35
parqueaderos_imp 0 0.0 0.48 1 1.04

Las casas que se encuentran en la zona Norte con precios de hasta $350 millones, tiene como mediana un área costruida de 131\(m^2\), una cantidad de 3 baños, 4 habitaciones y como máximo 1 parqueadero por vviienda. Siguiendo las características de la casa que el cliente desea, tanto el área, como el número de baños es mayor que la mitad de las viviendas de esta zona Norte. Por lo que las viviendas ofertadas escogidas se encuentran con mejores atributos que las demás y a un precio accequible.

# Estadísticas descriptivas de viviendas con precios de hasta $350 millones; var cualitativas

base1_350 %>% group_by(estrato) %>% count(estrato)
base1_350 %>% group_by(COMUNA) %>% count(COMUNA)
base1_350 %>% group_by(piso_2) %>% count(piso_2)

En cuanto al estrato, las viviendas de hasta $350 millones de la zona Norte son caracterizadas por ser de estrato 3 en su mayoría y pertenecer por ende a la Comuna 5 y donde las viviendas ofertadas se encuentran con mayor frecuencia en el piso 2.

Para conocer la ubicación de estas viviendas, se grafica las ubicaciones de ellas en el mapa de Cali.

# Mapa con mejores ofertas

datos_filtrados <- base1 %>% filter(preciom <= 350)

mejores_ofertas <- datos_filtrados %>% filter(id %in% c(852, 4727))

fig <- plot_ly(data = datos_filtrados, 
               lat = ~latitud, 
               lon = ~longitud, 
               type = 'scattermapbox', 
               mode = 'markers', 
               marker = list(size = 10, opacity = 0.7, color = 'blue'), 
               text = ~paste(
                 'ID:', id, '<br>',
                 'Precio:', preciom, 'millones<br>',
                 'Área Construida:', areaconst, 'm²<br>',
                 'Baños:', banios, '<br>',
                 'Habitaciones:', habitaciones, '<br>',
                 'Barrio:', barrio, '<br>',
                 'Estrato:', estrato
               )) %>%
  add_trace(data = mejores_ofertas, 
            lat = ~latitud, 
            lon = ~longitud, 
            type = 'scattermapbox', 
            mode = 'markers', 
            marker = list(size = 15, color = 'red'), 
            text = ~paste(
              'ID:', id, '<br>',
              'Precio:', preciom, 'millones<br>',
              'Área Construida:', areaconst, 'm²<br>',
              'Baños:', banios, '<br>',
              'Habitaciones:', habitaciones, '<br>',
              'Barrio:', barrio, '<br>',
              'Estrato:', estrato
            ),
            name = 'Mejor oferta') %>%
  layout(
    mapbox = list(
      style = 'open-street-map',
      center = list(lat = mean(datos_filtrados$latitud), lon = mean(datos_filtrados$longitud)),
      zoom = 12
    ),
    title = 'Viviendas con presupuesto igual o menor a $350 millones',
    hovermode = 'closest'
  )

fig

1.7. Entrenamiento del modelo de regresión lineal múltiple.

1.7.1. Modelo.

Como metodología alternativa, se realiza el entrenamiento del modelo de regresión lineal múltiple son una partición aleatoria donde el 70% de los datos serán los de entrenamiento y el 30% restante serán los datos de prueba.

# Entrenamiento del modelo de regresión lineal  múltiple.

library(caret)

set.seed(123)
trainIndex <- createDataPartition(base1$preciom, p = 0.7, list = FALSE)
trainData <- base1[trainIndex, ]
testData <- base1[-trainIndex, ]

mod_1_train <- lm(preciom ~ areaconst + estrato + parqueaderos_imp + habitaciones + banios, 
                  data = trainData)

summary(mod_1_train)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + parqueaderos_imp + 
##     habitaciones + banios, data = trainData)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -487.70  -73.05  -12.61   47.51 1040.57 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       46.43171   27.07512   1.715  0.08712 .  
## areaconst          1.10601    0.06603  16.749  < 2e-16 ***
## estrato4          36.72786   24.16630   1.520  0.12934    
## estrato5          68.02663   23.33217   2.916  0.00375 ** 
## estrato6         325.36028   36.30653   8.961  < 2e-16 ***
## parqueaderos_imp -17.53255   18.23497  -0.961  0.33688    
## habitaciones      -1.88417    5.87622  -0.321  0.74865    
## banios            20.17771    7.55346   2.671  0.00786 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 155.1 on 408 degrees of freedom
## Multiple R-squared:  0.7114, Adjusted R-squared:  0.7065 
## F-statistic: 143.7 on 7 and 408 DF,  p-value: < 2.2e-16

Con el modelo entrenado se observan diferencias en los coeficientes de cada una de las variables con respecto al modelo sin entrenar. Esta vez, el área construida, el estrato 5 y 6 y el número de baños siguen aportando significativamente a la predicción del precio de la vivienda, pero con un peso distinto. Por cada aumento en \(m^2\) del área de la vivienda, el precio de ella aumenta en promedio $1 millon. Para el estrato 6, éste aumenta el precio promedio en $325 millones si se compara con el estrato 2 y $68 millones en el estrato 5 y por cada unidad de baño más, el precio promedio del apartamento tiene un valor de $20 millones más.

Este entrenamiento resulta ser más congruente con lo encontrado en las correlaciones realizadas vs el precio del apartamento, donde la cantidad de parqueaderos y de habitaciones no obtuvieron coeficientes de correlación que indicaran una relación fuerte con la variable respuesta (\(\rho=-0.35\) y \(\rho=0.42\) respectivamente).

Luego, la varianza explicada fue de \(R^2_{adj}=0.71\), más baja que en la regresión sin entrenamiento, que aunque sigue siendo alta, se podría mejorar con las recomendaciones descritas en la estimación del modelo de regresión (Sección 1.3).

1.7.2. Predicción con datos de prueba.

Para conocer si el modelo entrenado tiene buen rendimiento, se predicen los precios de cada apartamento y se compara con el valor real de este.

# Predicción con datos de prueba

predictions <- predict(mod_1_train, newdata = testData)

head(data.frame(Predicted = predictions, Actual = testData$preciom))

Revisando ligeramente la tabla de las predicciones del precio y de su respectivo valor real, se evidencia que existe una diferencia grande estre ellas dos.

1.7.3. Métricas de rendimiento.

Se calculan las métricas de Error Cuadrático Medio, Error Absoluto Medio y Coeficiente de determinación \(R^2\) para evaluar el rendimiento de la predicción del modelo entrenado.

# Error Cuadrático Medio (MSE)
mse <- mean((testData$preciom - predictions)^2)

# Error Absoluto Medio (MAE)
mae <- mean(abs(testData$preciom - predictions))

# Coeficiente de Determinación (R²)
sst <- sum((testData$preciom - mean(testData$preciom))^2)  # Suma de cuadrados total
sse <- sum((testData$preciom - predictions)^2)         # Suma de cuadrados del error
r_squared <- 1 - (sse / sst)

cat("Error Cuadrático Medio (MSE) es:", mse, "\n")
## Error Cuadrático Medio (MSE) es: 40016.16
cat("Error Absoluto Medio (MAE) es:", mae, "\n")
## Error Absoluto Medio (MAE) es: 114.6091
cat("Coeficiente de Determinación (R2) es:", r_squared, "\n")
## Coeficiente de Determinación (R2) es: 0.4255588

Siguiendo los anteriores cálculos, el MSE de 400016 evidencia que, en promedio, el cuadrado de los errores de predicción es de 400016 millones de pesos. Por otro lado el MAE, con un valor de 114.6 millones de pesos indica que, en promedio, las predicciones del modelo están a 114.6 millones de pesos de distancia de los valores reales. Y por último, el \(R^2\) de 0.42 indica que el modelo explica el 42% de la variabilidad en los precios de las viviendas, el cual es relativamente bajo.

2. Zona Sur.

2.1 Base de datos.

Esta vez, el filtro de la nueva base de datos base2 tendrá las mismas características que la base anterior pero en la zona Sur y tipo de vivienda Apartamento.

base2 <- vivienda %>% filter(tipo_modif == "Apartamento", zona_alcaldia == "Zona Sur")
head(base2)

2.2 Análisis exploratorio.

Al igual que en la zona Norte, se realiza un análisis exploratorio de los datos enfocado en la correlación de la variable respuesta con las demás características.

Por tanto, es necesario calcular las pruebas de normalidad de las variables cuantitativas para poder conocer el coeficiente de correlación que se debe usar.

Correlación: Precio vs área contruida

# Correlación: Precio vs área contruida

sh_precio <- shapiro.test(base2$preciom)
sh_areac <- shapiro.test(base2$areaconst)

cat("El valor-p del test de shapiro wilk para precio es de:", sh_precio$p.value, "\n")
## El valor-p del test de shapiro wilk para precio es de: 4.986116e-47
cat("El valor-p del test de shapiro wilk para área es de:", sh_areac$p.value, "\n")
## El valor-p del test de shapiro wilk para área es de: 1.112236e-54

Al ser ambas variable sno normales, se calcula el coeficiente de spearman.

# Gráfico de correlación con plotly: Precio vs área construida

library(plotly)
cor_test <- cor.test(base2$areaconst, base2$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base2$areaconst and base2$preciom
## S = 130262110, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##     rho 
## 0.89604
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

plot_areac <- plot_ly(
  data = base2,
  x = ~areaconst,
  y = ~preciom,
  type = 'scatter',
  mode = 'markers',
  marker = list(size = 10, color = 'rgba(0, 112, 255, 0.5)')
) %>%
  layout(
    title = 'Correlación entre área construida y precio',
    xaxis = list(title = 'Área Construida'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_areac

Se observa una correlación de 0.79, el cual puede considerarse alta y por lo tanto, el precio de la vivienda y el área construida están altamente correlacionadas (\(\rho=0.89\)).

Correlación: Precio vs estrato

En este caso, al ser el estrato una variable cualitativa ordinal, se calcula el coeficiente de correlación de spearman.

library(plotly)

# Realizar la prueba de correlación
cor_test <- cor.test(as.numeric(base2$estrato), base2$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  as.numeric(base2$estrato) and base2$preciom
## S = 312665971, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.7504666
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

# Crear el gráfico de boxplot
plot_est <- plot_ly(
  data = base2,
  x = ~as.factor(estrato),  # Convertir a factor para el boxplot
  y = ~preciom,
  type = 'box',
  marker = list(color = "#CDC673")
) %>%
  layout(
    title = 'Distribución del Precio según el Estrato',
    xaxis = list(title = 'Estrato'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_est

En este caso, el estrato en el que se encuentra la vivienda y su precio también tienen una correlación alta (\(\rho\)=0.75) y se ve evidenciado en el bosplot, donde se observa una tendencia creciente en el precio de la vviienda en cada estrato.

Correlación: Precio vs baños

# Correlación: Precio vs baños

sh_banios <- shapiro.test(base2$banios)

cat("El valor-p del test de shapiro wilk para baños es de:", sh_banios$p.value, "\n")
## El valor-p del test de shapiro wilk para baños es de: 1.243067e-45
library(plotly)

# Realizar la prueba de correlación
cor_test <- cor.test(base2$banios, base2$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base2$banios and base2$preciom
## S = 336276303, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.7316236
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

# Crear el gráfico de boxplot
plot_ban <- plot_ly(
  data = base2,
  x = ~as.factor(banios),  # Convertir a factor para el boxplot
  y = ~preciom,
  type = 'box',
  marker = list(color = "#EE9572")
) %>%
  layout(
    title = 'Distribución del Precio según el Número de Baños',
    xaxis = list(title = 'Número de Baños'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_ban

Se demostró que la cantidad de baños guarda una relación fuerte entre el precio como las características de área y estrato (\(\rho=0.73\)) y donde el comportamiento del precio es creciente a medida que aumenta esta cantidad de baños.

Correlación: Precio vs parqueaderos

# Correlación: Precio vs parqueaderos

base2$parqueaderos_imp <- as.numeric(base2$parqueaderos_imp)

sh_parq <- shapiro.test(base2$parqueaderos_imp)

cat("El valor-p del test de shapiro wilk para habitaciones es de:", sh_parq$p.value, "\n")
## El valor-p del test de shapiro wilk para habitaciones es de: 5.981449e-62
library(plotly)

# Realizar la prueba de correlación
cor_test <- cor.test(base2$parqueaderos_imp, base2$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base2$parqueaderos_imp and base2$preciom
## S = 1703356034, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##        rho 
## -0.3594195
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

# Crear el gráfico de boxplot
plot_parq <- plot_ly(
  data = base2,
  x = ~as.factor(parqueaderos_imp),  # Convertir a factor para el boxplot
  y = ~preciom,
  type = 'box',
  marker = list(color = "#548B54")
) %>%
  layout(
    title = 'Distribución del Precio según el Número de Parqueaderos',
    xaxis = list(title = 'Número de Parqueaderos'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_parq

En cuanto a la cantidad de parqueaderos, ésta muuestra una correlación muy débil con respecto al precio de la vivienda (\(\rho=-0.35\)), pues su comportamiento en los precios es similar cuando no se tiene parqueaderos a cuando sólo tiene 1.

Correlación: Precio vs habitaciones

# Correlación: Precio vs habitaciones

sh_hab <- shapiro.test(base1$habitaciones)

cat("El valor-p del test de shapiro wilk para habitaciones es de:", sh_hab$p.value, "\n")
## El valor-p del test de shapiro wilk para habitaciones es de: 1.20499e-20
library(plotly)

# Realizar la prueba de correlación
cor_test <- cor.test(base2$habitaciones, base2$preciom, method = "spearman")
cor_test
## 
##  Spearman's rank correlation rho
## 
## data:  base2$habitaciones and base2$preciom
## S = 723471949, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.4226093
cor_coefficient <- cor_test$estimate
p_value <- cor_test$p.value

# Crear el gráfico de boxplot
plot_hab <- plot_ly(
  data = base2,
  x = ~as.factor(habitaciones),  # Convertir a factor para el boxplot
  y = ~preciom,
  type = 'box',
  marker = list(color = "#EEA2AD")
) %>%
  layout(
    title = 'Distribución del Precio según el Número de Habitaciones',
    xaxis = list(title = 'Número de Habitaciones'),
    yaxis = list(title = 'Precio'),
    annotations = list(
      text = paste("Coeficiente de correlación (r):", round(cor_coefficient, 2), "<br>Valor-p:", round(p_value, 4)),
      xref = "paper", yref = "paper",
      x = 1.05, y = 1,
      showarrow = FALSE,
      font = list(size = 12)
    )
  )

plot_hab

También sucede con la correlación entre el número de habitaciones y el preecio de la vivienda en la zona Sur, el cual hay una correlación débil entre ambas variables (\(\rho=0.42\)). Lo anterior puede ser evidenciado en el boxplot, donde a pesar que puede existir una tendencia creciente entre el número de habitaciones y el precio, ésto no sucede de forma constante en todas las cantidades de habitaciones que tiene la zona Sur.

Correlación: Precio vs zona

Se realiza entonces un análisis de Kruskal Wallis al ser la variable precio no normal. En este caso, al sólo tener casas de la zona Sur, se calculará si hay asociación entre el precio de la vivienda y las comunas que conforman esta zona.

base2$COMUNA <- factor(base2$COMUNA)

# Test de Kruskal Wallis

kruskal.test(preciom ~ COMUNA, data=base2)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  preciom by COMUNA
## Kruskal-Wallis chi-squared = 721.97, df = 1, p-value < 2.2e-16

Se tiene un valor-p muy cercano a cero, por lo que se rechaza la hipótesis nula de que el rango medio de los grupos es el mismo, y así la variable de comuna tener una relación con el precio de la casa en la zona Sur.

2.3. Modelo de regresión lineal múltiple.

Se estima un modelo de regresión múltiple comn las variables analizadas en el punto anterior. La función vendría dada por precio=f(áreaconstruida,estrato,parqueaderos,habitaciones,banios).

base2$estrato <- factor(base2$estrato)

# Modelo de regresión lineal múltiple

mod_2 <- lm(preciom ~ areaconst+estrato+parqueaderos_imp+habitaciones+banios, data=base2)
summary(mod_2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + parqueaderos_imp + 
##     habitaciones + banios, data = base2)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1130.63   -40.49    -1.83    36.65   942.67 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       49.36360   19.63204   2.514  0.01200 *  
## areaconst          1.32889    0.05143  25.838  < 2e-16 ***
## estrato4         -11.57610   16.52783  -0.700  0.48376    
## estrato5          20.96340   16.80392   1.248  0.21235    
## estrato6         191.34209   18.19474  10.516  < 2e-16 ***
## parqueaderos_imp -22.65147    7.13706  -3.174  0.00153 ** 
## habitaciones     -20.20167    4.37082  -4.622 4.05e-06 ***
## banios            60.46362    3.89641  15.518  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 104.1 on 1951 degrees of freedom
## Multiple R-squared:  0.7604, Adjusted R-squared:  0.7595 
## F-statistic: 884.4 on 7 and 1951 DF,  p-value: < 2.2e-16

En los resultados se observa que para predecir el precio de los apartamentos en la zona Sur, las variables que influyen es el área construida y el estrato 6, pues dieron significativas en el modelo, al igual que la cantidad de parqueaderos, baños y de habitaciones. Al interpretar estos coeficientes, se evidencia que por cada aumento en una unidad de m2 del área construida, se puede esperar que el precio de la casa aumente en promedio en $1 millón de pesos. Para los estratos, resultó significativo que el estar la vivienda en un estrato 6. aumente en promedio el precio en $191 millones si se compara con el estrato 3. Luego, para la cantidad de baños, cada que se aumente esta cantidad en la casa, se esperará que el precio de la vivienda aumente en promedio de $60 millones y en las habitaciones, que disminuya el precio promedio de la vivienda en $20 millones si tiene una habitación menos. También sucede lo mismo con la cantidad de parqueaderos, donde por cada aumento en esta cantidad, el precio promedio del apartamento disminuya en $22 millones.

Siguiendo las interpretaciones, suena congruente que a mayor área construida, mayor estrato y mayor cantidad de baños el precio de la vivienda se incremente, más no parece serlo en las variable de habitaciones y parqueaderos, donde el precio disminuye si hay una habitación o un parqueadero más. Con base a las correlaciones calculadas anteriormente, los parqueaderos mostraron tener una correlación baja con el precio al igual que la cantidad de habitaciones, aunque en conjunto con otras variables, éstas sean significativas, los coeficientes no son lógicos con la situación.

Luego, con base a la varianza explicada, se obtuvo un valor de \(R^2_{adj}=0.76\), un poco alto pero de igual manera se podría mejorar esta capacidad. Entre las sugerencias se tendrían las mismas que en el caso de la zona Norte:

  1. Agregar interacciones, como entre el estrato y el área construida, pues esto podría ayudar a capturar efectos combinados que un modelo lineal podría no detectar.

  2. Revisar la multicolinealidad entre variables que podrían estar relacionadas para mejorar la precisión del modelo.

  3. Transformar variables como el precio de la vivienda o el área construida si tienen distribuciones sesgadas. Esto podría mejorar el ajuste del modelo y hacerlo más robusto.

  4. Incluir nuevas variables que podrían influir en el precio de la vivienda, como características adicionales que actualmente no están incluidas en el modelo.

  5. Probar el uso de modelos alternativos que puedan captar relaciones no lineales o interacciones más complejas, como árboles de decisión, Random Forest, o modelos de Boosting. Estos enfoques pueden manejar mejor las no linealidades y los posibles valores atípicos en los datos.

2.4. Validación de supuestos.

Tomando en cuenta las hipótesis de cada uno de los supuestos mostrados en la zona Norte, se verifican si ellos se cumplen.

# Residuales

residuales_2 <- residuals(mod_2)

2.4.1. Supuesto de Normalidad.

# Prueba de Shapiro Wilk

shapiro.test(residuales_2)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuales_2
## W = 0.76582, p-value < 2.2e-16

La prueba de Shapiro Wilk no refleja el cumplimiento del supuesto de Normalidad, pues se tiene un valor p muy cercano a cero (valor-p<0.001).

2.4.2. Supuesto de Homocedasticidad.

# Prueba de homocedasticidad

lmtest::bptest(mod_2)
## 
##  studentized Breusch-Pagan test
## 
## data:  mod_2
## BP = 577.41, df = 7, p-value < 2.2e-16

El test confirma que se rechaza la hipótesis nula (H0) por lo que no se cumpliría el supuesto de homocedasticidad (valor-p<0.001).

2.4.3. Supuesto de no autocorrelación.

# Prueba de no autocorrelación

lmtest::dwtest(mod_2)
## 
##  Durbin-Watson test
## 
## data:  mod_2
## DW = 1.7202, p-value = 2.157e-10
## alternative hypothesis: true autocorrelation is greater than 0

Por último, el test rechaza la hipótesis nula (H0) y no se cumple el supuesto de independencia de los residuales (valor-p<0.001).

2.4.4 Supuesto de multicolinealidad

# Prueba de multicolinealidad

vif(mod_2)
##                      GVIF Df GVIF^(1/(2*Df))
## areaconst        2.043680  1        1.429573
## estrato          1.730359  3        1.095694
## parqueaderos_imp 1.137618  1        1.066592
## habitaciones     1.578546  1        1.256402
## banios           2.743186  1        1.656257

Analizando la multicolinealidad de las variables, se observa que al ser el VIF ajustado en todos los casos por debajo de 2, indica que no existe multicolinealidad significativa entre las variables independientes.

En esta ocasión, a diferencia de la zona Norte, no se cumplieron ninguno de los tres supuestos, por lo que se sugiere realizar estas alternativas para corregir la no autocorrelación. En cuanto al supuesto de Normalidad y Homocedasticidad, las sugerencias son las mismas que las de la zona Norte:

  1. Incluir variables de tiempo, como el año o el mes de venta. Esto puede ayudar a capturar estas dependencias y reducir la autocorrelación en los residuos.

  2. En algunos casos, la autocorrelación puede ser resultado de una especificación incorrecta del modelo, por tanto aplicar transformaciones a las variables dependientes o independientes, como diferencias estacionales o ajustes logarítmicos, puede ayudar a estabilizar la varianza y reducir la autocorrelación.

  3. La autocorrelación también puede indicar que algunas variables importantes están omitidas del modelo, por eso se puede considerar incluir variables relevantes.

2.5 Predicción vivienda 2.

La solicitud de asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad con requisitos de la vivienda 2, viene dada por las siguientes características:

tabla <- data.frame(
  
  Caracteristicas = c("tipo", "area construida", "parqueaderos", "banios", "habitaciones", "estrato",
                      "zona", "credito preaprobado"),
  Vivienda_2 = c("Apartamento", 300, 3, 3, 5, "5 o 6", "Sur", "850 millones")
  )

library(gt)
tabla %>%
  gt()
Caracteristicas Vivienda_2
tipo Apartamento
area construida 300
parqueaderos 3
banios 3
habitaciones 5
estrato 5 o 6
zona Sur
credito preaprobado 850 millones

Tomando las características de la solicitud de la segunda vivienda, se realizan dos modelos de predicción dado que se requieren dos estratos; 5 y 6.

# Predicción solicitud vivienda 2 para estrato 5

data_pred_1 <- data.frame(
  areaconst = 300,      
  parqueaderos_imp = 3,  
  banios = 3    ,
  habitaciones = 5,
  estrato = "5"
)

pred_2 <- predict(mod_2, newdata = data_pred_1)

cat("La predicción del precio de la casa de la solicitud vivienda 2 para estrato 4 es de", pred_2 , "millones","\n")
## La predicción del precio de la casa de la solicitud vivienda 2 para estrato 4 es de 481.4208 millones
# Predicción solicitud vivienda 2 para estrato 6

data_pred_2 <- data.frame(
  areaconst = 300,      
  parqueaderos_imp = 3,  
  banios = 3    ,
  habitaciones = 5,
  estrato = "6"
)

pred_2 <- predict(mod_2, newdata = data_pred_2)

cat("La predicción del precio de la casa de la solicitud vivienda 1 para estrato 6 es de", pred_2 , "millones","\n")
## La predicción del precio de la casa de la solicitud vivienda 1 para estrato 6 es de 651.7995 millones

Teniendo en cuenta que el crédito preaprobado es de $850 millones, las características de la vivienda en ambos estratos se ajustan al presupuesto, variando únicamente en el estrato en el que ésta se encuentra, a pesar de tener las mismas características, por lo que es posible encontrar viviendas en ambos estratos que cumplan con lo solicitado por el cliente.

2.6. Ofertas potenciales.

De acuerdo con las características solicitadas de la vivienda, se busca qué casa se le puede ofrecer al cliente que esté dentro de sus parámetros.

# Caracteríticas de la vivienda 1

viviendas_2 <- base2 %>%
  filter(areaconst==300, parqueaderos_imp==3, banios==3, habitaciones==5, estrato %in% c("5", "6"))

viviendas_2

Sin embargo, no se encontró en el catálogo viviendas con estas características en específico, por lo que se buscará si hay viviendas en el estrato 4 o 5, que tengan más de 300m2, más de 3 parqueaderos, más de 3 baños y 5 habitaciones y además que su precio no supere los $850 millones para así tener la oferta con mejores características al mismo valor.

# Caracteríticas de la vivienda 2

viviendas_2 <- base2 %>%
  filter(areaconst>=300, parqueaderos_imp>=3, banios>=3, habitaciones>=5, estrato %in% c("5", "6"),
         preciom<=850)

viviendas_2

En el catálogo no se encontró una vivienda con mejores características con un precio de hasta $850 millones, por lo que ahora es necesario encontrar ofertas de vivienda en el catálogo que tengan como máximo las descripciones de la vivienda.

# Caracteríticas de la vivienda 2

viviendas_2 <- base2 %>%
  filter(areaconst<=300, parqueaderos_imp<=3, banios<=3, habitaciones<=5, estrato %in% c("5", "6"),
         preciom<=850) %>%
  arrange(desc(preciom))

head(viviendas_2, 5)

Se encontraron apartamentos en el estrato 6 con no más de 3 habitaciones, pero a su vez más económicos que el presupuesto que se tiene. El apartamento con id=3848, tiene un área construida de 200\(m^2\), con 3 baños y habitaciones y aunque no tiene parqueadero, su precio está en casi $10 millones menos que el crédito pre aprobado, éste se encuentra en el barrio “Ciudad Jardín” en la comuna 22. A pesar de que las viviendas escogidas no cuentan con algún parqueadero, esto puede deberse a que sea un conjunto residencial con parqueaderos comunitarios, por lo que sí se puede acceder a uno, aún así, las viviendas escogidas cumplen con la mayoría de las características solicitadas y a un precio menor que el del crédito.

Para conocer el comportamiento de las casas en la zona Sur con un precio de hasta $850 millones, se realizan descriptivas de la zona y se compararán con las características de las mejores viviendas para ofrecer al cliente.

# Estadísticas descriptivas de viviendas con precios de hasta $350 millones; var cuantitativas

base2_850 <- base2 %>% filter(preciom <= 850)

var_cuant <- c("preciom", "areaconst", "banios", "habitaciones", "parqueaderos_imp")

min_base2_850 <- apply(base2_850[, var_cuant], 2, min, na.rm = TRUE)
max_base2_850 <- apply(base2_850[, var_cuant], 2, max, na.rm = TRUE)
median_base2_850 <- apply(base2_850[, var_cuant], 2, median, na.rm = TRUE)
media_base2_850 <- apply(base2_850[, var_cuant], 2, mean, na.rm = TRUE)
cv_base2_850 <- apply(base2_850[, var_cuant], 2, function(x) sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE))

tab_varcuant <- data.frame(
  "Minimo" = round(min_base2_850, 2),
  "Mediana" = round(median_base2_850, 2),
  "Media" = round(media_base2_850, 2),
  "Maximo" = round(max_base2_850, 2),
  "CV" = round(cv_base2_850, 2)
)


library(knitr)
library(kableExtra)
t1 <- kable(tab_varcuant, format = "html", align = "c",
           caption = "Resumen de estadísticas variables cuantitativas") %>%
  kable_styling(full_width = FALSE) %>%
  add_header_above(c(" " = 1, "Estadísticas descriptivas" = 5))

t1
Resumen de estadísticas variables cuantitativas
Estadísticas descriptivas
Minimo Mediana Media Maximo CV
preciom 70 260 302.26 850 0.52
areaconst 40 86 97.59 932 0.54
banios 0 2 2.54 10 0.36
habitaciones 0 3 2.95 9 0.21
parqueaderos_imp 0 0 0.15 1 2.40

Los apartamentos que se encuentran en la zona Sur con precios de hasta $850 millones, tiene como mediana un área costruida de 260\(m^2\), una cantidad de 2 baños, 3 habitaciones y como máximo 1 parqueadero por vivienda. Siguiendo las características del apartamento que el cliente desea, tanto el área, como el número de baños y el de habitaciones es mayor que la mitad de las viviendas de esta zona Sur. Por lo que las viviendas ofertadas escogidas se encuentran con mejores atributos que las demás y a un precio accequible.

# Estadísticas descriptivas de viviendas con precios de hasta $350 millones; var cualitativas

base2_850 %>% group_by(estrato) %>% count(estrato)
base2_850 %>% group_by(COMUNA) %>% count(COMUNA)
base2_850 %>% group_by(piso_2) %>% count(piso_2)

En cuanto al estrato, las viviendas de hasta $850 millones de la zona Sur son caracterizadas por ser de estrato 5 en su mayoría y pertenecer por ende a la Comuna 17 y donde las viviendas ofertadas se encuentran con mayor frecuencia en el piso 4 y 5.

Para conocer la ubicación de estas viviendas, se grafica las ubicaciones de ellas en el mapa de Cali.

# Mapa con mejores ofertas

datos_filtrados <- base2 %>% filter(preciom <= 850)

mejores_ofertas <- datos_filtrados %>% filter(id %in% c(6723, 3603, 3827, 5693, 3848))

fig <- plot_ly(data = datos_filtrados, 
               lat = ~latitud, 
               lon = ~longitud, 
               type = 'scattermapbox', 
               mode = 'markers', 
               marker = list(size = 10, opacity = 0.7, color = 'blue'), 
               text = ~paste(
                 'ID:', id, '<br>',
                 'Precio:', preciom, 'millones<br>',
                 'Área Construida:', areaconst, 'm²<br>',
                 'Baños:', banios, '<br>',
                 'Habitaciones:', habitaciones, '<br>',
                 'Barrio:', barrio, '<br>',
                 'Estrato:', estrato
               )) %>%
  add_trace(data = mejores_ofertas, 
            lat = ~latitud, 
            lon = ~longitud, 
            type = 'scattermapbox', 
            mode = 'markers', 
            marker = list(size = 15, color = 'red'), 
            text = ~paste(
              'ID:', id, '<br>',
              'Precio:', preciom, 'millones<br>',
              'Área Construida:', areaconst, 'm²<br>',
              'Baños:', banios, '<br>',
              'Habitaciones:', habitaciones, '<br>',
              'Barrio:', barrio, '<br>',
              'Estrato:', estrato
            ),
            name = 'Mejor oferta') %>%
  layout(
    mapbox = list(
      style = 'open-street-map',
      center = list(lat = mean(datos_filtrados$latitud), lon = mean(datos_filtrados$longitud)),
      zoom = 12
    ),
    title = 'Viviendas con presupuesto igual o menor a $850 millones',
    hovermode = 'closest'
  )

fig

2.7. Entrenamiento del modelo de regresión lineal múltiple.

2.7.1. Modelo.

Como metodología alternativa, se realiza el entrenamiento del modelo de regresión lineal múltiple son una partición aleatoria donde el 70% de los datos serán los de entrenamiento y el 30% restante serán los datos de prueba.

# Entrenamiento del modelo de regresión lineal  múltiple.

library(caret)

set.seed(123)
trainIndex <- createDataPartition(base2$preciom, p = 0.7, list = FALSE)
trainData <- base1[trainIndex, ]
testData <- base1[-trainIndex, ]

mod_2_train <- lm(preciom ~ areaconst + estrato + + parqueaderos_imp + habitaciones + banios, 
                  data = trainData)

summary(mod_2_train)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + +parqueaderos_imp + 
##     habitaciones + banios, data = trainData)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -952.91  -70.89  -18.26   49.30  810.45 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       46.27751   26.87452   1.722 0.085849 .  
## areaconst          0.82114    0.05682  14.451  < 2e-16 ***
## estrato4          75.15513   23.39021   3.213 0.001420 ** 
## estrato5         131.30535   22.82784   5.752 1.76e-08 ***
## estrato6         331.46502   36.07607   9.188  < 2e-16 ***
## parqueaderos_imp  -3.90751   17.66421  -0.221 0.825042    
## habitaciones      -0.62947    5.68583  -0.111 0.911903    
## banios            25.12116    7.34092   3.422 0.000686 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 150.2 on 398 degrees of freedom
##   (967 observations deleted due to missingness)
## Multiple R-squared:  0.683,  Adjusted R-squared:  0.6774 
## F-statistic: 122.5 on 7 and 398 DF,  p-value: < 2.2e-16

Con el modelo entrenado se observan diferencias en los coeficientes de cada una de las variables con respecto al modelo sin entrenar. Esta vez, el área construida, el estrato 6 y el número de baños siguen aportando significativamente a la predicción del precio de la vivienda, pero con un peso distinto. Por cada aumento en \(m^2\) del área de la vivienda, el precio de ella aumenta en promedio $0.82 millones. Para el estrato 6, éste aumenta el precio promedio en $331 millones si se compara con el estrato 3 y por cada unidad de baño más, el precio promedio del apartamento tiene un valor de $25 millones más.

La estimación obtuvo además que el estrato 5 es significativo cuando con el modelo sin entrenar no lo estaba, en este caso aumenta el precio promedio en $131 millones con respecto al estrato 3. De igual manera, se evidencia que el modelo con entrenamiento dejó de tener como variables significativas la cantidad de parqueaderos y las habitaciones.

Este entrenamiento resulta ser más congruente con lo encontrado en las correlaciones realizadas vs el precio del apartamento, donde la cantidad de parqueaderos y de habitaciones no obtuvieron coeficientes de correlación que indicaran una relación fuerte con la variable respuesta (\(\rho=-0.35\) y \(\rho=0.42\) respectivamente).

Luego, la varianza explicada fue de \(R^2_{adj}=0.67\), más baja que en la regresión sin entrenamiento, que aunque sigue siendo alta, se podría mejorar con las recomendaciones descritas en la estimación del modelo de regresión (Sección 2.3).

2.7.2. Predicción con datos de prueba.

Para conocer si el modelo entrenado tiene buen rendimiento, se predicen los precios de cada apartamento y se compara con el valor real de este.

# Predicción con datos de prueba

predictions <- predict(mod_2_train, newdata = testData)

head(data.frame(Predicted = predictions, Actual = testData$preciom))

Revisando ligeramente la tabla de las predicciones del precio y de su respectivo valor real, se evidencia que existe una diferencia grande estre ellas dos.

2.7.3. Métricas de rendimiento.

Se calculan las métricas de Error Cuadrático Medio, Error Absoluto Medio y Coeficiente de determinación \(R^2\) para evaluar el rendimiento de la predicción del modelo entrenado.

# Error Cuadrático Medio (MSE)
mse <- mean((testData$preciom - predictions)^2)

# Error Absoluto Medio (MAE)
mae <- mean(abs(testData$preciom - predictions))

# Coeficiente de Determinación (R²)
sst <- sum((testData$preciom - mean(testData$preciom))^2)  # Suma de cuadrados total
sse <- sum((testData$preciom - predictions)^2)         # Suma de cuadrados del error
r_squared <- 1 - (sse / sst)

cat("Error Cuadrático Medio (MSE) es:", mse, "\n")
## Error Cuadrático Medio (MSE) es: 35959.46
cat("Error Absoluto Medio (MAE) es:", mae, "\n")
## Error Absoluto Medio (MAE) es: 103.215
cat("Coeficiente de Determinación (R2) es:", r_squared, "\n")
## Coeficiente de Determinación (R2) es: 0.6266525

Siguiendo los anteriores cálculos, el MSE de 35959.46 evidencia que, en promedio, el cuadrado de los errores de predicción es de 35959.46 millones de pesos. Por otro lado el MAE, con un valor de 103.2 millones de pesos indica que, en promedio, las predicciones del modelo están a 114.61 millones de pesos de distancia de los valores reales. Y por último, el \(R^2\) de 0.63 indica que el modelo explica el 63% de la variabilidad en los precios de las viviendas, el cual no es muy alto.