Para responder al requerimiento de María y facilitar la comprensión del proceso de análisis de la compra de las dos viviendas, vamos a desarrollar un código en R paso a paso. Este código incluirá comentarios para cada sección y línea de código, explicando el propósito y la función de cada uno. Por cuestiones de espacio y enfoque, presentaré un esquema general del código que deberías seguir para cada uno de los pasos solicitados
#Carga de librerías a utilizar en el desarrollo del informe ejecutivo
# devtools::install_github("dgonxalex80/paqueteMODELOS", force = TRUE)
library(paqueteMET)
suppressMessages(library(paqueteMET))
suppressMessages(library(knitr))
suppressMessages(library(dplyr))
suppressMessages(library(ggplot2))
knitr::opts_chunk$set(echo = TRUE)
suppressMessages(library(tidyverse))
suppressMessages(library(sp))
suppressMessages(library(maps))
suppressMessages(library(plotly))
# Descarte de registro con N.A.
vivienda_sin_na <- na.omit(vivienda)
na_count <- vivienda_sin_na %>%
summarise(across(everything(), ~sum(is.na(.))))
# Ver los resultados
print(na_count)
## # A tibble: 1 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 0 0 0 0 0 0 0 0 0
## # ℹ 4 more variables: tipo <int>, barrio <int>, longitud <int>, latitud <int>
A continuación, se detallan los valores promedios de longitud y latitud por Zona de la ciudad de Cali, para tener una referencia, al momento de entrar a evaluar cada requerimiento en particular:
Los rangos promedio de longitud y latitud por cada zona son los siguientes:
Longitud promedio: -76.5200
Latitud promedio: 3.4427
Longitud promedio: -76.5283
Latitud promedio: 3.4154
Longitud promedio: -76.5257
Latitud promedio: 3.4269
Longitud promedio: -76.5134
Latitud promedio: 3.4170
Longitud promedio: -76.5150
Latitud promedio: 3.4149
A continuación, se presentará un gráfico de densidad y de ubicación, para poder visualizar, en donde se encuentran ubicados los inmuebles, y donde se concentran la mayor cantidad:
ggplot(vivienda_sin_na, aes(x = longitud, y = latitud)) +
geom_point(alpha = 0.5) + # Puntos semitransparentes para visualizar la densidad
stat_density_2d(aes(fill = ..level..), geom = "polygon") +
scale_fill_viridis_c() + # Utilizar una escala de color
labs(fill = "Densidad") + # Etiqueta para la barra de color
theme_minimal() + # Un tema minimalista para el gráfico
ggtitle("Densidad de Viviendas por Zona") # Título del gráfico
A continuación, se detalla el análisis de la gráfica:
Puntos Negros: Representa la ubicación de una vivienda individual según su longitud (eje x) y latitud (eje y).
Áreas de Color: Muestra las regiones con mayor o menor número de viviendas.
Paleta de Colores: El púrpura oscuro representa áreas de baja densidad, mientras que el amarillo representa las áreas de mayor densidad.
Una vez presentada la ubicación general de todos los registros, procedemos a evaluar cada requerimiento particular:
Características del inmueble:
Como primera medida, se realizará una proceso de filtrado a la base de datos original, para establecer un alcance, acorde a los requerimientos presentados:
#PASO1: Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?).
# Filtrar las casas en la zona norte
base1 <- vivienda_sin_na %>%
filter(tipo == 'Casa' & zona == 'Zona Norte')
# Mostrar los primeros 3 registros
head(base1, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4460 Zona N… 02 4 625 355 3 5 5
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
print(base1,3)
## # A
## # tibble:
## # 254
## # ×
## # 13
## # ℹ 244 more rows
## # ℹ 13 more variables: id <dbl>, zona <chr>, piso <chr>, estrato <dbl>, preciom <dbl>, areaconst <dbl>, parqueaderos <dbl>, banios <dbl>, habitaciones <dbl>, tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Generar un mapa con los puntos de las bases
# Suponiendo que tenemos las coordenadas geográficas
ggplot(base1, aes(x = longitud, y = latitud)) +
geom_point(color = "red") +
ggtitle("Ubicación de las casas en la Zona Norte") +
theme_minimal()
Con base en el gráfico presentado, le presentamos el siguiente análisis:
La descripción de la Zona Norte muestra que la longitud varía entre -76.58915 y -76.46745 y la latitud entre 3.33308 y 3.49770. Estos rangos deben ser consistentes con la ubicación geográfica de la Zona Norte dentro de la ciudad.
Comparando estos rangos con los de otras zonas, parece que hay una superposición en los rangos de longitud y latitud entre las diferentes zonas. Por ejemplo, la Zona Centro, Oeste, Oriente y Sur tienen rangos de longitud y latitud que se superponen con los de la Zona Norte. Esto significa que algunos de los puntos mostrados en la gráfica podrían estar ubicados en zonas adyacentes si consideramos solo las coordenadas geográficas.
Por último, presentamos el gráfico de densidad de la ubicación: Zona Norte:
ggplot(base1, aes(x = longitud, y = latitud)) +
geom_point(alpha = 0.5) + # Puntos semitransparentes para visualizar la densidad
stat_density_2d(aes(fill = ..level..), geom = "polygon") +
scale_fill_viridis_c() + # Utilizar una escala de color
labs(fill = "Densidad") + # Etiqueta para la barra de color
theme_minimal() + # Un tema minimalista para el gráfico
ggtitle("Densidad de Viviendas por Zona") # Título del gráfico
A continuación, procedemos a realizar un análisis exploratorio de datos enfocado en la correlación entre el precio de la casa, en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda:
#PASO2: Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.
matriz_correlacion <- base1 %>%
select(preciom, areaconst, estrato, banios, habitaciones) %>%
cor()
plot_ly(z = matriz_correlacion, x = colnames(matriz_correlacion), y = rownames(matriz_correlacion), type = "heatmap", colorscale = "Viridis") %>%
layout(title = "Matriz de Correlación de Precio y Características de Viviendas")
A continuación, presentamos el análisis del gráfico de correlación:
Correlación Positiva Fuerte: Las celdas con colores más cercanos al amarillo indican una correlación positiva fuerte. Si alguna de estas celdas corresponde al par (preciom, areaconst) o (preciom, estrato), esto sugeriría que a medida que el área construida o el estrato de la vivienda aumenta, también lo hace el precio, lo cual es una tendencia esperada en el mercado inmobiliario.
Correlación Moderada: Colores intermedios, como el verde, podrían indicar una correlación moderada. Esto podría sugerir que variables como el número de baños y habitaciones tienen un impacto notable, pero no tan significativo como el área construida o el estrato, en el precio de la vivienda.
-Correlaciones Bajas o Nulas: Las celdas con colores más oscuros indican una correlación baja o nula.
Una vez observada la correlación entre variables, se procede a presentar los gráficos de correlación de la variable precio en función de cada una de las características del inmueble:
# Genera los subgráficos
p1 <- plot_ly(base1, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers', name = "Área Construida") %>%
layout(title = 'Área Construida vs Precio', margin = list(b = 40))
p2 <- plot_ly(base1, x = ~estrato, y = ~preciom, type = 'scatter', mode = 'markers', name = "Estrato") %>%
layout(title = 'Estrato vs Precio', margin = list(b = 40))
p3 <- plot_ly(base1, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers', name = "Número de Baños") %>%
layout(title = 'Número de Baños vs Precio', margin = list(t = 40))
p4 <- plot_ly(base1, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers', name = "Número de Habitaciones") %>%
layout(title = 'Número de Habitaciones vs Precio', margin = list(t = 40))
# Combinar los gráficos en un solo gráfico con 4 subgráficos
subplot(
p1, p2, p3, p4,
nrows = 2,
shareX = FALSE,
shareY = FALSE,
titleX = TRUE,
titleY = TRUE,
margin = 0.09,
heights = c(0.5, 0.5)
) %>% layout(title = 'Comparación de Características vs Precio')
Análisis de correlación por característica:
Área Construida vs Precio: Relación positiva entre el área construida de las viviendas y sus precios. Las viviendas con mayor área tienden a tener precios más altos. Por lo tanto, el área construida es un factor significativo en la valoración de las viviendas. Sin embargo, hay una gran dispersión en los datos, lo que sugiere que otros factores también influyen en el precio.
Estrato vs Precio: El precio de la vivienda aumenta con el estrato, lo cual es consistente con la expectativa de que las viviendas en estratos más altos tienen precios más altos. Los puntos se agrupan según el estrato, lo que indica niveles de precios distintos para cada estrato
Número de Baños vs Precio: Las viviendas con más baños tienden a tener precios más altos, aunque la relación no es tan fuerte como con el área construida o el estrato
Número de Habitaciones vs Precio: Similar al número de baños, las viviendas con más habitaciones tienden a ser más caras. La relación es más dispersa para viviendas con un número mayor de habitaciones.
A continuación, procedemos a realizar una estimación de un modelo de regresión lineal múltiple, para validar si la valoración estadística del mismo, permite determinar la posible acertividad y eficiencia en la estimación de posibles precios de viviendas:
#PASO3: Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).
# Estimación del modelo de regresión lineal
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base1)
# Resumen del modelo para interpretación de coeficientes y R2
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = base1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -761.11 -84.10 -16.36 52.22 925.67
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -245.62878 60.86958 -4.035 7.27e-05 ***
## areaconst 0.66444 0.06703 9.913 < 2e-16 ***
## estrato 85.58184 13.17690 6.495 4.51e-10 ***
## habitaciones 8.91428 7.14129 1.248 0.213
## parqueaderos 28.05949 6.77575 4.141 4.74e-05 ***
## banios 11.49860 9.51130 1.209 0.228
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 152.8 on 248 degrees of freedom
## Multiple R-squared: 0.5952, Adjusted R-squared: 0.587
## F-statistic: 72.92 on 5 and 248 DF, p-value: < 2.2e-16
A continuación, presentamos la interpretación de los estadísticos del modelo de regresión lineal múltiple obtenido:
Interpretación de coeficientes:
Intercept (-245.62878): Valor estimado del precio de la vivienda cuando todas las variables independientes son cero, lo cual no es lógico en el contexto real porque no se puede tener una vivienda con área cero, estrato cero, etc. Este valor es estadísticamente significativo con un valor p muy bajo, lo que indica que es diferente de cero.
areaconst (0.66444): Por cada metro cuadrado adicional de área construida, el precio de la vivienda aumenta en promedio 0.66444 millones de pesos. Este coeficiente es estadísticamente significativo y lógico, ya que se espera que una vivienda más grande tenga mayor precio.
estrato (85.58184): Por cada nivel adicional de estrato, el precio de la vivienda aumenta en promedio 85.58184 millones de pesos. Este resultado es estadísticamente significativo y tiene sentido, ya que los estratos más altos suelen asociarse con mejores servicios y localizaciones más deseables.
habitaciones (8.91428): El número de habitaciones tiene un coeficiente positivo, lo que sugiere que a medida que aumenta el número de habitaciones, también lo hace el precio de la vivienda. Sin embargo, este coeficiente no es estadísticamente significativo (p > 0.05), lo que indica que no hay suficiente evidencia para afirmar que el número de habitaciones afecta el precio de la vivienda en esta muestra.
parqueaderos (28.05949): Por cada parqueadero adicional, el precio de la vivienda aumenta en promedio 28.05949 millones de pesos. Este coeficiente es estadísticamente significativo y es razonable, ya que los parqueaderos adicionales son una comodidad valorada.
banios (11.49860): Cada baño adicional parece aumentar el precio de la vivienda en 11.49860 millones de pesos. Sin embargo, este efecto no es estadísticamente significativo (p > 0.05), sugiriendo que no hay evidencia clara en esta muestra de que el número de baños tenga un impacto en el precio.
Interpretación del Ajuste del Modelo:
Multiple R-squared (0.5952): Alrededor del 59.52% de la variabilidad en el precio de la vivienda puede ser explicada por el modelo. Lo que indica que el modelo tiene un buen ajuste.
Adjusted R-squared (0.587): Este valor ajusta el R-squared basándose en el número de predictores en el modelo y el tamaño de la muestra, y sigue siendo alto, lo que confirma que el modelo es adecuado.
F-statistic: El valor de la prueba F es muy alto y el valor p asociado es menor que 2.2e-16, lo que indica que el modelo es estadísticamente significativo en su conjunto.
Implicaciones y Mejoras:
Los resultados indican que el área construida, el estrato y el número de parqueaderos son factores importantes que influyen en el precio de una vivienda. Para mejorar el modelo, se podría:
A continuación, se presenta el diagnóstico del modelo para la validación de supuestos:
#PASO4: Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).
# Diagnóstico del modelo para verificar supuestos
par(mfrow = c(2, 2))
plot(modelo)
Aquí está la interpretación de cada uno:
Residuales vs Valores Ajustados: No se identifica un patrón claro y definido, lo cual es bueno, ya que indica que no hay estructuras obvias no capturadas por el modelo. Sin embargo, hay algunos puntos con residuos altos, lo que podría indicar outliers o que el modelo no es perfecto para esos casos. Sugerencia: Investigar los casos con residuos altos para entender si se deben a datos anómalos o si hay un patrón no capturado por el modelo. Considerar incluir otras variables explicativas si es necesario.
Q-Q Plot de los Residuos: Los residuos siguen de cerca la línea recta en el medio del gráfico, pero desvían en los extremos. Esto sugiere que los residuos tienen colas más pesadas que una distribución normal, lo que puede ser un signo de outliers o que la relación no es completamente lineal.Sugerencia: Si los residuos tienen colas pesadas, se podría considerar la posibilidad de que haya outliers significativos que afecten al modelo. Estos datos podrían ser examinados más detenidamente para ver si deben ser excluidos o si se necesita un modelo diferente que maneje mejor los outliers.
Gráfico de Ubicación-Escala: Hay un ligero incremento en la dispersión de los residuos estandarizados a medida que aumentan los valores ajustados, lo que podría indicar heterocedasticidad. Esto significa que la varianza de los errores no es constante. Sugerencia: Si se confirma la heterocedasticidad, se podrían aplicar transformaciones a la variable de respuesta (como el logaritmo) o se podrían utilizar errores estándar robustos o modelos ponderados para abordar este problema
Residuos vs Apalancamiento (Leverage): La mayoría de los puntos tienen un bajo apalancamiento, pero hay unos pocos puntos fuera de las líneas de distancia de Cook, lo que sugiere que podrían ser puntos de influencia. Sugerencia: Identificar y examinar los puntos con alto apalancamiento y residuos grandes para decidir si representan datos válidos o si son anomalías. Si son errores o datos atípicos no representativos, podrían ser removidos. Si son válidos, se puede considerar un modelo de regresión robusta que minimice su influencia.
Teniendo en cuenta el modelo descrito, se procede a establecer una predicción del precio acorde a las características del primer requerimiento:
#PASO5: Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.
# Predicción usando el modelo estimado
prediccion1 <- predict(modelo, newdata = data.frame(areaconst = 200, estrato = 4, habitaciones = 4, parqueaderos = 1, banios = 2))
# Mostrar la predicción
prediccion1
## 1
## 316.3002
El valor de la predicción correspoden a 316.3 Millones de pesos. El cual, está cubierto a través del crédito preaprobado que maneja actualmente.
A continuación, se procede a filtrar la base de datos acorde a todos las características del primer requerimiento:
#PASO6: Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.
# Paso 1: Predecir precios usando el modelo
base1$precio_predicho <- predict(modelo, newdata = base1)
# Paso 2: Filtrar viviendas que cumplen con los criterios de la vivienda 1 y están dentro del presupuesto
ofertas_potenciales <- base1 %>%
filter(tipo == "Casa",
areaconst >= 200,
parqueaderos >= 1,
banios >= 2,
habitaciones >= 4,
estrato %in% c(4, 5),
preciom <= 350) %>%
arrange((preciom)) # Ordenar por precio de menor a mayor
# Paso 3: Seleccionar 5 ofertas potenciales
print(ofertas_potenciales, n = Inf)
## # A tibble: 22 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1020 Zona … 02 4 230 250 2 3 5
## 2 7432 Zona … 01 4 260 280 2 4 6
## 3 1914 Zona … 02 5 300 205 2 5 6
## 4 4458 Zona … 02 4 315 270 2 4 4
## 5 1343 Zona … 02 5 320 200 2 4 4
## 6 3053 Zona … 02 5 320 230 2 4 4
## 7 952 Zona … 02 4 330 275 2 3 5
## 8 1108 Zona … 02 4 330 260 1 3 4
## 9 4267 Zona … 01 5 335 202 1 4 5
## 10 4800 Zona … 01 5 340 250 2 4 4
## 11 3101 Zona … 02 5 340 355 2 5 8
## 12 1887 Zona … 01 5 340 203 2 3 4
## 13 2544 Zona … 01 4 340 264. 2 4 4
## 14 7470 Zona … 02 4 340 264 2 5 7
## 15 4483 Zona … 02 5 342 250 1 4 6
## 16 4210 Zona … 01 5 350 200 3 3 4
## 17 4209 Zona … 02 5 350 300 3 5 6
## 18 4422 Zona … 02 5 350 240 2 3 6
## 19 819 Zona … 02 5 350 264 2 3 4
## 20 937 Zona … 02 4 350 280 2 3 4
## 21 5031 Zona … 03 4 350 350 1 4 5
## 22 1842 Zona … 02 5 350 240 2 3 4
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_predicho <dbl>
Se observa, que existen un total de 22 inmuebles en la base de datos que cumplen con los requerimientos establecidos. Por lo tanto, y teniendo en cuenta que la predicción del modelo estableció un valor aproximado del inmueble de 316.3 Millones de pesos, recomendamos las 5 ofertas de inmuebles que están más cercanos a este valor y cumplen con todos los requerimientos:
# Asumiendo que 'ofertas_potenciales' es tu dataframe y ya contiene la columna 'preciom'
valor_referencia <- 316.3
# Añadir una nueva columna con la diferencia absoluta entre 'preciom' y el valor de referencia
ofertas_potenciales <- ofertas_potenciales %>%
mutate(diferencia_abs = abs(preciom - valor_referencia))
# Ordenar el dataframe por la diferencia absoluta y seleccionar los 5 registros superiores
ofertas_cercanas <- ofertas_potenciales %>%
arrange(diferencia_abs) %>%
head(5)
# Mostrar los resultados
print(ofertas_cercanas)
## # A tibble: 5 × 15
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4458 Zona N… 02 4 315 270 2 4 4
## 2 1343 Zona N… 02 5 320 200 2 4 4
## 3 3053 Zona N… 02 5 320 230 2 4 4
## 4 952 Zona N… 02 4 330 275 2 3 5
## 5 1108 Zona N… 02 4 330 260 1 3 4
## # ℹ 6 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_predicho <dbl>, diferencia_abs <dbl>
Teniendo en cuenta la selección de las 5 sugerencias potenciales que cumplen con su total requerimiento, procedemos a mostrar su ubicación para mayyor información:
ggplot(ofertas_cercanas, aes(x = longitud, y = latitud)) +
geom_point(color = "red") +
ggtitle("Ubicación de las casas en la Zona Norte") +
theme_minimal()
library(leaflet)
# Coordenadas aproximadas del centro de Cali, Colombia
cali_lat <- 3.4516
cali_lon <- -76.53198
# Crear un mapa con leaflet centrado en Cali
leaflet() %>%
addTiles() %>% # Añadir mapa base
setView(lng = cali_lon, lat = cali_lat, zoom = 12) %>% # Centrar en Cali con un nivel de zoom adecuado
addMarkers(lng = ofertas_cercanas$longitud, lat = ofertas_cercanas$latitud, popup = "Oferta cercana") # Añadir marcadores para ofertas_cercanas