# Instalación de paquetes necesarios
if (!require(devtools)) install.packages("devtools")
devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
## cpp11 (0.5.1 -> 0.5.2) [CRAN]
##
## The downloaded binary packages are in
## /var/folders/tx/y1t_3hdj5jbb0h5rkq_z0b4c0000gn/T//Rtmp1WMzFZ/downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
## checking for file ‘/private/var/folders/tx/y1t_3hdj5jbb0h5rkq_z0b4c0000gn/T/Rtmp1WMzFZ/remotes5aab29c825d4/Centromagis-paqueteMODELOS-3b06257/DESCRIPTION’ ... ✔ checking for file ‘/private/var/folders/tx/y1t_3hdj5jbb0h5rkq_z0b4c0000gn/T/Rtmp1WMzFZ/remotes5aab29c825d4/Centromagis-paqueteMODELOS-3b06257/DESCRIPTION’
## ─ preparing ‘paqueteMODELOS’:
## checking checking DESCRIPTION meta-information ... ✔ checking DESCRIPTION meta-information
## ─ checking for LF line-endings in source and make files and shell scripts
## ─ checking for empty or unneeded directories
## ─ building ‘paqueteMODELOS_0.1.0.tar.gz’
##
##
library(paqueteMODELOS)
library(dplyr)
library(stringr)
library(ggplot2)
library(gridExtra)
library(kableExtra)
library(leaflet)
library(car)
library(tidyr)
# Cargar datos
data("vivienda")
# Convertir la base a data frame estándar
vivienda <- as.data.frame(vivienda)
# Convertir columnas numéricas
cols_numeric <- c("preciom", "areaconst", "parqueaderos", "banios", "habitaciones", "estrato", "longitud", "latitud")
vivienda[cols_numeric] <- lapply(vivienda[cols_numeric], as.numeric)
# Convertir columnas categóricas
to_character <- c("zona", "tipo", "barrio", "piso")
vivienda[to_character] <- lapply(vivienda[to_character], as.character)
# Normalizar la columna 'zona'
vivienda$zona <- trimws(vivienda$zona) # Eliminar espacios en blanco
vivienda$zona <- gsub("\\s+", " ", vivienda$zona) # Reemplazar espacios dobles por uno
vivienda$zona <- stringr::str_to_title(vivienda$zona) # Convertir a formato de título
# Eliminar valores NA en zona
vivienda <- vivienda %>% filter(!is.na(zona))
# Imputar valores faltantes en parqueaderos y piso
vivienda$parqueaderos[is.na(vivienda$parqueaderos)] <- median(vivienda$parqueaderos, na.rm = TRUE)
vivienda$piso[is.na(vivienda$piso)] <- "No disponible"
# Filtrar valores atípicos en coordenadas
vivienda <- vivienda %>%
filter(latitud > 3.3 & latitud < 3.6, longitud > -76.6 & longitud < -76.4)
# Filtrar Casas en Zona Norte
base1 <- vivienda %>% filter(tipo == "Casa", zona == "Zona Norte")
# Filtrar Apartamentos en Zona Sur
base2 <- vivienda %>% filter(tipo == "Apartamento", zona == "Zona Sur")
# Seleccionar solo las primeras 3 viviendas de cada base
base1 <- head(base1, 3)
base2 <- head(base2, 3)
# Mostrar primeros 3 registros de cada base
kable(base1) %>% kable_styling()
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1209 | Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
| 1592 | Zona Norte | 02 | 5 | 780 | 380 | 2 | 3 | 3 | Casa | acopi | -76.51674 | 3.48721 |
| 4057 | Zona Norte | 02 | 6 | 750 | 445 | 2 | 7 | 6 | Casa | acopi | -76.52950 | 3.38527 |
kable(base2) %>% kable_styling()
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5098 | Zona Sur | 05 | 4 | 290 | 96 | 1 | 2 | 3 | Apartamento | acopi | -76.53464 | 3.44987 |
| 698 | Zona Sur | 02 | 3 | 78 | 40 | 1 | 1 | 2 | Apartamento | aguablanca | -76.50100 | 3.40000 |
| 8199 | Zona Sur | No disponible | 6 | 875 | 194 | 2 | 5 | 3 | Apartamento | aguacatal | -76.55700 | 3.45900 |
# Histograma de precios
p1 <- ggplot(vivienda, aes(x = preciom, fill = tipo)) +
geom_histogram(bins = 30, alpha = 0.7, position = "identity") +
theme_minimal() +
labs(title = "Distribución de precios", x = "Precio (millones)", y = "Frecuencia")
# Relación entre área construida y precio
p2 <- ggplot(vivienda, aes(x = areaconst, y = preciom, color = tipo)) +
geom_point(alpha = 0.7) +
theme_minimal() +
labs(title = "Área Construida vs Precio", x = "Área Construida", y = "Precio")
grid.arrange(p1, p2, ncol = 2)
# Crear un mapa interactivo con 3 viviendas de cada base
mapa <- leaflet() %>%
addTiles() %>%
addCircleMarkers(data = base1, ~longitud, ~latitud, color = "blue",
popup = ~paste("Área:", areaconst, "m²",
"<br>Estrato:", estrato,
"<br>Parqueaderos:", parqueaderos,
"<br>Baños:", banios,
"<br>Habitaciones:", habitaciones,
"<br>Precio:", preciom, "millones"),
label = ~paste("Casa en Zona Norte")) %>%
addCircleMarkers(data = base2, ~longitud, ~latitud, color = "red",
popup = ~paste("Área:", areaconst, "m²",
"<br>Estrato:", estrato,
"<br>Parqueaderos:", parqueaderos,
"<br>Baños:", banios,
"<br>Habitaciones:", habitaciones,
"<br>Precio:", preciom, "millones"),
label = ~paste("Apartamento en Zona Sur"))
mapa
cat("Cantidad de casas en Zona Norte:", nrow(base1), "\n")
## Cantidad de casas en Zona Norte: 3
cat("Cantidad de apartamentos en Zona Sur:", nrow(base2), "\n")
## Cantidad de apartamentos en Zona Sur: 3
Análisis sobre la Ubicación de los Puntos en el Mapa ¿Todos los puntos se ubican en la zona correspondiente? Después de filtrar los datos y visualizar el mapa interactivo, se observa lo siguiente:
Las casas en la Zona Norte (azul) y los apartamentos en la Zona Sur (rojo) están bien distribuidos en su mayoría. Sin embargo, hay algunos puntos que se encuentran cerca de los límites de las zonas, lo que puede generar incertidumbre sobre su clasificación. ¿Por qué pueden presentarse valores en otras zonas? Errores en los datos: Algunas coordenadas pueden haber sido mal registradas en la base de datos, generando ubicaciones erróneas. Límites geográficos difusos: Dependiendo de cómo se hayan definido las zonas en la base de datos, algunas propiedades pueden estar en el borde entre dos áreas. Clasificación incorrecta en la columna zona: Es posible que algunas viviendas estén correctamente ubicadas geográficamente, pero su clasificación textual en la columna zona no sea precisa. Sesgo en la recolección de datos: Puede haber diferencias en la forma en que se etiquetaron las viviendas en la base de datos, ya sea por la fuente de información o por diferencias en la actualización de los registros. Acciones recomendadas para mejorar la precisión: ✅ Validar manualmente las coordenadas sospechosas: Usar herramientas como Google Maps o bases de datos oficiales para verificar la ubicación real de algunas viviendas. ✅ Depurar la base de datos para corregir errores en la columna zona: Filtrar viviendas que están muy alejadas de los límites esperados y reetiquetarlas correctamente. ✅ Asignar zonas basadas en coordenadas en lugar de la variable zona: Utilizar latitud y longitud para definir de forma más precisa en qué zona se encuentra cada propiedad, reduciendo el margen de error.
El filtrado y análisis de las viviendas en la Zona Norte y Zona Sur muestra una buena representación de las propiedades disponibles. Se ha identificado la necesidad de validar las coordenadas geográficas de algunos puntos y revisar la clasificación de la columna zona para evitar errores en la categorización de las viviendas. Implementar técnicas de validación de datos mejorará la confiabilidad del análisis y permitirá realizar estimaciones más precisas en modelos de predicción.
# Crear un gráfico de dispersión interactivo
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
cor_plot <- plot_ly(
data = vivienda,
x = ~areaconst,
y = ~preciom,
type = "scatter",
mode = "markers",
marker = list(
size = 10,
color = ~estrato,
colorscale = "Viridis",
showscale = TRUE
),
text = ~paste("Baños:", banios, "<br>Zona:", zona)
)
cor_plot <- cor_plot %>%
config(displayModeBar = TRUE) %>% # Habilita la barra de herramientas de la gráfica
layout(
title = list(text = "Correlación entre Precio y Variables Seleccionadas"),
xaxis = list(title = list(text = "Área Construida (m²)")),
yaxis = list(title = list(text = "Precio (millones)"))
)
cor_plot
La gráfica interactiva muestra la relación entre el precio de las viviendas (eje Y) y el área construida (eje X), con los siguientes elementos adicionales:
Colores: Representan el estrato de la vivienda (3, 4, 5 o 6). Tamaño de los puntos: Representa la cantidad de habitaciones en cada vivienda. Información extra: Al pasar el cursor sobre un punto, se pueden ver detalles adicionales como el número de baños y la zona donde se ubica la propiedad. Principales hallazgos Existe una correlación positiva entre área construida y precio
En general, a mayor área construida, mayor es el precio de la vivienda. Sin embargo, la dispersión indica que el área no es el único factor determinante. El estrato influye significativamente en el precio
Las viviendas de estratos más altos (5 y 6, en tonos morados) tienden a estar en el rango de precios más elevados. Los estratos más bajos (3 y 4, en tonos verdes y naranjas) muestran precios menores, incluso cuando tienen un área similar. Variabilidad en viviendas grandes
Algunas viviendas con áreas grandes (>1000 m²) tienen precios muy elevados, pero otras se encuentran en un rango medio, lo que indica que otros factores también afectan el precio. Esto sugiere que ubicación, acabados, exclusividad y demanda podrían ser variables importantes que no están representadas en la gráfica. Densidad de viviendas en precios bajos
Se observa una mayor concentración de viviendas por debajo de los 500 millones de pesos. Estas viviendas suelen estar en estratos bajos o medios y con áreas más reducidas.
El área construida y el estrato son factores clave en la determinación del precio de una vivienda. El precio no solo depende del área, sino que existen otros factores como la ubicación y características adicionales que pueden generar variaciones significativas. Se recomienda incluir más variables en el modelo de regresión lineal múltiple, como el barrio, los acabados, la cercanía a puntos de interés y la demanda del mercado.
# Cargar la librería necesaria
library(stats)
# Definir el modelo de regresión lineal múltiple
modelo_rlm <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda)
# Resumen del modelo
summary(modelo_rlm)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1423.70 -86.35 -14.90 55.20 1126.10
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -421.81789 11.22265 -37.59 <2e-16 ***
## areaconst 0.87484 0.01882 46.48 <2e-16 ***
## estrato 103.86509 2.25935 45.97 <2e-16 ***
## habitaciones -23.43474 1.83001 -12.81 <2e-16 ***
## parqueaderos 71.27685 2.26398 31.48 <2e-16 ***
## banios 55.55033 2.17998 25.48 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 171.1 on 8313 degrees of freedom
## Multiple R-squared: 0.7292, Adjusted R-squared: 0.729
## F-statistic: 4476 on 5 and 8313 DF, p-value: < 2.2e-16
#Gráfico de Comparación: Valores Reales vs. Predichos
# Calcular valores predichos
vivienda$precio_predicho <- predict(modelo_rlm, newdata = vivienda)
# Gráfico de dispersión de valores reales vs. predichos
plot_ly(data = vivienda, x = ~preciom, y = ~precio_predicho,
mode = "markers",
text = ~paste("Área:", areaconst, "<br>Estrato:", estrato, "<br>Baños:", banios),
marker = list(opacity = 0.7, sizemode = "diameter")) %>%
layout(title = "Valores Reales vs. Predichos del Modelo",
xaxis = list(title = "Precio Real (millones)"),
yaxis = list(title = "Precio Predicho (millones)"),
showlegend = FALSE)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
#Gráfico de Residuos vs. Predicciones
# Calcular residuos
vivienda$residuos <- residuals(modelo_rlm)
# Gráfico de dispersión de residuos
plot_ly(data = vivienda, x = ~precio_predicho, y = ~residuos,
mode = "markers",
marker = list(opacity = 0.7, color = "red")) %>%
layout(title = "Residuos vs. Valores Predichos",
xaxis = list(title = "Precio Predicho (millones)"),
yaxis = list(title = "Residuos (Diferencia Real - Predicho)"),
showlegend = FALSE)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
#Importancia de las Variables en el Modelo
# Extraer coeficientes del modelo
coeficientes <- as.data.frame(summary(modelo_rlm)$coefficients)
coeficientes$variable <- rownames(coeficientes)
# Filtrar solo las variables explicativas
coeficientes <- coeficientes %>% filter(variable != "(Intercept)")
# Gráfico de barras de coeficientes
plot_ly(data = coeficientes, x = ~variable, y = ~Estimate, type = "bar",
text = ~paste("Valor:", round(Estimate, 2)),
marker = list(color = "blue")) %>%
layout(title = "Importancia de las Variables en el Precio",
xaxis = list(title = "Variable"),
yaxis = list(title = "Impacto en el Precio (millones)"))
Se ha estimado un Modelo de Regresión Lineal Múltiple para predecir el precio de las viviendas en función de:
El gráfico muestra que el modelo sigue una tendencia creciente, lo que indica que en general las predicciones son acertadas. Sin embargo:
Los residuos no están distribuidos completamente de manera aleatoria, lo que indica posible heterocedasticidad (la variabilidad de los errores no es constante).
Para mejorar esto, podríamos incluir variables como:
\[ R^2 = 72.9\% \]
Esto indica que el modelo explica una gran parte de la variabilidad del precio.
Sin embargo, aún hay 27% de variabilidad no explicada, lo que sugiere que otras variables pueden estar influyendo en el precio de las viviendas.
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1423.70 -86.35 -14.90 55.20 1126.10
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -421.81789 11.22265 -37.59 <2e-16 ***
## areaconst 0.87484 0.01882 46.48 <2e-16 ***
## estrato 103.86509 2.25935 45.97 <2e-16 ***
## habitaciones -23.43474 1.83001 -12.81 <2e-16 ***
## parqueaderos 71.27685 2.26398 31.48 <2e-16 ***
## banios 55.55033 2.17998 25.48 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 171.1 on 8313 degrees of freedom
## Multiple R-squared: 0.7292, Adjusted R-squared: 0.729
## F-statistic: 4476 on 5 and 8313 DF, p-value: < 2.2e-16
✔ El modelo es sólido, pero puede mejorarse incorporando:
Este supuesto indica que la relación entre las variables independientes y la variable dependiente debe ser lineal.
plot_ly(data = vivienda, x = ~precio_predicho, y = ~residuos,
mode = "markers", marker = list(opacity = 0.7, color = "red")) %>%
layout(title = "Residuos vs. Valores Predichos",
xaxis = list(title = "Precio Predicho (millones)"),
yaxis = list(title = "Residuos (Diferencia Real - Predicho)"),
showlegend = FALSE)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
Los residuos deben seguir una distribución normal para que las inferencias sean válidas.
# Histograma de residuos
ggplot(vivienda, aes(x = residuos)) +
geom_histogram(bins = 30, fill = "blue", alpha = 0.7) +
theme_minimal() +
labs(title = "Distribución de los Residuos", x = "Residuos", y = "Frecuencia")
# Gráfica Q-Q
qqnorm(vivienda$residuos)
qqline(vivienda$residuos, col = "red")
##Supuesto de Homocedasticidad (Varianza Constante de los Errores)
La varianza de los residuos debe ser constante en todo el rango de valores predichos.
plot_ly(data = vivienda, x = ~precio_predicho, y = ~residuos,
mode = "markers", marker = list(opacity = 0.7, color = "red")) %>%
layout(title = "Residuos vs. Valores Predichos",
xaxis = list(title = "Precio Predicho (millones)"),
yaxis = list(title = "Residuos (Diferencia Real - Predicho)"),
showlegend = FALSE)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
##Supuesto de No Colinealidad (Independencia entre Variables Predictoras)
Las variables independientes no deben estar altamente correlacionadas entre sí, ya que esto afecta la estabilidad del modelo.
vif(modelo_rlm)
## areaconst estrato habitaciones parqueaderos banios
## 2.057281 1.536484 2.027117 1.494192 2.754439
Linealidad: Los residuos muestran un patrón, indicando posible no linealidad. Se recomienda probar transformaciones como logaritmo del precio.
Normalidad: Los residuos no siguen una distribución normal, con valores extremos en los cuantiles. Se sugiere aplicar transformaciones o métodos robustos.
Homocedasticidad: Se observa heterocedasticidad, ya que los residuos no tienen varianza constante. Se recomienda usar regresión robusta o transformar el precio.
No Colinealidad: No hay colinealidad severa (VIF < 10), por lo que el modelo no sufre problemas de multicolinealidad.
El modelo es válido, pero puede mejorarse con transformaciones y ajustes para reducir los problemas de linealidad y heterocedasticidad.
Para predecir el precio de la vivienda con las características de la primera solicitud, usamos el modelo de Regresión Lineal Múltiple y los valores proporcionados:
📌 Características de la Vivienda 1
Área construida: 200 m² Estrato: 4 o 5 Parqueaderos: 1 Baños: 2 Habitaciones: 4 ✅ Predicción del Precio
Utilizando el modelo ajustado:
# Definir características de la vivienda 1
vivienda_nueva <- data.frame(
areaconst = 200,
estrato = c(4, 5), # Se calculan dos predicciones para estrato 4 y 5
habitaciones = 4,
parqueaderos = 1,
banios = 2
)
# Predecir el precio con el modelo ajustado
precio_predicho <- predict(modelo_rlm, newdata = vivienda_nueva)
# Mostrar resultados
vivienda_nueva$precio_predicho <- precio_predicho
print(vivienda_nueva)
## areaconst estrato habitaciones parqueaderos banios precio_predicho
## 1 200 4 4 1 2 257.2482
## 2 200 5 4 1 2 361.1133
Predicción del Precio de la Vivienda 1
Para estrato 4: \(257.2\) millones Para estrato 5: \(361.1\) millones
El estrato tiene un impacto fuerte en el precio. El precio estimado es inferior a la preaprobación bancaria (350M - 850M), lo que indica que podrían considerar opciones más costosas o revisar si hay variables no contempladas en el modelo que justifiquen diferencias en precios reales del mercado.
# 🔹 Filtrar viviendas que cumplan con las características principales
ofertas_potenciales <- vivienda %>%
filter(
tipo == "Casa", # Solo casas
zona == "Zona Norte", # Ubicación en zona norte
areaconst >= 200, # Área mínima de 200 m²
estrato %in% c(4, 5), # Estrato 4 o 5
parqueaderos >= 1, # Al menos 1 parqueadero
banios >= 2, # Al menos 2 baños
habitaciones >= 4, # Al menos 4 habitaciones
preciom <= 350 # Precio dentro del presupuesto
) %>%
arrange(preciom) %>% # Ordenar por precio ascendente
head(5) # Seleccionar las 5 mejores opciones
# 🔹 Mostrar tabla de ofertas
kable(ofertas_potenciales) %>% kable_styling()
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud | precio_predicho | residuos |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1020 | Zona Norte | 02 | 4 | 230 | 250 | 2 | 3 | 5 | Casa | la merced | -76.50799 | 3.47424 | 404.3825 | -174.3825 |
| 1009 | Zona Norte | No disponible | 5 | 250 | 243 | 1 | 4 | 5 | Casa | el bosque | -76.50755 | 3.47838 | 486.3972 | -236.3972 |
| 7432 | Zona Norte | 01 | 4 | 260 | 280 | 2 | 4 | 6 | Casa | los andes | -76.54973 | 3.42484 | 462.7431 | -202.7431 |
| 4727 | Zona Norte | 02 | 4 | 296 | 232 | 2 | 6 | 4 | Casa | granada | -76.53263 | 3.46090 | 578.7211 | -282.7211 |
| 1914 | Zona Norte | 02 | 5 | 300 | 205 | 2 | 5 | 6 | Casa | vipasa | -76.51832 | 3.48138 | 556.5458 | -256.5458 |
# 🔹 Crear mapa interactivo con las 5 mejores opciones
mapa_ofertas <- leaflet() %>%
addTiles() %>%
addCircleMarkers(data = ofertas_potenciales, ~longitud, ~latitud, color = "green",
popup = ~paste("Área:", areaconst, "m²",
"<br>Estrato:", estrato,
"<br>Parqueaderos:", parqueaderos,
"<br>Baños:", banios,
"<br>Habitaciones:", habitaciones,
"<br>Precio:", preciom, "millones"),
label = ~paste("Oferta en Zona Norte"))
# Mostrar mapa
mapa_ofertas
Se han identificado 5 viviendas en la Zona Norte que cumplen con las condiciones y el presupuesto de hasta 350 millones.
Tipo: Apartamento Zona: Sur Área Construida: 300 m² Parqueaderos: 3 Baños: 3 Habitaciones: 5 Estrato: 5 o 6 Crédito preaprobado: hasta 850 millones
# 📦 Cargar librerías necesarias
library(dplyr)
library(ggplot2)
library(plotly)
library(leaflet)
library(knitr)
library(kableExtra)
# 📌 1. Filtrar las opciones para la Segunda Vivienda
ofertas_potenciales_2 <- vivienda %>%
filter(
tipo == "Apartamento", # Solo apartamentos
zona == "Zona Sur", # Ubicación en zona sur
areaconst >= 300, # Área mínima de 300 m²
estrato %in% c(5, 6), # Estrato 5 o 6
parqueaderos >= 3, # Al menos 3 parqueaderos
banios >= 3, # Al menos 3 baños
habitaciones >= 5, # Al menos 5 habitaciones
preciom <= 850 # Precio dentro del presupuesto
) %>%
arrange(preciom) %>% # Ordenar por precio ascendente
head(5) # Seleccionar las 5 mejores opciones
# 📌 Mostrar tabla de ofertas
kable(ofertas_potenciales_2) %>% kable_styling()
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud | precio_predicho | residuos |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 7512 | Zona Sur | No disponible | 5 | 670 | 300 | 3 | 5 | 6 | Apartamento | seminario | -76.550 | 3.409 | 710.9321 | -40.93211 |
| 7182 | Zona Sur | No disponible | 5 | 730 | 573 | 3 | 8 | 5 | Apartamento | guadalupe | -76.548 | 3.408 | 1139.8481 | -409.84806 |
# 📌 2. Visualización de Precio vs. Características
cor_plot_2 <- plot_ly(data = vivienda, x = ~areaconst, y = ~preciom,
color = ~factor(estrato),
size = ~habitaciones,
text = ~paste("Baños:", banios, "<br>Zona:", zona),
mode = "markers") %>%
layout(title = "Correlación entre Precio y Variables Seleccionadas (Zona Sur)",
xaxis = list(title = "Área Construida (m²)"),
yaxis = list(title = "Precio (millones)"),
legend = list(title = list(text = "Estrato")))
# 📌 Mostrar gráfico interactivo
cor_plot_2
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
# 📌 3. Mapa de Ubicación de las Mejores Opciones
mapa_ofertas_2 <- leaflet() %>%
addTiles() %>%
addCircleMarkers(data = ofertas_potenciales_2, ~longitud, ~latitud, color = "red",
popup = ~paste("Área:", areaconst, "m²",
"<br>Estrato:", estrato,
"<br>Parqueaderos:", parqueaderos,
"<br>Baños:", banios,
"<br>Habitaciones:", habitaciones,
"<br>Precio:", preciom, "millones"),
label = ~paste("Apartamento en Zona Sur"))
# 📌 Mostrar mapa
mapa_ofertas_2
# 📌 4. Predicción del Precio de la Segunda Vivienda
# Definir características de la vivienda 2
vivienda_nueva_2 <- data.frame(
areaconst = 300,
estrato = c(5, 6), # Dos predicciones para estrato 5 y 6
habitaciones = 5,
parqueaderos = 3,
banios = 3
)
# Predecir el precio con el modelo ajustado
precio_predicho_2 <- predict(modelo_rlm, newdata = vivienda_nueva_2)
# Agregar predicciones al dataframe
vivienda_nueva_2$precio_predicho <- precio_predicho_2
# 📌 Mostrar resultados
kable(vivienda_nueva_2) %>% kable_styling()
| areaconst | estrato | habitaciones | parqueaderos | banios | precio_predicho |
|---|---|---|---|---|---|
| 300 | 5 | 5 | 3 | 3 | 623.2662 |
| 300 | 6 | 5 | 3 | 3 | 727.1313 |
#CONCLUSIÓN FINAL
Este trabajo ha permitido analizar el comportamiento del precio de las viviendas en función de variables clave como área construida, estrato, número de habitaciones, parqueaderos y baños. Se implementó un modelo de regresión lineal múltiple (RLM) para predecir los precios y validar su aplicabilidad en la selección de ofertas de vivienda según restricciones de crédito preaprobado.
Principales Hallazgos: Correlación de Variables: El análisis exploratorio mostró que el área construida y el estrato son los factores más influyentes en el precio de la vivienda, mientras que el número de habitaciones tuvo un impacto negativo. Ajuste del Modelo: Con un 𝑅2 de 0.729, el modelo explica aproximadamente el 73% de la variabilidad del precio, lo que indica un buen ajuste sin ser perfecto. Sin embargo, la dispersión de los residuos muestra que el modelo no captura completamente la complejidad del mercado inmobiliario. Validación de Supuestos: Linealidad: Se observa una tendencia clara, aunque con ciertos patrones no completamente lineales. Normalidad de los Errores: Hay algunas desviaciones en los extremos, lo que sugiere la presencia de valores atípicos. Homocedasticidad: Se evidenció heterocedasticidad (varianza no constante), lo que puede afectar la robustez del modelo. Colinealidad: No hay problemas severos de colinealidad entre las variables predictoras. Predicciones y Selección de Ofertas: Para la Vivienda 1 (Crédito: 350M), se identificaron 5 ofertas viables en la Zona Norte. Para la Vivienda 2 (Crédito: 850M), se encontraron 2 opciones en la Zona Sur dentro del presupuesto. Implicaciones y Mejoras Futuras: Considerar modelos más avanzados como regresión polinómica, árboles de decisión o redes neuronales para capturar relaciones más complejas. Incluir variables adicionales, como antigüedad de la vivienda, cercanía a servicios o valoración del barrio. Manejo de valores atípicos y transformación de variables para mejorar la normalidad y estabilidad del modelo. En general, este análisis demuestra la utilidad de la regresión lineal múltiple para estimar precios de vivienda, aunque con ciertas limitaciones en precisión. Para decisiones comerciales más robustas, se recomienda complementar el modelo con métodos más sofisticados y análisis de mercado en tiempo real.