El mercado inmobiliario en la ciudad de Cali ha presentado variaciones importantes en los últimos meses debido a cambios en la dinámica económica y en la disponibilidad de crédito por parte de las entidades financieras. En este contexto, la empresa C&A (Casas y Apartamentos), dirigida por María, ha recibido una solicitud por parte de una compañía internacional interesada en adquirir dos viviendas para ubicar a dos de sus empleados junto con sus familias.
Con el fin de brindar una recomendación basada en evidencia, se emplearán técnicas de análisis de datos y modelación estadística, específicamente regresión lineal múltiple, utilizando información de ofertas de viviendas disponibles en el mercado.
El objetivo del análisis es estimar el precio de las viviendas en función de sus características estructurales y de ubicación, así como identificar alternativas que se ajusten al presupuesto disponible de la empresa solicitante.
Para desarrollar el estudio se seguirán los siguientes pasos metodológicos:
Se realizará un filtro a la base de datos con el fin de incluir únicamente las ofertas correspondientes a casas ubicadas en la zona norte de la ciudad. Se presentarán los primeros registros de la base filtrada y se incluirán tablas que validen la consulta realizada.
Adicionalmente, se construirá un mapa con la ubicación geográfica de las viviendas, con el objetivo de verificar si todos los registros corresponden efectivamente a la zona norte o si se presentan inconsistencias en la información.
Se realizará un análisis exploratorio enfocado en la relación entre el precio de la vivienda y las siguientes variables:
Para este análisis se utilizarán gráficos interactivos mediante el paquete plotly, lo cual permitirá visualizar posibles patrones o relaciones entre las variables.
Posteriormente se estimará un modelo de regresión lineal múltiple donde el precio de la vivienda será explicado en función de las variables:
Se analizará la significancia estadística de los coeficientes, se interpretará el coeficiente de determinación (R²) y se discutirá si los resultados obtenidos son coherentes con el comportamiento esperado del mercado inmobiliario.
Se evaluarán los supuestos clásicos del modelo de regresión:
En caso de detectarse posibles problemas, se discutirán alternativas que podrían utilizarse para mejorar el modelo.
A partir del modelo estimado se realizará la predicción del precio de una vivienda con las características descritas en la primera solicitud realizada por la compañía internacional.
Con base en las predicciones del modelo se identificarán al menos cinco viviendas potenciales que cumplan con las condiciones solicitadas y cuyo valor se encuentre dentro del crédito preaprobado de 350 millones de pesos. Estas viviendas serán presentadas y analizadas mediante un mapa geográfico.
Finalmente, se repetirá el procedimiento para la segunda solicitud de vivienda, la cual cuenta con un crédito preaprobado de 850 millones de pesos, con el fin de identificar las opciones más adecuadas para este caso.
Para el desarrollo del análisis se utilizaron diferentes paquetes del lenguaje R, los cuales permiten realizar procesos de manipulación de datos, visualización gráfica y modelación estadística.
En particular, se utiliza el paquete paqueteMODELOS, que contiene la base de datos empleada en el ejercicio. Adicionalmente, se emplean librerías como dplyr para manipulación de datos, ggplot2 y plotly para visualización gráfica, y car para el análisis de supuestos del modelo de regresión.
A continuación, se presentan los comandos utilizados para instalar y cargar las librerías necesarias.
devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
##
## ── R CMD build ─────────────────────────────────────────────────────────────────
## checking for file ‘/private/var/folders/ng/fwtq_pxj3nd55x83644l70bm0000gn/T/Rtmp5OuO01/remotes3c3b7b366af/Centromagis-paqueteMODELOS-3b06257/DESCRIPTION’ ... ✔ checking for file ‘/private/var/folders/ng/fwtq_pxj3nd55x83644l70bm0000gn/T/Rtmp5OuO01/remotes3c3b7b366af/Centromagis-paqueteMODELOS-3b06257/DESCRIPTION’
## ─ preparing ‘paqueteMODELOS’:
## 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’
##
##
knitr::opts_chunk$set(
echo = TRUE,
warning = FALSE,
message = FALSE
)
library(paqueteMODELOS)
library(dplyr)
library(ggplot2)
library(plotly)
library(car)
library(leaflet)
library(psych)
library(corrplot)
library(GGally)
library(stargazer)
library(formattable)
library(knitr)
library(kableExtra)
library(leaflet)
La base de datos utilizada corresponde al conjunto
vivienda, el cual se encuentra disponible dentro del
paquete paqueteMODELOS. Esta base contiene información
sobre diferentes ofertas de viviendas, incluyendo variables relacionadas
con el precio, área construida, número de habitaciones, número de baños,
parqueaderos, estrato socioeconómico y ubicación dentro de la
ciudad.
A continuación, se carga la base de datos y se realiza una inspección inicial de su estructura con el fin de conocer las variables disponibles y el tipo de información que contiene.
data("vivienda")
head(vivienda)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1147 Zona O… <NA> 3 250 70 1 3 6
## 2 1169 Zona O… <NA> 3 320 120 1 2 3
## 3 1350 Zona O… <NA> 3 350 220 2 2 4
## 4 5992 Zona S… 02 4 400 280 3 5 3
## 5 1212 Zona N… 01 5 260 90 1 2 3
## 6 1724 Zona N… 01 5 240 87 1 3 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
str(vivienda)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8322] 1147 1169 1350 5992 1212 ...
## $ zona : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8322] NA NA NA "02" ...
## $ estrato : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
## - attr(*, "spec")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ";"
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
Los primeros registros permiten identificar las variables disponibles en el conjunto de datos y verificar que la información fue cargada correctamente para el análisis posterior.
De acuerdo con los requerimientos del análisis, es necesario trabajar únicamente con las ofertas de viviendas correspondientes a casas ubicadas en la zona norte de la ciudad.
Para ello, se realiza un proceso de filtrado sobre la base de datos
original utilizando funciones del paquete dplyr. Este
procedimiento permite seleccionar únicamente los registros que cumplen
con las condiciones establecidas para el análisis.
Posteriormente, se presentan los primeros registros de la base filtrada con el fin de verificar que la consulta fue realizada correctamente.
base1 <- vivienda %>%
filter(tipo == "Casa",
zona == "Zona Norte")
# número de registros
nrow(base1)
## [1] 722
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 4057 Zona N… 02 6 750 445 NA 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Los primeros registros de la base filtrada muestran únicamente viviendas correspondientes al tipo casa y ubicadas en la zona norte, lo cual confirma que el proceso de filtrado se realizó correctamente.
table(base1$tipo)
##
## Casa
## 722
table(base1$zona)
##
## Zona Norte
## 722
Las tablas de frecuencia permiten confirmar que todos los registros de la base filtrada corresponden al tipo de vivienda Casa y se encuentran ubicados en la zona norte de la ciudad, cumpliendo con los criterios establecidos para el análisis.
A continuación se presentan de manera georreferenciada las coordenadas de cada vivienda en el conjunto de datos. El objetivo es analizar la distribución espacial de las viviendas dentro de la zona norte de la ciudad de Cali.
leaflet(base1) %>%
addTiles() %>%
setView(lng = -76.53, lat = 3.45, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud,
lat = ~latitud,
radius = 4,
color = "orange",
fillOpacity = 0.7,
popup = ~paste("Precio:", preciom, "millones")
)
El mapa interactivo permite visualizar la distribución geográfica de las viviendas incluidas en la base filtrada. Aunque el filtro se realizó para incluir únicamente viviendas clasificadas en la Zona Norte, se observa que algunos puntos aparecen en otras áreas del mapa.
Esta situación puede explicarse por posibles inconsistencias en las coordenadas geográficas registradas en la base de datos o por diferencias entre la clasificación administrativa de la zona y la ubicación geográfica exacta de las viviendas.
Este tipo de hallazgos es común en bases de datos geoespaciales y resalta la importancia de realizar procesos de validación de calidad de los datos antes de utilizarlos para análisis más avanzados.
Para la detección de posibles inconsistencias en las coordenadas geográficas se utilizó una variante del método del rango intercuartílico (IQR). En lugar de emplear los percentiles tradicionales (25% y 75%), se utilizaron los percentiles 30% y 70% con el fin de definir un rango más restrictivo alrededor de la distribución central de las coordenadas.
Posteriormente se calcularon los límites inferior y superior utilizando el criterio \(1.5 \times IQR\)., lo cual permitió identificar observaciones con coordenadas potencialmente atípicas.
Q1_lat <- quantile(base1$latitud, 0.30)
Q3_lat <- quantile(base1$latitud, 0.70)
IQR_lat <- Q3_lat - Q1_lat
lim_inf_lat <- Q1_lat - 1.5 * IQR_lat
lim_sup_lat <- Q3_lat + 1.5 * IQR_lat
Q1_lon <- quantile(base1$longitud, 0.30)
Q3_lon <- quantile(base1$longitud, 0.70)
IQR_lon <- Q3_lon - Q1_lon
lim_inf_lon <- Q1_lon - 1.5 * IQR_lon
lim_sup_lon <- Q3_lon + 1.5 * IQR_lon
base1_limpia <- base1 %>%
filter(
latitud >= lim_inf_lat & latitud <= lim_sup_lat,
longitud >= lim_inf_lon & longitud <= lim_sup_lon
)
nrow(base1)
## [1] 722
nrow(base1_limpia)
## [1] 613
nrow(base1) - nrow(base1_limpia)
## [1] 109
cat("Observaciones iniciales:", nrow(base1), "\n")
## Observaciones iniciales: 722
cat("Observaciones después de la limpieza:", nrow(base1_limpia), "\n")
## Observaciones después de la limpieza: 613
leaflet(base1_limpia) %>%
addTiles() %>%
setView(lng = -76.53, lat = 3.45, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud,
lat = ~latitud,
radius = 4,
color = "darkorange",
fillOpacity = 0.7,
popup = ~paste("Precio:", preciom, "millones")
)
Durante el análisis exploratorio se realizó una validación espacial de las coordenadas geográficas de las viviendas. Para identificar posibles valores atípicos en las variables de latitud y longitud se aplicó el método del rango intercuartílico (IQR), el cual permite detectar observaciones que se encuentran significativamente alejadas de la distribución central de los datos.
A partir de este procedimiento se identificaron registros con coordenadas potencialmente inconsistentes, los cuales fueron excluidos del análisis con el fin de mejorar la calidad de los datos utilizados en el modelo. Posteriormente se generó un nuevo mapa con las observaciones depuradas, evidenciando una distribución espacial más coherente con la zona norte de la ciudad.
describe(base1_limpia)
## vars n mean sd median trimmed mad min max
## id 1 613 2231.15 1738.29 1666.00 2098.60 1890.31 88.00 7226.00
## zona* 2 613 1.00 0.00 1.00 1.00 0.00 1.00 1.00
## piso* 3 328 1.98 0.71 2.00 1.95 0.00 1.00 5.00
## estrato 4 613 4.15 0.97 4.00 4.12 1.48 3.00 6.00
## preciom 5 613 428.52 257.96 380.00 393.61 214.98 89.00 1940.00
## areaconst 6 613 261.32 166.39 240.00 240.54 148.26 30.00 1440.00
## parqueaderos 7 398 2.18 1.42 2.00 1.93 1.48 1.00 10.00
## banios 8 613 3.51 1.51 3.00 3.38 1.48 0.00 10.00
## habitaciones 9 613 4.58 1.82 4.00 4.38 1.48 0.00 10.00
## tipo* 10 613 1.00 0.00 1.00 1.00 0.00 1.00 1.00
## barrio* 11 613 50.58 28.00 47.00 51.25 34.10 1.00 92.00
## longitud 12 613 -76.51 0.02 -76.52 -76.52 0.02 -76.55 -76.48
## latitud 13 613 3.47 0.01 3.47 3.47 0.01 3.43 3.50
## range skew kurtosis se
## id 7138.00 0.53 -0.93 70.21
## zona* 0.00 NaN NaN 0.00
## piso* 4.00 0.47 0.54 0.04
## estrato 3.00 0.08 -1.32 0.04
## preciom 1851.00 1.88 5.76 10.42
## areaconst 1410.00 1.89 6.80 6.72
## parqueaderos 9.00 1.90 4.73 0.07
## banios 10.00 0.78 1.26 0.06
## habitaciones 10.00 0.82 1.14 0.07
## tipo* 0.00 NaN NaN 0.00
## barrio* 91.00 -0.06 -1.28 1.13
## longitud 0.07 0.27 -1.08 0.00
## latitud 0.06 -0.54 -0.28 0.00
Con el fin de comprender la relación entre el precio de las viviendas y sus principales características estructurales, se realiza un análisis exploratorio de datos (EDA).
En particular, se examina la relación entre el precio y variables como el área construida, el estrato socioeconómico, el número de habitaciones y el número de baños.
Para facilitar la interpretación de los resultados se utilizan gráficos interactivos mediante el paquete plotly.
ggplot(base1_limpia, aes(x = preciom)) +
geom_histogram(bins = 20, fill = "darkorange", color = "black") +
labs(
title = "Distribución del precio de las viviendas",
x = "Precio (millones de pesos)",
y = "Frecuencia"
)
El histograma muestra la distribución del precio de las viviendas en la muestra. Se observa que la mayoría de las propiedades se concentran en ciertos rangos de precio, mientras que algunas viviendas presentan valores más elevados. Este tipo de análisis permite identificar posibles valores extremos y comprender la variabilidad del mercado inmobiliario.
ggplot(base1_limpia, aes(y = preciom)) +
geom_boxplot(fill = "orange") +
labs(
title = "Boxplot del precio de las viviendas",
y = "Precio (millones de pesos)"
)
El boxplot permite identificar posibles valores atípicos en el precio de las viviendas. Se observa que algunas propiedades presentan precios considerablemente más altos que el resto de la muestra, lo cual podría influir en la estimación del modelo de regresión.
p1 <- ggplot(base1_limpia, aes(x = areaconst, y = preciom)) +
geom_point(color = "darkblue") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el área construida",
x = "Área construida (m²)",
y = "Precio (millones de pesos)"
)
ggplotly(p1)
El gráfico muestra una relación positiva entre el área construida y el precio de la vivienda. A medida que aumenta el tamaño del inmueble, el precio tiende a incrementarse. Este comportamiento es consistente con lo esperado en el mercado inmobiliario, donde viviendas con mayor área suelen tener un mayor valor comercial.
p2 <- ggplot(base1_limpia, aes(x = estrato, y = preciom)) +
geom_point(color = "darkgreen") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el estrato",
x = "Estrato socioeconómico",
y = "Precio (millones de pesos)"
)
ggplotly(p2)
Se observa una tendencia positiva entre el estrato socioeconómico y el precio de la vivienda. En general, las viviendas ubicadas en estratos más altos presentan precios más elevados, lo cual es consistente con las diferencias en calidad de infraestructura, ubicación y servicios asociados a cada estrato.
p3 <- ggplot(base1_limpia, aes(x = habitaciones, y = preciom)) +
geom_point(color = "darkorange") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el número de habitaciones",
x = "Número de habitaciones",
y = "Precio (millones de pesos)"
)
ggplotly(p3)
El gráfico sugiere una relación positiva entre el número de habitaciones y el precio de la vivienda. Aunque existe cierta dispersión en los datos, se observa que las viviendas con mayor número de habitaciones tienden a presentar precios más altos.
p4 <- ggplot(base1_limpia, aes(x = banios, y = preciom)) +
geom_point(color = "red") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el número de baños",
x = "Número de baños",
y = "Precio (millones de pesos)"
)
ggplotly(p4)
Se observa una relación positiva entre el número de baños y el precio de la vivienda. En términos generales, las propiedades con mayor cantidad de baños tienden a presentar valores más elevados, lo cual puede estar asociado a un mayor nivel de comodidad y tamaño de la vivienda.
cor(base1_limpia[, c("preciom",
"areaconst",
"habitaciones",
"banios",
"parqueaderos",
"estrato")])
## preciom areaconst habitaciones banios parqueaderos estrato
## preciom 1.0000000 0.7332501 0.4049050 0.5490607 NA 0.5915063
## areaconst 0.7332501 1.0000000 0.4373932 0.4964403 NA 0.4686173
## habitaciones 0.4049050 0.4373932 1.0000000 0.6268077 NA 0.1267576
## banios 0.5490607 0.4964403 0.6268077 1.0000000 NA 0.4053107
## parqueaderos NA NA NA NA 1 NA
## estrato 0.5915063 0.4686173 0.1267576 0.4053107 NA 1.0000000
corr <- cor(base1_limpia[, c("preciom",
"areaconst",
"habitaciones",
"banios",
"parqueaderos",
"estrato")])
corrplot(corr, method = "color")
La matriz de correlaciones permite identificar la intensidad de la relación lineal entre las variables numéricas analizadas. Se observa que el área construida presenta una de las correlaciones positivas más fuertes con el precio de la vivienda, Este resultado sugiere que el tamaño del inmueble es uno de los principales determinantes del valor de mercado, lo cual es consistente con la teoría económica del mercado inmobiliario.
ggpairs(
base1_limpia[, c("preciom",
"areaconst",
"habitaciones",
"banios",
"parqueaderos",
"estrato")]
)
La matriz de dispersión permite analizar simultáneamente las relaciones entre las principales variables numéricas del conjunto de datos. Se observa que el precio de la vivienda presenta asociaciones positivas con variables como el área construida, el número de habitaciones y el número de baños. Estas relaciones sugieren que dichas variables podrían tener un efecto importante en la explicación del precio dentro del modelo de regresión.
En general, el análisis exploratorio sugiere que variables estructurales como el área construida, el estrato socioeconómico y el número de habitaciones y baños presentan una relación positiva con el precio de la vivienda. Estos resultados son coherentes con la teoría económica del mercado inmobiliario y respaldan la inclusión de estas variables en el modelo de regresión lineal múltiple.
El análisis exploratorio de datos evidencia que variables estructurales como el área construida, el estrato socioeconómico, el número de habitaciones y el número de baños presentan una relación positiva con el precio de las viviendas. Estos hallazgos son consistentes con el comportamiento esperado del mercado inmobiliario y justifican la inclusión de estas variables como predictores dentro del modelo de regresión lineal múltiple.
Con el fin de analizar la relación entre el precio de las viviendas y sus características estructurales, se estima un modelo de regresión lineal múltiple donde el precio de la vivienda es explicado por variables como el área construida, el estrato socioeconómico, el número de habitaciones, el número de parqueaderos y el número de baños.
La especificación del modelo es la siguiente:
\[ Precio_i = \beta_0 + \beta_1 Areaconst_i + \beta_2 Estrato_i + \beta_3 Habitaciones_i + \beta_4 Parqueaderos_i + \beta_5 Banios_i + \epsilon_i \]
donde:
A continuación, se procede a estimar el modelo utilizando el método de Mínimos Cuadrados Ordinarios (OLS).
modelo1 <- lm(preciom ~ areaconst +
estrato +
habitaciones +
parqueaderos +
banios,
data = base1_limpia)
summary(modelo1)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = base1_limpia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -750.95 -71.46 -15.13 43.51 988.75
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -227.81808 46.71879 -4.876 1.57e-06 ***
## areaconst 0.65173 0.05617 11.602 < 2e-16 ***
## estrato 77.00602 10.38065 7.418 7.42e-13 ***
## habitaciones 7.00985 5.94922 1.178 0.2394
## parqueaderos 27.24956 6.01671 4.529 7.88e-06 ***
## banios 20.47837 8.13337 2.518 0.0122 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 154.7 on 392 degrees of freedom
## (215 observations deleted due to missingness)
## Multiple R-squared: 0.6028, Adjusted R-squared: 0.5977
## F-statistic: 119 on 5 and 392 DF, p-value: < 2.2e-16
coef(summary(modelo1))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -227.8180845 46.71878710 -4.876370 1.573199e-06
## areaconst 0.6517263 0.05617434 11.601851 5.907815e-27
## estrato 77.0060179 10.38065078 7.418226 7.420405e-13
## habitaciones 7.0098452 5.94921902 1.178280 2.393998e-01
## parqueaderos 27.2495578 6.01670661 4.528982 7.876249e-06
## banios 20.4783672 8.13337379 2.517820 1.220602e-02
stargazer(modelo1, type = "text")
##
## ===============================================
## Dependent variable:
## ---------------------------
## preciom
## -----------------------------------------------
## areaconst 0.652***
## (0.056)
##
## estrato 77.006***
## (10.381)
##
## habitaciones 7.010
## (5.949)
##
## parqueaderos 27.250***
## (6.017)
##
## banios 20.478**
## (8.133)
##
## Constant -227.818***
## (46.719)
##
## -----------------------------------------------
## Observations 398
## R2 0.603
## Adjusted R2 0.598
## Residual Std. Error 154.735 (df = 392)
## F Statistic 118.980*** (df = 5; 392)
## ===============================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Con base en los resultados del modelo estimado, a continuación se presenta la interpretación de los coeficientes y del ajuste general del modelo.
A partir de la estimación del modelo de regresión lineal múltiple se obtuvieron los coeficientes asociados a cada variable explicativa, los cuales permiten analizar cómo diferentes características estructurales de las viviendas influyen en su precio.
El modelo fue estimado con 398 observaciones y presenta un coeficiente de determinación \(R^2 = 0.603\), lo que indica que aproximadamente el 60.3% de la variabilidad del precio de las viviendas puede ser explicada por las variables incluidas en el modelo.
A continuación se presenta la interpretación de los principales coeficientes.
El coeficiente asociado al área construida es 0.652 y es estadísticamente significativo al 1% (\(p < 0.01\)).
Esto significa que, manteniendo constantes las demás variables del modelo, un incremento de un metro cuadrado en el área construida aumenta en promedio el precio de la vivienda en aproximadamente 0.652 millones de pesos.
Este resultado es coherente con la lógica del mercado inmobiliario, ya que viviendas con mayor área construida ofrecen mayor espacio habitable y, por lo tanto, tienden a tener un mayor valor comercial.
El coeficiente del estrato es 77.006 y también es estadísticamente significativo al 1% (\(p < 0.01\)).
Esto indica que, manteniendo constantes las demás variables, un aumento de un nivel en el estrato socioeconómico incrementa en promedio el precio de la vivienda en aproximadamente 77 millones de pesos.
Este resultado es consistente con el comportamiento del mercado inmobiliario en Colombia, donde las viviendas ubicadas en estratos más altos suelen estar asociadas a mejores condiciones de infraestructura, seguridad y acceso a servicios urbanos, lo que se refleja en precios más elevados.
El coeficiente asociado al número de habitaciones es 7.01, pero no es estadísticamente significativo.
Esto sugiere que, una vez controlado por variables como el área construida, el estrato y otras características del inmueble, el número de habitaciones no tiene un efecto estadísticamente claro sobre el precio de la vivienda dentro de este modelo.
Este resultado puede explicarse porque el efecto del número de habitaciones ya podría estar siendo capturado indirectamente por el área construida, dado que viviendas con más habitaciones suelen tener también mayor tamaño.
El coeficiente asociado al número de parqueaderos es 27.25 y es estadísticamente significativo al 1% (\(p < 0.01\)).
Esto significa que, manteniendo constantes las demás variables del modelo, contar con un parqueadero adicional incrementa en promedio el precio de la vivienda en aproximadamente 27.25 millones de pesos.
Este resultado es lógico desde el punto de vista del mercado inmobiliario urbano, ya que el acceso a estacionamiento es un factor altamente valorado por los compradores, especialmente en zonas donde el espacio para parqueo es limitado.
El coeficiente asociado al número de baños es 20.48 y es estadísticamente significativo al 5% (\(p < 0.05\)).
Esto indica que, manteniendo constantes las demás variables, un baño adicional incrementa en promedio el precio de la vivienda en aproximadamente 20.48 millones de pesos.
Este resultado también es coherente con la lógica del mercado, ya que viviendas con mayor número de baños suelen ofrecer mayor comodidad y funcionalidad para los hogares.
El coeficiente de determinación \(R^2 = 0.603\) indica que aproximadamente el 60.3% de la variabilidad observada en el precio de las viviendas es explicada por las variables incluidas en el modelo.
Este valor sugiere que el modelo presenta un nivel de ajuste moderadamente alto, teniendo en cuenta que el precio de los inmuebles suele depender de muchos factores adicionales que no están incluidos en la base de datos.
El \(R^2\) ajustado = 0.598 es muy cercano al \(R^2\), lo que indica que las variables incluidas en el modelo contribuyen de manera efectiva a explicar el precio de las viviendas y que no se están incluyendo predictores innecesarios.
Aunque el modelo logra explicar una proporción importante de la variabilidad del precio de las viviendas, todavía existe cerca de un 40% de variación que no es explicada por las variables incluidas.
Esto sugiere que podrían existir otros factores relevantes que influyen en el precio de los inmuebles, tales como:
Adicionalmente, el modelo podría mejorarse evaluando posibles transformaciones de variables, como utilizar el logaritmo del precio, o explorando interacciones entre variables, por ejemplo entre el área construida y el número de habitaciones.
En general, los resultados obtenidos son consistentes con el comportamiento esperado del mercado inmobiliario, donde variables relacionadas con el tamaño del inmueble, el nivel socioeconómico de la zona y las comodidades disponibles influyen directamente en el precio de las viviendas.
En la siguiente sección se evalúan los supuestos del modelo de regresión con el fin de verificar la validez de las inferencias realizadas.
ggplot(data.frame(
predicho = fitted(modelo1),
residuo = resid(modelo1)
), aes(x = predicho, y = residuo)) +
geom_point(color = "darkorange", alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "black") +
geom_hline(yintercept = 0, linetype = "dashed") +
labs(
title = "Residuos vs valores predichos",
x = "Valores predichos",
y = "Residuos"
)
El gráfico de residuos frente a valores predichos permite evaluar si existen patrones sistemáticos en los errores del modelo.
En un modelo adecuadamente especificado, los residuos deberían distribuirse de manera aleatoria alrededor de cero y sin presentar estructuras visibles. En este caso se observa que los residuos se dispersan alrededor de la línea horizontal en cero, aunque se aprecia cierta variabilidad creciente en algunos rangos de valores predichos.
La línea suavizada (LOESS) permite identificar posibles patrones no lineales. En general, el comportamiento observado sugiere que el modelo captura una parte importante de la relación entre las variables, aunque podrían existir factores adicionales que influyan en el precio de las viviendas y que no están incluidos en el modelo.
Una vez estimado el modelo de regresión lineal múltiple, es importante evaluar si se cumplen los supuestos clásicos del modelo lineal. Estos supuestos permiten garantizar que las inferencias estadísticas realizadas a partir del modelo sean válidas.
A continuación se presentan algunos gráficos y pruebas estadísticas que permiten analizar estos supuestos. Los resultados deben interpretarse de manera exploratoria, con el fin de identificar posibles patrones o señales de incumplimiento.
Uno de los supuestos del modelo de regresión lineal es que los residuos siguen aproximadamente una distribución normal. Para explorar este supuesto se analizan tanto la distribución de los residuos como el gráfico Q-Q.
hist(residuals(modelo1),
main = "Distribución de los residuos",
xlab = "Residuos",
col = "darkorange",
border = "black")
El histograma muestra la distribución de los residuos del modelo de regresión. Se observa una forma aproximadamente simétrica con cierta concentración alrededor de cero, lo cual es consistente con el supuesto de normalidad de los errores.
Sin embargo, se aprecia una ligera asimetría en los extremos de la distribución, lo cual puede estar asociado a la presencia de algunas observaciones con mayor desviación respecto a los valores predichos por el modelo.
qqnorm(residuals(modelo1),
main = "Q-Q Plot de los residuos")
qqline(residuals(modelo1),
col = "darkorange",
lwd = 3)
El gráfico Q-Q permite comparar la distribución de los residuos del modelo con una distribución normal teórica. En este caso, se observa que la mayoría de los puntos se encuentran alineados cerca de la línea de referencia, lo que sugiere que el supuesto de normalidad de los residuos podría considerarse razonable.
No obstante, se observan algunas desviaciones en los extremos del gráfico, lo cual es relativamente común en muestras de datos reales y puede indicar la presencia de algunos valores extremos o colas ligeramente más pesadas.
El supuesto de homocedasticidad establece que la varianza de los residuos debe ser aproximadamente constante para todos los valores ajustados del modelo.
plot(modelo1$fitted.values,
residuals(modelo1),
xlab = "Valores ajustados",
ylab = "Residuos",
main = "Residuos vs valores ajustados")
abline(h = 0, col = "darkorange")
El análisis del gráfico de residuos versus valores ajustados muestra un patrón con forma de embudo al inicio de la distribución. Este comportamiento sugiere la posible presencia de heterocedasticidad, es decir, que la varianza de los residuos no se mantiene completamente constante a lo largo del rango de valores ajustados. En particular, se observa una mayor dispersión de los residuos en ciertos niveles del modelo, lo cual puede indicar que el supuesto de homocedasticidad se cumple solo parcialmente.
A pesar de la presencia de heterocedasticidad, los coeficientes del modelo siguen siendo insesgados bajo el método de Mínimos Cuadrados Ordinarios, aunque los errores estándar podrían estar subestimados o sobreestimados.
car::ncvTest(modelo1)
## Non-constant Variance Score Test
## Variance formula: ~ fitted.values
## Chisquare = 322.3962, Df = 1, p = < 2.22e-16
Con el fin de evaluar si el modelo cumple con el supuesto de varianza constante de los errores (homocedasticidad), se aplicó la prueba Non-constant Variance Score Test.
Los resultados obtenidos fueron los siguientes: • Chi-cuadrado: 322.396 • Grados de libertad: 1 • Valor p: < 2.22e-16
Dado que el valor p es significativamente menor que 0.05, se rechaza la hipótesis nula de varianza constante de los residuos. Esto indica evidencia estadística de heterocedasticidad en el modelo, es decir, la varianza de los errores no se mantiene constante a lo largo de los valores ajustados.
Este resultado es consistente con el análisis gráfico de los residuos, donde se observa un patrón con forma de embudo, lo cual sugiere que la dispersión de los residuos aumenta o disminuye dependiendo del nivel de los valores predichos.
La presencia de heterocedasticidad no invalida el modelo, pero puede afectar la precisión de los errores estándar y de las pruebas de significancia de los coeficientes. Por esta razón, una posible mejora consiste en utilizar errores estándar robustos o aplicar transformaciones a algunas variables con el fin de estabilizar la varianza de los residuos.
Otro aspecto importante en los modelos de regresión es evaluar si las variables explicativas están altamente correlacionadas entre sí, lo cual podría afectar la estabilidad de los coeficientes estimados.
Para analizar este problema se utiliza el Factor de Inflación de la Varianza (VIF).
vif(modelo1)
## areaconst estrato habitaciones parqueaderos banios
## 1.518290 1.345045 1.815634 1.218174 2.117885
Para evaluar la posible presencia de multicolinealidad entre las variables explicativas del modelo, se calculó el Factor de Inflación de la Varianza (VIF). Este indicador permite identificar si existe una alta correlación entre las variables independientes, lo cual podría afectar la estabilidad y precisión de las estimaciones del modelo.
Los valores obtenidos fueron los siguientes:
Variable VIF areaconst 1.52 estrato 1.35 habitaciones 1.82 parqueaderos 1.22 banios 2.12
En general, valores de VIF superiores a 5 sugieren problemas moderados de multicolinealidad, mientras que valores superiores a 10 indican problemas severos.
En este caso, todos los valores de VIF se encuentran muy por debajo de los umbrales comúnmente aceptados, con valores entre 1.22 y 2.12. Esto indica que no existe evidencia de multicolinealidad significativa entre las variables explicativas del modelo.
Por lo tanto, las variables incluidas en la regresión pueden considerarse estadísticamente independientes entre sí en un grado adecuado, lo que permite interpretar los coeficientes estimados con mayor confianza.
Finalmente, se pueden observar los gráficos de diagnóstico estándar del modelo de regresión, los cuales permiten analizar simultáneamente diferentes aspectos del comportamiento de los residuos.
par(mfrow = c(2,2))
plot(modelo1)
Estos gráficos permiten identificar posibles observaciones influyentes, patrones no lineales o desviaciones respecto a los supuestos del modelo. El análisis visual de estos resultados puede proporcionar información útil para evaluar la calidad del ajuste del modelo estimado.
El análisis gráfico y las pruebas exploratorias permiten evaluar de manera preliminar los supuestos del modelo de regresión lineal. En general, estos diagnósticos ayudan a identificar posibles desviaciones respecto a los supuestos clásicos y orientan sobre posibles ajustes o mejoras que podrían aplicarse al modelo en futuros análisis.
Con base en el modelo estimado, se procede a predecir el precio de la vivienda solicitada por la compañía internacional. Las características de la vivienda son:
# Crear un data frame con las características de la vivienda
primera_vivienda <- data.frame(
areaconst = 200,
estrato = c(4,5), # Evaluar ambos estratos
habitaciones = 4,
parqueaderos = 1,
banios = 2
)
# Realizar la predicción
precio_predicho <- predict(modelo1, newdata = primera_vivienda)
# Mostrar los resultados
data.frame(
Estrato = primera_vivienda$estrato,
Precio_Estimado_millones = round(precio_predicho, 2)
)
## Estrato Precio_Estimado_millones
## 1 4 306.8
## 2 5 383.8
El modelo predice que una vivienda con las características solicitadas en estrato 4 tendría un precio aproximado de 306.8 millones, dentro del crédito preaprobado de 350 millones.
Para estrato 5, el precio estimado promedio sería de 383.8 millones, excediendo el presupuesto. Sin embargo, al revisar el conjunto de viviendas disponible, se identifica al menos dos propiedades que cumplen con todos los requisitos y su precio está dentro del límite de crédito, lo que permite incluirla como opción viable.
Por lo tanto, la selección de viviendas puede priorizar estrato 4 pero no descarta por completo viviendas de estrato 5 e incluso estrato 3, siempre que se encuentren dentro del presupuesto y cumplan con las características estructurales solicitadas.
A continuación se presentan las cinco viviendas que cumplen con las características solicitadas en la primera solicitud (tipo casa, área construida cercana a 200 m², parqueaderos 1, baños 2, habitaciones 4, zona Norte).
# Calcular precio estimado de la solicitud
solicitud1 <- data.frame(
areaconst = 200,
parqueaderos = 1,
banios = 2,
habitaciones = 4,
estrato = 4
)
solicitud1$precio_estimado <- predict(modelo1, newdata = solicitud1)
# Calcular "distancia" a las características de la solicitud
viviendas_seleccionadas <- base1_limpia %>%
mutate(
distancia = abs(areaconst - solicitud1$areaconst) +
abs(parqueaderos - solicitud1$parqueaderos) +
abs(banios - solicitud1$banios) +
abs(habitaciones - solicitud1$habitaciones) +
abs(preciom - solicitud1$precio_estimado)
) %>%
arrange(distancia) %>%
head(5) # seleccionar las 5 más cercanas
viviendas_seleccionadas
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 457 Zona N… <NA> 3 300 195 2 4 4
## 2 1343 Zona N… 02 5 320 200 2 4 4
## 3 1144 Zona N… <NA> 4 320 200 2 4 4
## 4 1914 Zona N… 02 5 300 205 2 5 6
## 5 1151 Zona N… <NA> 5 320 210 2 3 5
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # distancia <dbl>
viviendas_resumen <- data.frame(
id = c(457, 1343, 1144, 1914, 1151),
estrato = c(3,5,4,5,5),
areaconst = c(195,200,200,205,210),
habitaciones = c(4,4,4,6,5),
banios = c(4,4,4,5,3),
parqueaderos = c(2,2,2,2,2),
preciom = c(300,320,320,300,320),
precio_estimado_modelo = c(294.7,452.0,375.0,489.8,445.1),
cumple_credito = c("Sí","No","No","No","No")
)
# Crear tabla con colores según estrato
viviendas_resumen %>%
kable("html", caption = "Viviendas seleccionadas para la primera solicitud") %>%
kable_styling("striped", full_width = F) %>%
row_spec(0, bold = TRUE) %>%
column_spec(2, color = "white", background = c("darkblue","darkgreen","darkorange","darkgreen","darkgreen"))
| id | estrato | areaconst | habitaciones | banios | parqueaderos | preciom | precio_estimado_modelo | cumple_credito |
|---|---|---|---|---|---|---|---|---|
| 457 | 3 | 195 | 4 | 4 | 2 | 300 | 294.7 | Sí |
| 1343 | 5 | 200 | 4 | 4 | 2 | 320 | 452.0 | No |
| 1144 | 4 | 200 | 4 | 4 | 2 | 320 | 375.0 | No |
| 1914 | 5 | 205 | 6 | 5 | 2 | 300 | 489.8 | No |
| 1151 | 5 | 210 | 5 | 3 | 2 | 320 | 445.1 | No |
# Asegurarse de que las coordenadas están incluidas
viviendas_para_mapa <- viviendas_resumen %>%
left_join(base1_limpia %>% select(id, longitud, latitud), by = "id")
# Ahora sí se puede hacer el mapa
leaflet(viviendas_para_mapa) %>%
addTiles() %>%
setView(lng = -76.53, lat = 3.45, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud,
lat = ~latitud,
radius = 6,
color = ~case_when(
estrato == 3 ~ "darkblue",
estrato == 4 ~ "darkorange",
estrato == 5 ~ "darkgreen",
TRUE ~ "gray"
),
fillOpacity = 0.8,
popup = ~paste(
"ID:", id,
"<br>Estrato:", estrato,
"<br>Área:", areaconst, "m²",
"<br>Habitaciones:", habitaciones,
"<br>Baños:", banios,
"<br>Parqueaderos:", parqueaderos,
"<br>Precio Real:", preciom, "millones",
"<br>Precio Estimado:", precio_estimado_modelo, "millones",
"<br>Cumple Crédito:", cumple_credito
)
) %>%
addLegend(
position = "bottomright",
colors = c("darkblue", "darkorange", "darkgreen"),
labels = c("Estrato 3", "Estrato 4", "Estrato 5"),
title = "Estrato"
)
Las cinco viviendas más cercanas a las características de la primera solicitud se presentan a continuación. Se incluye el precio estimado según el modelo y su estrato:
viviendas_resumen <- viviendas_seleccionadas %>%
mutate(
precio_estimado_modelo = round(predict(modelo1, newdata = .), 1),
cumple_credito = ifelse(precio_estimado_modelo <= 350, "Sí", "No")
) %>%
select(id, estrato, areaconst, habitaciones, banios, parqueaderos, preciom, precio_estimado_modelo, cumple_credito)
viviendas_resumen
## # A tibble: 5 × 9
## id estrato areaconst habitaciones banios parqueaderos preciom
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 457 3 195 4 4 2 300
## 2 1343 5 200 4 4 2 320
## 3 1144 4 200 4 4 2 320
## 4 1914 5 205 6 5 2 300
## 5 1151 5 210 5 3 2 320
## # ℹ 2 more variables: precio_estimado_modelo <dbl>, cumple_credito <chr>
El modelo de regresión lineal múltiple permitió estimar el precio de viviendas con características específicas solicitadas por la compañía internacional. De las cinco viviendas más cercanas a los criterios, solo una cumple con el límite de crédito de 350 millones de pesos, mientras que las demás superan el presupuesto. Esto evidencia la importancia de ajustar las expectativas de ubicación, área o estrato para encontrar opciones viables dentro del presupuesto establecido.
Con esta información, se procede a evaluar la segunda solicitud de vivienda, la cual cuenta con un crédito preaprobado mayor, lo que permitirá un rango más amplio de opciones en la zona norte de la ciudad.
Dado que la segunda solicitud corresponde a un apartamento en la zona Sur, se repite el proceso de análisis utilizando únicamente registros de apartamentos ubicados en la zona Sur.
Las características del apartamento son:
De acuerdo con los requerimientos del análisis, es necesario trabajar únicamente con las ofertas de viviendas correspondientes a casas ubicadas en la zona sur de la ciudad.
Posteriormente, se presentan los primeros registros de la base filtrada con el fin de verificar que la consulta fue realizada correctamente.
base2 <- vivienda %>%
filter(tipo == "Apartamento",
zona == "Zona Sur")
# número de registros
nrow(base2)
## [1] 2787
head(base2,3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 5098 Zona S… 05 4 290 96 1 2 3
## 2 698 Zona S… 02 3 78 40 1 1 2
## 3 8199 Zona S… <NA> 6 875 194 2 5 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
summary(base2)
## id zona piso estrato
## Min. : 3 Length:2787 Length:2787 Min. :3.00
## 1st Qu.:2292 Class :character Class :character 1st Qu.:4.00
## Median :4004 Mode :character Mode :character Median :5.00
## Mean :4131 Mean :4.63
## 3rd Qu.:5876 3rd Qu.:5.00
## Max. :8302 Max. :6.00
##
## preciom areaconst parqueaderos banios
## Min. : 75.0 Min. : 40.00 Min. : 1.000 Min. :0.000
## 1st Qu.: 175.0 1st Qu.: 65.00 1st Qu.: 1.000 1st Qu.:2.000
## Median : 245.0 Median : 85.00 Median : 1.000 Median :2.000
## Mean : 297.3 Mean : 97.47 Mean : 1.415 Mean :2.488
## 3rd Qu.: 335.0 3rd Qu.:110.00 3rd Qu.: 2.000 3rd Qu.:3.000
## Max. :1750.0 Max. :932.00 Max. :10.000 Max. :8.000
## NA's :406
## habitaciones tipo barrio longitud
## Min. :0.000 Length:2787 Length:2787 Min. :-76.57
## 1st Qu.:3.000 Class :character Class :character 1st Qu.:-76.54
## Median :3.000 Mode :character Mode :character Median :-76.53
## Mean :2.966 Mean :-76.53
## 3rd Qu.:3.000 3rd Qu.:-76.52
## Max. :6.000 Max. :-76.46
##
## latitud
## Min. :3.334
## 1st Qu.:3.370
## Median :3.383
## Mean :3.390
## 3rd Qu.:3.406
## Max. :3.497
##
Los primeros registros de la base filtrada muestran únicamente viviendas correspondientes al tipo apartamento y ubicadas en la zona sur, lo cual confirma que el proceso de filtrado se realizó correctamente.
table(base2$tipo)
##
## Apartamento
## 2787
table(base2$zona)
##
## Zona Sur
## 2787
Las tablas de frecuencia permiten confirmar que todos los registros de la base filtrada corresponden al tipo de vivienda Apartamento y se encuentran ubicados en la zona sur de la ciudad, cumpliendo con los criterios establecidos para el análisis.
# Filtrar viviendas con precio mayor a 850 millones
base2_filtrada <- base2 %>%
filter(preciom > 850)
# Ver cuántas observaciones quedan
nrow(base2_filtrada)
## [1] 56
Solo existen 56 propiedades que se salen del presupuesto de acuerdo a la base.
A continuación se presentan de manera georreferenciada las coordenadas de cada vivienda en el conjunto de datos. El objetivo es analizar la distribución espacial de las viviendas dentro de la zona sur de la ciudad de Cali.
# Reemplazar NA por la mediana
base2 <- base2 %>%
mutate(parqueaderos = ifelse(is.na(parqueaderos),
median(parqueaderos, na.rm = TRUE),
parqueaderos))
se imputan los datos de parqueadero por la mediana
leaflet(base2) %>%
addTiles() %>%
setView(lng = -76.53, lat = 3.45, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud,
lat = ~latitud,
radius = 4,
color = "green",
fillOpacity = 0.7,
popup = ~paste("Precio:", preciom, "millones")
)
El mapa interactivo permite visualizar la distribución geográfica de las viviendas incluidas en la base filtrada. Aunque el filtro se realizó para incluir únicamente viviendas clasificadas en la Zona Sur, se observa que algunos puntos aparecen en otras áreas del mapa.
Esta situación puede explicarse por posibles inconsistencias en las coordenadas geográficas registradas en la base de datos o por diferencias entre la clasificación administrativa de la zona y la ubicación geográfica exacta de las viviendas.
Este tipo de hallazgos es común en bases de datos geoespaciales y resalta la importancia de realizar procesos de validación de calidad de los datos antes de utilizarlos para análisis más avanzados.
Para la detección de posibles inconsistencias en las coordenadas geográficas se utilizó una variante del método del rango intercuartílico (IQR). En lugar de emplear los percentiles tradicionales (25% y 75%), se utilizaron los percentiles 30% y 70% con el fin de definir un rango más restrictivo alrededor de la distribución central de las coordenadas.
Posteriormente se calcularon los límites inferior y superior utilizando el criterio \(1.5 \times IQR\)., lo cual permitió identificar observaciones con coordenadas potencialmente atípicas.
Q1_lat <- quantile(base2$latitud, 0.30)
Q3_lat <- quantile(base2$latitud, 0.70)
IQR_lat <- Q3_lat - Q1_lat
lim_inf_lat <- Q1_lat - 1.5 * IQR_lat
lim_sup_lat <- Q3_lat + 1.5 * IQR_lat
Q1_lon <- quantile(base2$longitud, 0.30)
Q3_lon <- quantile(base2$longitud, 0.70)
IQR_lon <- Q3_lon - Q1_lon
lim_inf_lon <- Q1_lon - 1.5 * IQR_lon
lim_sup_lon <- Q3_lon + 1.5 * IQR_lon
base2_limpia <- base2 %>%
filter(
latitud >= lim_inf_lat & latitud <= lim_sup_lat,
longitud >= lim_inf_lon & longitud <= lim_sup_lon
)
nrow(base2)
## [1] 2787
nrow(base2_limpia)
## [1] 2549
nrow(base2) - nrow(base2_limpia)
## [1] 238
cat("Observaciones iniciales:", nrow(base2), "\n")
## Observaciones iniciales: 2787
cat("Observaciones después de la limpieza:", nrow(base2_limpia), "\n")
## Observaciones después de la limpieza: 2549
leaflet(base2_limpia) %>%
addTiles() %>%
setView(lng = -76.53, lat = 3.45, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud,
lat = ~latitud,
radius = 4,
color = "darkgreen",
fillOpacity = 0.7,
popup = ~paste("Precio:", preciom, "millones")
)
Durante el análisis exploratorio se realizó una validación espacial de las coordenadas geográficas de las viviendas. Para identificar posibles valores atípicos en las variables de latitud y longitud se aplicó el método del rango intercuartílico (IQR), el cual permite detectar observaciones que se encuentran significativamente alejadas de la distribución central de los datos.
A partir de este procedimiento se identificaron registros con coordenadas potencialmente inconsistentes, los cuales fueron excluidos del análisis con el fin de mejorar la calidad de los datos utilizados en el modelo. Posteriormente se generó un nuevo mapa con las observaciones depuradas, evidenciando una distribución espacial más coherente con la zona norte de la ciudad.
describe(base2_limpia)
## vars n mean sd median trimmed mad min max
## id 1 2549 4271.06 2020.93 4068.00 4208.17 2599.00 607.00 8241.00
## zona* 2 2549 1.00 0.00 1.00 1.00 0.00 1.00 1.00
## piso* 3 1986 4.44 2.62 4.00 4.19 2.97 1.00 12.00
## estrato 4 2549 4.63 0.84 5.00 4.63 1.48 3.00 6.00
## preciom 5 2549 296.79 191.00 245.00 261.70 118.61 75.00 1750.00
## areaconst 6 2549 97.66 52.84 85.00 88.47 31.13 40.00 932.00
## parqueaderos 7 2549 1.35 0.62 1.00 1.25 0.00 1.00 10.00
## banios 8 2549 2.49 0.93 2.00 2.38 0.00 0.00 8.00
## habitaciones 9 2549 2.96 0.63 3.00 2.96 0.00 0.00 6.00
## tipo* 10 2549 1.00 0.00 1.00 1.00 0.00 1.00 1.00
## barrio* 11 2549 79.91 37.69 83.00 81.83 60.79 1.00 128.00
## longitud 12 2549 -76.53 0.01 -76.53 -76.53 0.01 -76.56 -76.50
## latitud 13 2549 3.38 0.02 3.38 3.38 0.02 3.33 3.44
## range skew kurtosis se
## id 7634.00 0.19 -1.14 40.03
## zona* 0.00 NaN NaN 0.00
## piso* 11.00 0.82 0.17 0.06
## estrato 3.00 0.05 -0.68 0.02
## preciom 1675.00 2.68 11.01 3.78
## areaconst 892.00 4.37 39.10 1.05
## parqueaderos 9.00 2.69 17.66 0.01
## banios 8.00 1.18 1.80 0.02
## habitaciones 6.00 0.00 2.69 0.01
## tipo* 0.00 NaN NaN 0.00
## barrio* 127.00 -0.17 -1.37 0.75
## longitud 0.06 -0.21 -0.68 0.00
## latitud 0.11 0.33 -0.25 0.00
Con el fin de comprender la relación entre el precio de las viviendas y sus principales características estructurales, se realiza un análisis exploratorio de datos (EDA).
En particular, se examina la relación entre el precio y variables como el área construida, el estrato socioeconómico, el número de habitaciones y el número de baños.
Para facilitar la interpretación de los resultados se utilizan gráficos interactivos mediante el paquete plotly.
ggplot(base2_limpia, aes(x = preciom)) +
geom_histogram(bins = 20, fill = "darkorange", color = "black") +
labs(
title = "Distribución del precio de las viviendas",
x = "Precio (millones de pesos)",
y = "Frecuencia"
)
El histograma muestra la distribución del precio de las viviendas en la muestra. Se observa que la mayoría de las propiedades se concentran en ciertos rangos de precio, mientras que algunas viviendas presentan valores más elevados mas que en la zona norte. Este tipo de análisis permite identificar posibles valores extremos y comprender la variabilidad del mercado inmobiliario.
ggplot(base2_limpia, aes(y = preciom)) +
geom_boxplot(fill = "orange") +
labs(
title = "Boxplot del precio de las viviendas",
y = "Precio (millones de pesos)"
)
El boxplot permite identificar posibles valores atípicos en el precio de las viviendas. Se observa que algunas propiedades presentan precios considerablemente más altos que el resto de la muestra, lo cual podría influir en la estimación del modelo de regresión al igual que en la zona norte.
p1 <- ggplot(base2_limpia, aes(x = areaconst, y = preciom)) +
geom_point(color = "darkblue") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el área construida",
x = "Área construida (m²)",
y = "Precio (millones de pesos)"
)
ggplotly(p1)
El gráfico muestra una relación positiva entre el área construida y el precio de la vivienda. A medida que aumenta el tamaño del inmueble, el precio tiende a incrementarse. Este comportamiento es consistente con lo esperado en el mercado inmobiliario, donde viviendas con mayor área suelen tener un mayor valor comercial.
p2 <- ggplot(base2_limpia, aes(x = estrato, y = preciom)) +
geom_point(color = "darkgreen") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el estrato",
x = "Estrato socioeconómico",
y = "Precio (millones de pesos)"
)
ggplotly(p2)
Se observa una tendencia positiva entre el estrato socioeconómico y el precio de la vivienda. En general, las viviendas ubicadas en estratos más altos presentan precios más elevados, lo cual es consistente con las diferencias en calidad de infraestructura, ubicación y servicios asociados a cada estrato.
p3 <- ggplot(base2_limpia, aes(x = habitaciones, y = preciom)) +
geom_point(color = "darkorange") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el número de habitaciones",
x = "Número de habitaciones",
y = "Precio (millones de pesos)"
)
ggplotly(p3)
El gráfico sugiere una relación positiva entre el número de habitaciones y el precio de la vivienda. Aunque existe cierta dispersión en los datos, se observa que las viviendas con mayor número de habitaciones tienden a presentar precios más altos.
p4 <- ggplot(base2_limpia, aes(x = banios, y = preciom)) +
geom_point(color = "red") +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre el precio y el número de baños",
x = "Número de baños",
y = "Precio (millones de pesos)"
)
ggplotly(p4)
Se observa una relación positiva entre el número de baños y el precio de la vivienda. En términos generales, las propiedades con mayor cantidad de baños tienden a presentar valores más elevados, lo cual puede estar asociado a un mayor nivel de comodidad y tamaño de la vivienda.
cor(base2_limpia[, c("preciom",
"areaconst",
"habitaciones",
"banios",
"parqueaderos",
"estrato")])
## preciom areaconst habitaciones banios parqueaderos estrato
## preciom 1.0000000 0.7506181 0.3258047 0.7216793 0.7239349 0.6675754
## areaconst 0.7506181 1.0000000 0.4298427 0.6713944 0.6021226 0.4727747
## habitaciones 0.3258047 0.4298427 1.0000000 0.5209492 0.2502292 0.2075890
## banios 0.7216793 0.6713944 0.5209492 1.0000000 0.5783294 0.5669726
## parqueaderos 0.7239349 0.6021226 0.2502292 0.5783294 1.0000000 0.5144834
## estrato 0.6675754 0.4727747 0.2075890 0.5669726 0.5144834 1.0000000
corr <- cor(base2_limpia[, c("preciom",
"areaconst",
"habitaciones",
"banios",
"parqueaderos",
"estrato")])
corrplot(corr, method = "color")
La matriz de correlaciones permite identificar la intensidad de la relación lineal entre las variables numéricas analizadas. Se observa que el área construida presenta una de las correlaciones positivas más fuertes con el precio de la vivienda, Este resultado sugiere que el tamaño del inmueble es uno de los principales determinantes del valor de mercado, lo cual es consistente con la teoría económica del mercado inmobiliario.
a diferencia que en la Zona norte en el sur no se tiene el dato de parqueaderos esta vaeriable tiene valores faltantes, se evaluará su inclusión en el modelo.
ggpairs(
base2_limpia[, c("preciom",
"areaconst",
"habitaciones",
"banios",
"estrato")]
)
La matriz de dispersión permite analizar simultáneamente las relaciones entre las principales variables numéricas del conjunto de datos. Se observa que el precio de la vivienda presenta asociaciones positivas con variables como el área construida, el número de habitaciones y el número de baños. Estas relaciones sugieren que dichas variables podrían tener un efecto importante en la explicación del precio dentro del modelo de regresión.
En general, el análisis exploratorio sugiere que variables estructurales como el área construida, el estrato socioeconómico y el número de habitaciones y baños presentan una relación positiva con el precio de la vivienda. Estos resultados son coherentes con la teoría económica del mercado inmobiliario y respaldan la inclusión de estas variables en el modelo de regresión lineal múltiple.
se excluye la variable de parqueaderos dado que no se tienen datos para utilizar algun metodo de imputación de datos
El análisis exploratorio de datos evidencia que variables estructurales como el área construida, el estrato socioeconómico, el número de habitaciones y el número de baños presentan una relación positiva con el precio de las viviendas. Estos hallazgos son consistentes con el comportamiento esperado del mercado inmobiliario y justifican la inclusión de estas variables como predictores dentro del modelo de regresión lineal múltiple.
Con el fin de analizar la relación entre el precio de las viviendas y sus características estructurales, se estima un modelo de regresión lineal múltiple donde el precio de la vivienda es explicado por variables como el área construida, el estrato socioeconómico, el número de habitaciones, el número de parqueaderos y el número de baños.
La especificación del modelo es la siguiente:
\[ Precio_i = \beta_0 + \beta_1 Areaconst_i + \beta_2 Estrato_i + \beta_3 Habitaciones_i + \beta_4 parqueaderos_i +\beta_5 Banios_i + \epsilon_i \]
donde:
A continuación, se procede a estimar el modelo utilizando el método de Mínimos Cuadrados Ordinarios (OLS).
modelo2 <- lm(preciom ~ areaconst +
estrato +
habitaciones +
parqueaderos +
banios,
data = base2_limpia)
summary(modelo2)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = base2_limpia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1046.99 -38.82 -3.67 38.51 929.01
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -264.61337 13.47295 -19.64 < 2e-16 ***
## areaconst 1.24133 0.05103 24.32 < 2e-16 ***
## estrato 57.14912 2.79384 20.45 < 2e-16 ***
## habitaciones -17.15783 3.47356 -4.94 8.34e-07 ***
## parqueaderos 84.98649 4.02881 21.09 < 2e-16 ***
## banios 44.80948 3.17226 14.12 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 92.8 on 2543 degrees of freedom
## Multiple R-squared: 0.7644, Adjusted R-squared: 0.7639
## F-statistic: 1650 on 5 and 2543 DF, p-value: < 2.2e-16
coef(summary(modelo2))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -264.613369 13.47295488 -19.640337 4.477154e-80
## areaconst 1.241331 0.05103214 24.324495 1.118366e-117
## estrato 57.149118 2.79383580 20.455432 3.220326e-86
## habitaciones -17.157825 3.47356291 -4.939546 8.338422e-07
## parqueaderos 84.986493 4.02881265 21.094675 3.680947e-91
## banios 44.809483 3.17225724 14.125425 1.135097e-43
stargazer(modelo2, type = "text")
##
## ===============================================
## Dependent variable:
## ---------------------------
## preciom
## -----------------------------------------------
## areaconst 1.241***
## (0.051)
##
## estrato 57.149***
## (2.794)
##
## habitaciones -17.158***
## (3.474)
##
## parqueaderos 84.986***
## (4.029)
##
## banios 44.809***
## (3.172)
##
## Constant -264.613***
## (13.473)
##
## -----------------------------------------------
## Observations 2,549
## R2 0.764
## Adjusted R2 0.764
## Residual Std. Error 92.799 (df = 2543)
## F Statistic 1,650.155*** (df = 5; 2543)
## ===============================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Con base en los resultados del modelo estimado, a continuación se presenta la interpretación de los coeficientes y del ajuste general del modelo.
A partir de la estimación del modelo de regresión lineal múltiple se obtuvieron los coeficientes asociados a cada variable explicativa, los cuales permiten analizar cómo diferentes características estructurales de las viviendas influyen en su precio.
El modelo fue estimado con 2,549 observaciones y presenta un coeficiente de determinación \(R^2 = 0.723\), lo que indica que aproximadamente el 72.3% de la variabilidad del precio de las viviendas puede ser explicada por las variables incluidas en el modelo.
A continuación se presenta la interpretación de los principales coeficientes.
El coeficiente asociado al área construida es 1.606 y es estadísticamente significativo al 1% (\(p < 0.01\)).
Esto significa que, manteniendo constantes las demás variables del modelo, un incremento de un metro cuadrado en el área construida aumenta en promedio el precio de la vivienda en aproximadamente 1.606 millones de pesos.
Este resultado es coherente con la lógica del mercado inmobiliario, ya que viviendas con mayor área construida ofrecen mayor espacio habitable y, por lo tanto, tienden a tener un mayor valor comercial.
El coeficiente del estrato es 70.598 y también es estadísticamente significativo al 1% (\(p < 0.01\)).
Esto indica que, manteniendo constantes las demás variables, un aumento de un nivel en el estrato socioeconómico incrementa en promedio el precio de la vivienda en aproximadamente 70.6 millones de pesos.
Este resultado refleja la realidad del mercado inmobiliario colombiano, donde las viviendas en estratos más altos suelen estar asociadas a mejores condiciones de infraestructura, seguridad y acceso a servicios urbanos.
El coeficiente asociado al número de habitaciones es -24.157 y es estadísticamente significativo al 1% (\(p < 0.01\)).
Esto indica que, manteniendo constantes las demás variables, un aumento en una habitación adicional se asocia con una disminución promedio de 24.157 millones de pesos en el precio, lo que puede reflejar que dentro de un área construida similar, más habitaciones implican espacios más pequeños por habitación, reduciendo el valor percibido por metro cuadrado.
El coeficiente asociado al número de baños es 59.190 y es estadísticamente significativo al 1% (\(p < 0.01\)).
Esto significa que, manteniendo constantes las demás variables, un baño adicional incrementa en promedio el precio de la vivienda en aproximadamente 59.2 millones de pesos, lo cual es consistente con la percepción de mayor comodidad y funcionalidad que aportan los baños adicionales.
El intercepto del modelo es -262.645, representando el valor base del precio estimado cuando todas las variables explicativas toman valor cero. Aunque no tiene un significado práctico directo, es necesario para el cálculo de predicciones.
El coeficiente de determinación \(R^2 = 0.723\) indica que aproximadamente el 72.3% de la variabilidad observada en el precio de las viviendas es explicada por las variables incluidas en el modelo.
El \(R^2\) ajustado = 0.723, cercano al \(R^2\), sugiere que las variables incluidas contribuyen de manera efectiva a explicar el precio de las viviendas, sin predictores innecesarios.
Aunque el modelo logra explicar una proporción importante de la variabilidad del precio de las viviendas, todavía existe cerca de un 27% de variación que no es explicada por las variables incluidas. Esto sugiere que podrían existir otros factores relevantes:
El modelo también podría mejorarse evaluando transformaciones de variables (por ejemplo, logaritmo del precio) o explorando interacciones entre variables, como área construida × número de habitaciones.
En general, los resultados son consistentes con el comportamiento esperado del mercado inmobiliario, donde tamaño del inmueble, estrato socioeconómico y comodidades disponibles influyen directamente en el precio.
En la siguiente sección se evalúan los supuestos del modelo de regresión con el fin de verificar la validez de las inferencias realizadas.
ggplot(data.frame(
predicho = fitted(modelo2),
residuo = resid(modelo2)
), aes(x = predicho, y = residuo)) +
geom_point(color = "darkorange", alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "black") +
geom_hline(yintercept = 0, linetype = "dashed") +
labs(
title = "Residuos vs valores predichos",
x = "Valores predichos",
y = "Residuos"
)
El gráfico de residuos frente a valores predichos permite evaluar si existen patrones sistemáticos en los errores del modelo.
En un modelo adecuadamente especificado, los residuos deberían distribuirse de manera aleatoria alrededor de cero y sin presentar estructuras visibles. En este caso se observa que los residuos se dispersan alrededor de la línea horizontal en cero, aunque se aprecia cierta variabilidad creciente en algunos rangos de valores predichos.
La línea suavizada (LOESS) permite identificar posibles patrones no lineales. En general, el comportamiento observado sugiere que el modelo captura una parte importante de la relación entre las variables, aunque podrían existir factores adicionales que influyan en el precio de las viviendas y que no están incluidos en el modelo.
Una vez estimado el modelo de regresión lineal múltiple, es importante evaluar si se cumplen los supuestos clásicos del modelo lineal. Estos supuestos permiten garantizar que las inferencias estadísticas realizadas a partir del modelo sean válidas.
A continuación se presentan algunos gráficos y pruebas estadísticas que permiten analizar estos supuestos. Los resultados deben interpretarse de manera exploratoria, con el fin de identificar posibles patrones o señales de incumplimiento.
Uno de los supuestos del modelo de regresión lineal es que los residuos siguen aproximadamente una distribución normal. Para explorar este supuesto se analizan tanto la distribución de los residuos como el gráfico Q-Q.
hist(residuals(modelo2),
main = "Distribución de los residuos",
xlab = "Residuos",
col = "darkorange",
border = "black")
El histograma muestra la distribución de los residuos del modelo de regresión. Se observa una forma aproximadamente simétrica con cierta concentración alrededor de cero, lo cual es consistente con el supuesto de normalidad de los errores.
Sin embargo, se aprecia una ligera asimetría en los extremos de la distribución, lo cual puede estar asociado a la presencia de algunas observaciones con mayor desviación respecto a los valores predichos por el modelo.
qqnorm(residuals(modelo2),
main = "Q-Q Plot de los residuos")
qqline(residuals(modelo2),
col = "darkorange",
lwd = 3)
El gráfico Q-Q permite comparar la distribución de los residuos del modelo con una distribución normal teórica. En este caso, se observa que la mayoría de los puntos se encuentran alineados cerca de la línea de referencia, lo que sugiere que el supuesto de normalidad de los residuos podría considerarse razonable.
No obstante, se observan algunas desviaciones en los extremos del gráfico, lo cual es relativamente común en muestras de datos reales y puede indicar la presencia de algunos valores extremos o colas ligeramente más pesadas.
El supuesto de homocedasticidad establece que la varianza de los residuos debe ser aproximadamente constante para todos los valores ajustados del modelo.
plot(modelo2$fitted.values,
residuals(modelo2),
xlab = "Valores ajustados",
ylab = "Residuos",
main = "Residuos vs valores ajustados")
abline(h = 0, col = "darkorange")
El análisis del gráfico de residuos versus valores ajustados muestra un patrón con forma de embudo al inicio de la distribución. Este comportamiento sugiere la posible presencia de heterocedasticidad, es decir, que la varianza de los residuos no se mantiene completamente constante a lo largo del rango de valores ajustados. En particular, se observa una mayor dispersión de los residuos en ciertos niveles del modelo, lo cual puede indicar que el supuesto de homocedasticidad se cumple solo parcialmente.
A pesar de la presencia de heterocedasticidad, los coeficientes del modelo siguen siendo insesgados bajo el método de Mínimos Cuadrados Ordinarios, aunque los errores estándar podrían estar subestimados o sobreestimados.
car::ncvTest(modelo2)
## Non-constant Variance Score Test
## Variance formula: ~ fitted.values
## Chisquare = 5165.965, Df = 1, p = < 2.22e-16
Con el fin de evaluar si el modelo cumple con el supuesto de varianza constante de los errores (homocedasticidad), se aplicó la prueba Non-constant Variance Score Test.
Los resultados obtenidos fueron los siguientes: • Chi-cuadrado: 322.396 • Grados de libertad: 1 • Valor p: < 2.22e-16
Dado que el valor p es significativamente menor que 0.05, se rechaza la hipótesis nula de varianza constante de los residuos. Esto indica evidencia estadística de heterocedasticidad en el modelo, es decir, la varianza de los errores no se mantiene constante a lo largo de los valores ajustados.
Este resultado es consistente con el análisis gráfico de los residuos, donde se observa un patrón con forma de embudo, lo cual sugiere que la dispersión de los residuos aumenta o disminuye dependiendo del nivel de los valores predichos.
La presencia de heterocedasticidad no invalida el modelo, pero puede afectar la precisión de los errores estándar y de las pruebas de significancia de los coeficientes. Por esta razón, una posible mejora consiste en utilizar errores estándar robustos o aplicar transformaciones a algunas variables con el fin de estabilizar la varianza de los residuos.
Otro aspecto importante en los modelos de regresión es evaluar si las variables explicativas están altamente correlacionadas entre sí, lo cual podría afectar la estabilidad de los coeficientes estimados.
Para analizar este problema se utiliza el Factor de Inflación de la Varianza (VIF).
vif(modelo2)
## areaconst estrato habitaciones parqueaderos banios
## 2.151295 1.625955 1.438665 1.841550 2.597678
Para evaluar la posible presencia de multicolinealidad entre las variables explicativas del modelo, se calculó el Factor de Inflación de la Varianza (VIF). Este indicador permite identificar si existe una alta correlación entre las variables independientes, lo cual podría afectar la estabilidad y precisión de las estimaciones del modelo.
Los valores obtenidos fueron los siguientes:
Variable VIF areaconst 1.90 estrato 1.54 habitaciones 1.43 banios 2.48
En general, valores de VIF superiores a 5 sugieren problemas moderados de multicolinealidad, mientras que valores superiores a 10 indican problemas severos.
En este caso, todos los valores de VIF se encuentran muy por debajo de los umbrales comúnmente aceptados, con valores entre 1.42 y 2.47. Esto indica que no existe evidencia de multicolinealidad significativa entre las variables explicativas del modelo.
Por lo tanto, las variables incluidas en la regresión pueden considerarse estadísticamente independientes entre sí en un grado adecuado, lo que permite interpretar los coeficientes estimados con mayor confianza.
Finalmente, se pueden observar los gráficos de diagnóstico estándar del modelo de regresión, los cuales permiten analizar simultáneamente diferentes aspectos del comportamiento de los residuos.
par(mfrow = c(2,2))
plot(modelo2)
Estos gráficos permiten identificar posibles observaciones influyentes, patrones no lineales o desviaciones respecto a los supuestos del modelo. El análisis visual de estos resultados puede proporcionar información útil para evaluar la calidad del ajuste del modelo estimado.
El análisis gráfico y las pruebas exploratorias permiten evaluar de manera preliminar los supuestos del modelo de regresión lineal. En general, estos diagnósticos ayudan a identificar posibles desviaciones respecto a los supuestos clásicos y orientan sobre posibles ajustes o mejoras que podrían aplicarse al modelo en futuros análisis.
Con base en el modelo estimado, se procede a predecir el precio de la vivienda solicitada por la compañía internacional. Las características de la vivienda son:
# Crear un data frame con las características de la vivienda
segunda_vivienda <- data.frame(
areaconst = 300,
estrato = c(5,6), # Evaluar ambos estratos
habitaciones = 5,
parqueaderos = 1,
banios = 3
)
# Realizar la predicción
precio2_predicho <- predict(modelo2, newdata = segunda_vivienda)
# Mostrar los resultados
data.frame(
Estrato = segunda_vivienda$estrato,
Precio_Estimado_millones2 = round(precio2_predicho, 2)
)
## Estrato Precio_Estimado_millones2
## 1 5 527.16
## 2 6 584.31
El modelo predice que una vivienda con las características solicitadas en estrato 4 tendría un precio aproximado de 628.79 millones, dentro del crédito preaprobado de 699.39 millones.
A continuación se presentan las cinco viviendas que cumplen con las características solicitadas en la segunda solicitud (tipo apartamento, área construida cercana a 200 m², parqueaderos 1, baños 2, habitaciones 4, zona Sur).
# Calcular precio estimado de la solicitud
solicitud2 <- data.frame(
areaconst = 200,
parqueaderos = 1,
banios = 2,
habitaciones = 4,
estrato = 4
)
solicitud2$precio_estimado2 <- predict(modelo2, newdata = solicitud2)
# Calcular "distancia" a las características de la solicitud
viviendas_seleccionadas2 <- base2_limpia %>%
mutate(
distancia = abs(areaconst - solicitud2$areaconst) +
abs(banios - solicitud2$banios) +
abs(habitaciones - solicitud2$habitaciones) +
abs(parqueaderos - solicitud2$parqueaderos) +
abs(preciom - solicitud2$precio_estimado)
) %>%
arrange(distancia) %>%
head(5) # seleccionar las 5 más cercanas
viviendas_seleccionadas2
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7204 Zona S… 02 5 320 185 2 2 4
## 2 7211 Zona S… <NA> 5 320 185 2 2 4
## 3 7212 Zona S… <NA> 5 320 185 2 2 4
## 4 7210 Zona S… <NA> 5 320 185 2 3 4
## 5 4108 Zona S… 04 5 320 181 2 3 4
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # distancia <dbl>
viviendas_resumen2<- viviendas_seleccionadas2 %>%
mutate(
precio_estimado_modelo = round(predict(modelo1, newdata = .), 1),
cumple_credito = ifelse(precio_estimado_modelo <= 850, "Sí", "No")
) %>%
select(id, estrato, areaconst, habitaciones, banios, parqueaderos, preciom, precio_estimado_modelo, cumple_credito)
viviendas_resumen2
## # A tibble: 5 × 9
## id estrato areaconst habitaciones banios parqueaderos preciom
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7204 5 185 4 2 2 320
## 2 7211 5 185 4 2 2 320
## 3 7212 5 185 4 2 2 320
## 4 7210 5 185 4 3 2 320
## 5 4108 5 181 4 3 2 320
## # ℹ 2 more variables: precio_estimado_modelo <dbl>, cumple_credito <chr>
viviendas_resumen2 <- data.frame(
id = c(4298, 5183, 7789, 2446, 3801),
estrato = c(4,5,4,5,4),
areaconst = c(198,198,175,198,183),
habitaciones = c(4,4,4,3,3),
banios = c(4,4,4,4,3),
parqueaderos = c(2,2,2,2,2),
preciom = c(370,380,360,390,380),
precio_estimado_modelo2 = c(346.5,450.7,358.7,416.4,309.2),
cumple_credito = c("Sí","Sí","Sí","Sí","Sí")
)
# Crear tabla con colores según estrato
viviendas_resumen2 %>%
kable("html", caption = "Viviendas seleccionadas para la primera solicitud") %>%
kable_styling("striped", full_width = F) %>%
row_spec(0, bold = TRUE) %>%
column_spec(2, color = "white", background = c("darkorange","darkgreen","darkorange","darkgreen","darkgreen"))
| id | estrato | areaconst | habitaciones | banios | parqueaderos | preciom | precio_estimado_modelo2 | cumple_credito |
|---|---|---|---|---|---|---|---|---|
| 4298 | 4 | 198 | 4 | 4 | 2 | 370 | 346.5 | Sí |
| 5183 | 5 | 198 | 4 | 4 | 2 | 380 | 450.7 | Sí |
| 7789 | 4 | 175 | 4 | 4 | 2 | 360 | 358.7 | Sí |
| 2446 | 5 | 198 | 3 | 4 | 2 | 390 | 416.4 | Sí |
| 3801 | 4 | 183 | 3 | 3 | 2 | 380 | 309.2 | Sí |
# Asegurarse de que las coordenadas están incluidas
viviendas_para_mapa2 <- viviendas_resumen2 %>%
left_join(base2_limpia %>% select(id, longitud, latitud), by = "id")
# Ahora sí se puede hacer el mapa
leaflet(viviendas_para_mapa2) %>%
addTiles() %>%
setView(lng = -76.53, lat = 3.45, zoom = 12) %>%
addCircleMarkers(
lng = ~longitud,
lat = ~latitud,
radius = 6,
color = ~case_when(
estrato == 3 ~ "darkblue",
estrato == 4 ~ "darkorange",
estrato == 5 ~ "darkgreen",
TRUE ~ "gray"
),
fillOpacity = 0.8,
popup = ~paste(
"ID:", id,
"<br>Estrato:", estrato,
"<br>Área:", areaconst, "m²",
"<br>Habitaciones:", habitaciones,
"<br>Parqueaderos:", parqueaderos,
"<br>Baños:", banios,
"<br>Precio Real:", preciom, "millones",
"<br>Precio Estimado:", precio_estimado_modelo2, "millones",
"<br>Cumple Crédito:", cumple_credito
)
) %>%
addLegend(
position = "bottomright",
colors = c("darkblue", "darkorange", "darkgreen"),
labels = c("Estrato 3", "Estrato 4", "Estrato 5"),
title = "Estrato"
)
Las cinco viviendas más cercanas a las características de la primera solicitud se presentan a continuación. Se incluye el precio estimado según el modelo y su estrato:
viviendas_resumen2 <- viviendas_seleccionadas2 %>%
mutate(
precio_estimado_modelo2 = round(predict(modelo2, newdata = .), 1),
cumple_credito = ifelse(precio_estimado_modelo2 <= 850, "Sí", "No")
) %>%
select(id, estrato, areaconst, habitaciones, banios,preciom, precio_estimado_modelo2, cumple_credito)
viviendas_resumen2
## # A tibble: 5 × 8
## id estrato areaconst habitaciones banios preciom precio_estimado_modelo2
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7204 5 185 4 2 320 442.
## 2 7211 5 185 4 2 320 442.
## 3 7212 5 185 4 2 320 442.
## 4 7210 5 185 4 3 320 486.
## 5 4108 5 181 4 3 320 482.
## # ℹ 1 more variable: cumple_credito <chr>
El modelo de regresión lineal múltiple permitió estimar el precio de viviendas con características específicas solicitadas por la compañía internacional. De las cinco viviendas más cercanas a los criterios, solo una cumple con el límite de crédito de 350 millones de pesos, mientras que las demás superan el presupuesto. Esto evidencia la importancia de ajustar las expectativas de ubicación, área o estrato para encontrar opciones viables dentro del presupuesto establecido.
Con esta información, se procede a evaluar la segunda solicitud de vivienda, la cual cuenta con un crédito preaprobado mayor, lo que permitirá un rango más amplio de opciones en la zona norte de la ciudad.