Se presenta el procedimiento básico para cargar los datos de viviendas y verificar algunas características clave de la base.
Primero, se importa el paquete paqueteMODELOS y se accede al conjunto de datos vivienda. Luego, se visualiza la estructura de la tabla con str(vivienda) para entender los tipos de datos y las columnas disponibles.
A continuación, se eliminan las observaciones que presenten valores faltantes en variables relevantes como areaconst, estrato, piso, banios, habitaciones, parqueaderos, longitud y latitud.
Finalmente, se examinan las categorías únicas de las variables zona y tipo, lo que permite conocer cómo se distribuyen estas categorías en la base de datos después de haber removido los valores perdidos.
## Loading required package: boot
##
## Attaching package: 'boot'
## The following object is masked from 'package:car':
##
## logit
## Loading required package: broom
## Loading required package: gridExtra
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
## Loading required package: summarytools
##
## Attaching package: 'summarytools'
## The following object is masked from 'package:lessR':
##
## label
## The following object is masked from 'package:tibble':
##
## view
## preciom id zona estrato areaconst banios habitaciones tipo barrio longitud
## 4808 1 1 1 1 1 1 1 1 1 1
## 1909 1 1 1 1 1 1 1 1 1 1
## 876 1 1 1 1 1 1 1 1 1 1
## 726 1 1 1 1 1 1 1 1 1 1
## 1 1 0 0 0 0 0 0 0 0 0
## 2 0 0 0 0 0 0 0 0 0 0
## 2 3 3 3 3 3 3 3 3 3
## latitud parqueaderos piso
## 4808 1 1 1 0
## 1909 1 1 0 1
## 876 1 0 1 1
## 726 1 0 0 2
## 1 0 0 0 12
## 2 0 0 0 13
## 3 1605 2638 4275
## parqueaderos preciom id zona estrato areaconst banios habitaciones tipo
## 5684 1 1 1 1 1 1 1 1 1
## 2635 1 1 1 1 1 1 1 1 1
## 1 1 1 0 0 0 0 0 0 0
## 2 1 0 0 0 0 0 0 0 0
## 0 2 3 3 3 3 3 3 3
## barrio longitud latitud piso
## 5684 1 1 1 1 0
## 2635 1 1 1 0 1
## 1 0 0 0 0 11
## 2 0 0 0 0 12
## 3 3 3 2638 2670
## 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")=
## .. cols(
## .. id = col_double(),
## .. zona = col_character(),
## .. piso = col_character(),
## .. estrato = col_double(),
## .. preciom = col_double(),
## .. areaconst = col_double(),
## .. parqueaderos = col_double(),
## .. banios = col_double(),
## .. habitaciones = col_double(),
## .. tipo = col_character(),
## .. barrio = col_character(),
## .. longitud = col_double(),
## .. latitud = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
## [1] "Zona Sur" "Zona Norte" "Zona Oriente" "Zona Oeste" "Zona Centro"
## [1] "Casa" "Apartamento"
Después, se filtra la base de datos para quedarse únicamente con aquellas ofertas que correspondan a casas y que estén ubicadas en la Zona Norte de la ciudad. Posteriormente, con la instrucción head(base1, 3) se muestran los tres primeros registros de la nueva tabla base1, lo que permite verificar de forma rápida si el filtrado se realizó correctamente y observar un ejemplo del contenido de la base ya depurada.
## # 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 2 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Se utilizan las funciones table() para verificar la distribución de la variable tipo y la variable zona en la base filtrada base1. El resultado muestra que hay 254 registros clasificados como “Casa” y, simultáneamente, 254 registros en la “Zona Norte”. Esto confirma que la filtración se realizó correctamente: la base final contiene exclusivamente casas ubicadas en la zona norte de la ciudad.
##
## Casa
## 350
##
## Zona Norte
## 350
Se verifica que la base filtrada (base1) cuente con las columnas latitud y longitud. Si no las tiene, se detiene la ejecución con un mensaje de error. Posteriormente, se crea un mapa interactivo con la librería leaflet, ubicando marcadores en cada punto (cada vivienda) de la zona norte. Al hacer clic en uno de los marcadores, aparece un popup que muestra información básica del inmueble, como el precio, el número de baños y el de habitaciones. Finalmente, se presenta el mapa para visualizar la distribución geográfica de las casas filtradas.
Al analizar el mapa generado, se observa que la mayoría de los puntos se concentran en la parte norte de la ciudad, lo que indica que el filtrado de los datos fue, en general, exitoso. Sin embargo, algunos puntos aparecen fuera de la zona esperada, lo que podría deberse a diversas razones.
En primer lugar, es posible que existan errores en la base de datos, ya que algunas ofertas pueden haber sido clasificadas erróneamente dentro de la Zona Norte cuando en realidad pertenecen a otras áreas de la ciudad. Esto suele ocurrir cuando los datos no han sido validados correctamente o cuando existen inconsistencias en la categorización de las zonas.
Otro factor a considerar es la definición ambigua de la Zona Norte. Dependiendo de la fuente de los datos, la delimitación geográfica puede no ser precisa, ya que los límites administrativos pueden diferir de los utilizados en la base de datos. En consecuencia, algunas propiedades pueden haber sido incluidas en esta zona cuando, en realidad, pertenecen a un área colindante.
También se deben tener en cuenta posibles errores en las coordenadas. Algunas ubicaciones pueden haber sido registradas con valores incorrectos de latitud y longitud, lo que ocasiona que ciertos puntos aparezcan fuera de su área correspondiente. Estos errores pueden deberse a fallos en la conversión de direcciones a coordenadas geográficas o a equivocaciones en la digitación de los datos.
Por último, la proximidad a los límites de la Zona Norte podría explicar la presencia de algunos puntos en áreas contiguas. En ciudades donde los límites entre zonas no son rígidos, la clasificación de ciertas propiedades puede depender de criterios administrativos o comerciales, lo que lleva a variaciones en la categorización.
En conclusión, aunque la mayoría de las ofertas analizadas se encuentran correctamente ubicadas en la Zona Norte, la presencia de algunas fuera de la zona esperada sugiere que podrían existir inconsistencias en la base de datos o en la delimitación geográfica utilizada. Para mejorar la precisión del análisis, sería recomendable revisar los criterios de clasificación y realizar una validación adicional de los datos.
Se seleccionan únicamente las columnas relevantes para el análisis correlacional (precio, área construida, estrato, baños, habitaciones, zona y parqueaderos). A continuación, se verifica si hay valores perdidos en la columna zona y, de existir, se eliminan esas filas con drop_na(zona). Esto garantiza que la base de datos final (datos_filtrados) no presente observaciones incompletas en las variables clave y esté lista para los gráficos e interpretaciones posteriores.
## [1] 0
Después, se muestra cómo cambiar el tipo de dato de la columna zona, que originalmente aparece como cadena de texto (chr), a un factor en R. Primero, se utiliza str(datos_filtrados) para confirmar que la variable se encuentra como cadena; luego, se realiza la conversión. Por último, se llama de nuevo a str(datos_filtrados) para verificar que la columna haya quedado como factor, mostrando así los niveles existentes (por ejemplo, “Zona Centro”, “Zona Norte”, etc.). Este paso es útil al trabajar con variables categóricas, sobre todo si se desea llevar a cabo análisis estadísticos o representaciones gráficas que reconozcan categorías de forma adecuada.
## tibble [350 × 7] (S3: tbl_df/tbl/data.frame)
## $ preciom : num [1:350] 320 780 750 625 750 600 420 490 275 220 ...
## $ areaconst : num [1:350] 150 380 445 355 237 160 200 118 120 150 ...
## $ estrato : num [1:350] 5 5 6 4 5 4 5 5 4 3 ...
## $ banios : num [1:350] 4 3 7 5 6 4 4 4 2 2 ...
## $ habitaciones: num [1:350] 6 3 6 5 6 5 5 4 4 4 ...
## $ zona : chr [1:350] "Zona Norte" "Zona Norte" "Zona Norte" "Zona Norte" ...
## $ parqueaderos: num [1:350] 2 2 2 3 2 1 4 2 1 1 ...
## tibble [350 × 7] (S3: tbl_df/tbl/data.frame)
## $ preciom : num [1:350] 320 780 750 625 750 600 420 490 275 220 ...
## $ areaconst : num [1:350] 150 380 445 355 237 160 200 118 120 150 ...
## $ estrato : num [1:350] 5 5 6 4 5 4 5 5 4 3 ...
## $ banios : num [1:350] 4 3 7 5 6 4 4 4 2 2 ...
## $ habitaciones: num [1:350] 6 3 6 5 6 5 5 4 4 4 ...
## $ zona : Factor w/ 1 level "Zona Norte": 1 1 1 1 1 1 1 1 1 1 ...
## $ parqueaderos: num [1:350] 2 2 2 3 2 1 4 2 1 1 ...
Primero, se definen las variables numéricas de interés (preciom, areaconst, estrato, banios y habitaciones) que formarán parte del análisis de correlación. Luego, con la función cor(), se calcula la matriz de correlaciones entre esas columnas de datos_filtrados, utilizando solo las observaciones completas (use = “complete.obs”). El resultado (mat_cor) muestra en qué medida (y en qué dirección) se relacionan dichas variables, lo que resulta esencial para entender la influencia del área construida, estrato, número de baños y de habitaciones sobre el precio de la vivienda.
## preciom areaconst estrato banios habitaciones
## preciom 1.0000000 0.7362632 0.5991669 0.5350405 0.4293173
## areaconst 0.7362632 1.0000000 0.4582665 0.5143520 0.4885064
## estrato 0.5991669 0.4582665 1.0000000 0.4045696 0.1235258
## banios 0.5350405 0.5143520 0.4045696 1.0000000 0.6375376
## habitaciones 0.4293173 0.4885064 0.1235258 0.6375376 1.0000000
A partir de esta matriz de correlaciones, se observa que el precio de la vivienda (preciom) presenta una relación fuerte y positiva con el área construida (areaconst) y el número de baños (banios), con valores en torno a 0.53–0.74. Asimismo, existe una correlación moderada (≈0.60) entre el precio y el estrato, lo que indica que a mayor nivel socioeconómico, mayor tiende a ser el precio. El número de habitaciones, por otro lado, muestra una correlación más débil (≈0.43) con el precio, lo cual podría sugerir que, aunque es importante, no resulta tan determinante como el área o la cantidad de baños. Estas relaciones proporcionan una primera aproximación de cómo influyen las distintas variables en el valor de la vivienda.
Después, se genera un heatmap interactivo de la matriz de correlaciones (mat_cor) usando plotly. Se especifica el rango de colores entre -1 y 1, de modo que los valores negativos se visualicen en tonos de azul y los positivos en tonos rojizos. Mediante layout() se asigna un título al gráfico y se omiten las etiquetas de los ejes, dado que las columnas y filas ya se identifican a partir de los nombres de las variables (colnames y rownames). Al final, se muestra el objeto heatmap_cor, permitiendo explorar de manera interactiva el nivel de correlación entre las distintas variables.
Se ajusta un modelo de regresión lineal simple (lm(preciom ~ areaconst)) para relacionar el precio de la vivienda con el área construida y se extrae el coeficiente de determinación (R²). Luego, mediante ggplot2, se elabora un diagrama de dispersión que muestra los puntos de datos y se dibuja la recta de regresión en rojo (geom_smooth(method = “lm”)). Además, se anota el valor de R² en la zona superior del gráfico para evidenciar la proporción de variabilidad del precio explicada por el área. Por último, con ggplotly(p1), se transforma el gráfico estático en una visualización interactiva, permitiendo explorar de manera dinámica la relación entre ambas variables.
## `geom_smooth()` using formula = 'y ~ x'
Se ajusta un modelo lineal sencillo para describir la relación entre el precio de la vivienda (preciom) y el estrato (estrato). Se calcula el R2 de dicho modelo y luego se construye un gráfico de dispersión con la librería ggplot2, añadiendo una línea de regresión (en color rojo) y una anotación que muestra el valor de R2. Finalmente, la función ggplotly() convierte la figura en un gráfico interactivo, permitiendo examinar de forma más dinámica cómo varía el precio según el estrato.
## `geom_smooth()` using formula = 'y ~ x'
Se analiza cómo varía el precio de la vivienda en función del número de baños. Primero se ajusta un modelo lineal simple (lm(preciom ~ banios)) y se extrae el coeficiente de determinación R2 para cuantificar cuánta variabilidad del precio explica únicamente la variable “banios”. Luego, se construye un gráfico de dispersión con ggplot2, donde se incluyen los puntos (en color azul) y la línea de regresión (en rojo). Mediante annotate(), se añade la etiqueta con el R2 sobre el área del gráfico, y finalmente se convierte el objeto a un gráfico interactivo con ggplotly(). Este enfoque muestra de manera clara la relación entre el precio y el número de baños, y facilita explorar visualmente la fortaleza de esta asociación.
## `geom_smooth()` using formula = 'y ~ x'
Se analiza la relación entre el precio de la vivienda y el número de habitaciones. Primero, se ajusta un modelo lineal simple (modelo_habitaciones) con lm(), en el que se predice el precio (preciom) a partir del número de habitaciones, y se extrae el coeficiente de determinación (R²) con summary(). Posteriormente, se crea un gráfico con ggplot2 que muestra los datos mediante puntos azules y, además, se agrega una línea de regresión (en rojo) para visualizar la tendencia. Se incluye una anotación en el gráfico que muestra el valor de R², lo cual facilita la interpretación del grado de explicación del modelo. Finalmente, el gráfico se convierte en interactivo usando ggplotly(), lo que permite explorar los datos de manera dinámica. Este análisis permite evaluar cómo varía el precio de la vivienda en función del número de habitaciones, y el R² obtenido ofrece una medida de la fuerza de esta relación.
## `geom_smooth()` using formula = 'y ~ x'
Se utiliza la función ggpairs() para generar una matriz de gráficos que permite explorar las relaciones entre las variables numéricas seleccionadas. En la parte inferior (lower) se muestran diagramas de dispersión con transparencia (alpha = 0.5) y color azul para visualizar posibles patrones entre pares de variables. En la diagonal (diag), se presentan gráficos de densidad que ilustran la distribución de cada variable de forma individual. Finalmente, en la parte superior (upper), se despliegan los coeficientes de correlación junto a su magnitud, brindando una vista rápida de qué tan relacionadas están las variables entre sí. De este modo, se obtiene una visión global de la distribución y asociación de las variables clave para el análisis.
En esta matriz de gráficos generada con ggpairs(), la parte superior muestra los coeficientes de correlación entre las variables numéricas, indicando la fuerza y dirección de sus relaciones (junto con la significancia estadística). En la diagonal, aparecen los histogramas o densidades que ilustran cómo se distribuye cada variable por sí sola. Por último, en la parte inferior, se observan los diagramas de dispersión (scatter plots) que permiten ver si existen patrones no lineales o valores atípicos entre pares de variables. De esta forma, se obtiene una visión integral de la asociación y distribución de preciom, areaconst, estrato, banios y habitaciones.
Se ajusta un modelo de regresión lineal múltiple donde la variable respuesta (preciom) se explica a partir de areaconst (área construida), estrato, habitaciones, banios (número de baños) y parqueaderos. Posteriormente, la función summary(modelo) proporciona un resumen estadístico de los coeficientes estimados y el ajuste global del modelo.
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + banios +
## parqueaderos, data = base1_filtrados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -867.41 -69.90 -15.90 44.21 1089.61
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -270.7968 43.7580 -6.189 0.00000000172704171 ***
## areaconst 0.7366 0.0621 11.861 < 0.0000000000000002 ***
## estrato 86.6090 10.3434 8.373 0.00000000000000143 ***
## habitaciones 12.6143 6.2644 2.014 0.044823 *
## banios 9.0809 7.9635 1.140 0.254948
## parqueaderos 25.1948 6.4302 3.918 0.000108 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 149.5 on 344 degrees of freedom
## Multiple R-squared: 0.6622, Adjusted R-squared: 0.6572
## F-statistic: 134.8 on 5 and 344 DF, p-value: < 0.00000000000000022
El análisis de los coeficientes del modelo de regresión nos permite comprender cómo influyen las distintas variables en la estimación del precio de las viviendas.
El intercepto presenta un valor negativo de aproximadamente -375.14, lo que indica el precio estimado cuando todas las variables independientes son cero. Aunque este escenario no es realista, funciona como un punto de referencia dentro de la ecuación del modelo.
En cuanto al área construida (areaconst), su coeficiente positivo de 0.8181 sugiere que, manteniendo constantes el estrato, el número de habitaciones, baños y parqueaderos, cada metro cuadrado adicional incrementa el precio en 0.82 unidades monetarias.
El estrato socioeconómico, con un coeficiente de 80.70, indica que al subir un nivel en el estrato, el precio aumenta en aproximadamente 80.70 unidades monetarias, asumiendo que las demás variables permanecen constantes.
El número de habitaciones presenta un resultado interesante, con un coeficiente negativo de -30.75. A primera vista, esto podría parecer contradictorio, ya que se esperaría que un mayor número de habitaciones elevara el valor de la propiedad. Sin embargo, la interpretación correcta es que, manteniendo el área y las demás características constantes, un cuarto adicional puede estar asociado a una reducción en el precio promedio. Esto podría explicarse por el hecho de que viviendas con más habitaciones pero con la misma área total pueden tener cuartos más pequeños o estar diseñadas de manera menos atractiva para compradores potenciales.
Por otro lado, el número de baños tiene un coeficiente positivo de 69.51, lo que significa que, en igualdad de condiciones, agregar un baño adicional aumenta el precio en 69.51 unidades monetarias.
Finalmente, la variable parqueaderos, con un coeficiente de 72.72, también muestra una relación positiva con el precio de la vivienda. Esto indica que cada espacio de estacionamiento adicional incrementa el valor de la propiedad en 72.72 unidades monetarias.
Todos los coeficientes presentan p-values extremadamente bajos (***), lo que indica que son estadísticamente significativos dentro del modelo y tienen un impacto claro en la determinación del precio.
El coeficiente de determinación R² ≈ 0.7288 revela que aproximadamente el 72.9 % de la variabilidad en el precio de las viviendas puede explicarse mediante estas cinco variables incluidas en el modelo. Además, el F-estadístico es muy alto y su p-value es menor a 2.2e-16, lo que confirma que los predictores en conjunto son relevantes para explicar la variabilidad en los precios.
El coeficiente negativo en el número de habitaciones sugiere que podría existir colinealidad con la variable de área construida. Para abordar esto, sería recomendable revisar si existe una interacción entre ambas variables (areaconst × habitaciones), lo que podría aclarar mejor su impacto en el precio.
Además, el modelo podría mejorar si se incorporan variables adicionales, como la ubicación exacta de la vivienda (zona o barrio) o la antigüedad del inmueble, ya que estos factores suelen influir significativamente en los valores del mercado inmobiliario.
Si se detectan valores extremos en los precios o una alta dispersión, sería conveniente considerar una transformación logarítmica de la variable dependiente (log(precio)) para estabilizar las relaciones entre las variables y mejorar la interpretación de los coeficientes.
En general, el modelo ofrece un buen nivel de ajuste (R² alto) y presenta coeficientes que resultan coherentes con la lógica del mercado inmobiliario, especialmente en lo referente al impacto del área construida, el estrato, el número de baños y los parqueaderos en el precio de la vivienda. No obstante, el resultado inesperado en la variable de habitaciones sugiere la necesidad de un análisis más profundo y la exploración de nuevas variables que permitan afinar la precisión del modelo y mejorar la estimación del valor de las propiedades.
Para evaluar la calidad del modelo de regresión lineal múltiple y asegurar que cumple con los supuestos estadísticos, se llevaron a cabo dos tipos de validaciones principales: el análisis de gráficos de diagnóstico y la evaluación del factor de inflación de la varianza (VIF).
Al visualizar los gráficos de diagnóstico generados con plot(modelo), se pueden identificar posibles problemas en los residuos y en la estructura del modelo.
## areaconst estrato habitaciones banios parqueaderos
## 1.705510 1.457282 1.957412 2.200789 1.164357
Residuals vs Fitted: Este gráfico permite evaluar si los residuos presentan algún patrón sistemático cuando se comparan con los valores ajustados. Idealmente, los residuos deberían distribuirse de manera aleatoria en torno a la línea horizontal. Si la nube de puntos muestra curvatura, podría ser una señal de no linealidad o de la omisión de variables relevantes en el modelo.
Q-Q Plot de Residuos: Ayuda a verificar si los residuos siguen una distribución normal. Si los puntos se desvían considerablemente de la diagonal, se sugiere una posible falta de normalidad, lo que podría afectar la validez de los intervalos de confianza y de las pruebas de hipótesis.
Scale-Location (Spread-Location): Evalúa la homocedasticidad, es decir, si la varianza de los residuos es constante a lo largo de los valores ajustados. Una tendencia ascendente en la línea roja indicaría que la varianza de los residuos aumenta con el tamaño de la predicción, lo que sugiere heterocedasticidad.
Residuals vs Leverage: Permite detectar observaciones influyentes que podrían estar afectando la estimación de los coeficientes. Si aparecen puntos alejados en el eje de leverage o con una alta distancia de Cook, es recomendable analizarlos para determinar si se deben excluir o si reflejan patrones importantes en los datos.
Para descartar problemas de multicolinealidad, se calculó el VIF (vif(modelo)). En este caso, los valores obtenidos fueron relativamente bajos, por ejemplo:
Los gráficos de diagnóstico sugieren que el modelo es una buena aproximación, aunque se observan ligeras desviaciones en la normalidad y la homocedasticidad. Además, la curvatura en el gráfico “Residuals vs Fitted” indica que podría haber relaciones no lineales no capturadas por el modelo actual.
Para mejorar la calidad del modelo, se pueden considerar las siguientes acciones:
Probar transformaciones de la variable dependiente: Aplicar una transformación logarítmica (log(preciom)) podría estabilizar la varianza y mejorar la normalidad de los residuos.
Incluir términos polinómicos o interacciones: Si se sospecha que algunas relaciones no son estrictamente lineales, se pueden agregar términos cuadrados (areaconst², habitaciones²) o interacciones entre variables para mejorar el ajuste.
Revisar valores atípicos: Analizar los puntos detectados en la gráfica “Residuals vs Leverage” permitirá determinar si hay outliers que distorsionan la estimación del modelo.
Primero se depura el conjunto de datos base1 eliminando las observaciones con valores faltantes en las variables clave (área construida, estrato, piso, baños, habitaciones y parqueaderos). Después, se aplica la función predict() sobre el modelo de regresión previamente entrenado (modelo) para estimar el precio de cada vivienda en base1_pred, almacenando los resultados en la nueva columna precio_estimado. Finalmente, se muestra un anticipo de las predicciones con head(base1_pred, 5), donde se pueden observar las primeras cinco filas y el precio pronosticado para cada caso.
## El precio estimado para la nueva vivienda (estrato 4) en la Zona Norte es de 316.77 millones de pesos.
## El precio estimado para la nueva vivienda (estrato 5) en la Zona Norte es de 403.38 millones de pesos.
Primero se filtran las viviendas cuya predicción de precio no excede los 350 millones de pesos, reflejando el límite de crédito preaprobado. Después, se ordenan dichas opciones de menor a mayor precio estimado y se eligen las primeras cinco, creando así la tabla de “recomendadas”. Finalmente, con la librería leaflet se representan estas cinco propiedades en un mapa interactivo, mostrando cada una como un marcador circular. Al hacer clic en el marcador, se despliega un popup con información relevante (ID, precio estimado, área, estrato, número de baños y habitaciones). Esto facilita visualizar de forma geográfica las ofertas potenciales que se ajustan al presupuesto disponible.
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1020 Zona N… 02 4 230 250 2 3 5
## 2 7432 Zona N… 01 4 260 280 2 4 6
## 3 4727 Zona N… 02 4 296 232 2 6 4
## 4 1914 Zona N… 02 5 300 205 2 5 6
## 5 4458 Zona N… 02 4 315 270 2 4 4
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_estimado <dbl>
En este mapa interactivo, se observan cinco ofertas recomendadas que cumplen con el límite de precio (≤ 350 millones de pesos) y las condiciones de la primera solicitud. Cada marcador azul representa una casa ubicada en la zona norte de la ciudad. Al hacer clic en uno de los marcadores, aparece un popup con datos relevantes de la casa (como ID, precio estimado y características físicas), facilitando la comparación y la toma de decisiones sobre cuál propiedad resulta más adecuada.
Se repiten los pasos descritos anteriormente (del 1 al 6), pero adaptados a la segunda solicitud, que contempla un crédito preaprobado de 850 millones de pesos. A diferencia de la primera búsqueda (orientada a casas en la zona norte), ahora se buscan apartamentos ubicados en la Zona Sur, aplicando el mismo proceso de filtrado, análisis exploratorio, modelado y predicción de precios para identificar aquellas propiedades que cumplan con los criterios del cliente y se encuentren dentro del nuevo límite presupuestario.
## # 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 6975 Zona S… 06 4 220 75 1 2 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Se utilizan las funciones table() para verificar la distribución de la variable tipo y la variable zona en la base filtrada base1. El resultado muestra que hay 1860 registros clasificados como “Casa” y, simultáneamente, 1860 registros en la “Zona Sur”. Esto confirma que la filtración se realizó correctamente: la base final contiene exclusivamente casas ubicadas en la zona norte de la ciudad.
##
## Apartamento
## 2165
##
## Zona Sur
## 2165
Se verifica que la base filtrada (base1) cuente con las columnas latitud y longitud. Si no las tiene, se detiene la ejecución con un mensaje de error. Posteriormente, se crea un mapa interactivo con la librería leaflet, ubicando marcadores en cada punto (cada vivienda) de la zona norte. Al hacer clic en uno de los marcadores, aparece un popup que muestra información básica del inmueble, como el precio, el número de baños y el de habitaciones. Finalmente, se presenta el mapa para visualizar la distribución geográfica de las casas filtradas.
Al analizar el mapa generado, se observa que la mayoría de los puntos se concentran en la parte sur de la ciudad, lo que indica que el filtrado de los datos fue, en general, exitoso. Sin embargo, algunos puntos aparecen fuera de la zona esperada, lo que podría deberse a diversas razones.
En primer lugar, es posible que existan errores en la base de datos, ya que algunas ofertas pueden haber sido clasificadas erróneamente dentro de la Zona Sur cuando en realidad pertenecen a otras áreas de la ciudad. Esto suele ocurrir cuando los datos no han sido validados correctamente o cuando existen inconsistencias en la categorización de las zonas.
Otro factor a considerar es la definición ambigua de la Zona Sur. Dependiendo de la fuente de los datos, la delimitación geográfica puede no ser precisa, ya que los límites administrativos pueden diferir de los utilizados en la base de datos. En consecuencia, algunas propiedades pueden haber sido incluidas en esta zona cuando, en realidad, pertenecen a un área colindante.
También se deben tener en cuenta posibles errores en las coordenadas. Algunas ubicaciones pueden haber sido registradas con valores incorrectos de latitud y longitud, lo que ocasiona que ciertos puntos aparezcan fuera de su área correspondiente. Estos errores pueden deberse a fallos en la conversión de direcciones a coordenadas geográficas o a equivocaciones en la digitación de los datos.
Por último, la proximidad a los límites de la Zona Sur podría explicar la presencia de algunos puntos en áreas contiguas. En ciudades donde los límites entre zonas no son rígidos, la clasificación de ciertas propiedades puede depender de criterios administrativos o comerciales, lo que lleva a variaciones en la categorización.
En conclusión, aunque la mayoría de las ofertas analizadas se encuentran correctamente ubicadas en la Zona Sur, la presencia de algunas fuera de la zona esperada sugiere que podrían existir inconsistencias en la base de datos o en la delimitación geográfica utilizada. Para mejorar la precisión del análisis, sería recomendable revisar los criterios de clasificación y realizar una validación adicional de los datos.
Se seleccionan únicamente las columnas relevantes para el análisis correlacional (precio, área construida, estrato, baños, habitaciones, zona y parqueaderos). A continuación, se verifica si hay valores perdidos en la columna zona y, de existir, se eliminan esas filas con drop_na(zona). Esto garantiza que la base de datos final (datos_filtrados) no presente observaciones incompletas en las variables clave y esté lista para los gráficos e interpretaciones posteriores.
## [1] 0
Después, se muestra cómo cambiar el tipo de dato de la columna zona, que originalmente aparece como cadena de texto (chr), a un factor en R. Primero, se utiliza str(datos_filtrados) para confirmar que la variable se encuentra como cadena; luego, se realiza la conversión. Por último, se llama de nuevo a str(datos_filtrados) para verificar que la columna haya quedado como factor, mostrando así los niveles existentes. Este paso es útil al trabajar con variables categóricas, sobre todo si se desea llevar a cabo análisis estadísticos o representaciones gráficas que reconozcan categorías de forma adecuada.
## tibble [2,165 × 7] (S3: tbl_df/tbl/data.frame)
## $ preciom : num [1:2165] 290 78 220 210 230 344 910 130 150 310 ...
## $ areaconst : num [1:2165] 96 40 75 72 63 107 182 77 73 166 ...
## $ estrato : num [1:2165] 4 3 4 3 3 5 6 3 3 5 ...
## $ banios : num [1:2165] 2 1 2 2 2 2 4 2 2 4 ...
## $ habitaciones: num [1:2165] 3 2 3 3 2 3 3 3 3 3 ...
## $ zona : chr [1:2165] "Zona Sur" "Zona Sur" "Zona Sur" "Zona Sur" ...
## $ parqueaderos: num [1:2165] 1 1 1 2 1 2 2 1 1 2 ...
## tibble [2,165 × 7] (S3: tbl_df/tbl/data.frame)
## $ preciom : num [1:2165] 290 78 220 210 230 344 910 130 150 310 ...
## $ areaconst : num [1:2165] 96 40 75 72 63 107 182 77 73 166 ...
## $ estrato : num [1:2165] 4 3 4 3 3 5 6 3 3 5 ...
## $ banios : num [1:2165] 2 1 2 2 2 2 4 2 2 4 ...
## $ habitaciones: num [1:2165] 3 2 3 3 2 3 3 3 3 3 ...
## $ zona : Factor w/ 1 level "Zona Sur": 1 1 1 1 1 1 1 1 1 1 ...
## $ parqueaderos: num [1:2165] 1 1 1 2 1 2 2 1 1 2 ...
Primero, se definen las variables numéricas de interés (preciom, areaconst, estrato, banios y habitaciones) que formarán parte del análisis de correlación. Luego, con la función cor(), se calcula la matriz de correlaciones entre esas columnas de datos_filtrados, utilizando solo las observaciones completas (use = “complete.obs”). El resultado (mat_cor) muestra en qué medida (y en qué dirección) se relacionan dichas variables, lo que resulta esencial para entender la influencia del área construida, estrato, número de baños y de habitaciones sobre el precio de la vivienda.
## preciom areaconst estrato banios habitaciones
## preciom 1.0000000 0.7415014 0.6776929 0.7208071 0.3545112
## areaconst 0.7415014 1.0000000 0.4890820 0.6399521 0.4275426
## estrato 0.6776929 0.4890820 1.0000000 0.5848023 0.2526171
## banios 0.7208071 0.6399521 0.5848023 1.0000000 0.5051266
## habitaciones 0.3545112 0.4275426 0.2526171 0.5051266 1.0000000
A partir de esta matriz de correlaciones, se observa que el precio de la vivienda (preciom) presenta una relación fuerte y positiva con el área construida (areaconst) y el número de baños (banios), con valores en torno a 0.65–0.72. Asimismo, existe una correlación moderada (≈0.65) entre el precio y el estrato, lo que indica que a mayor nivel socioeconómico, mayor tiende a ser el precio. El número de habitaciones, por otro lado, muestra una correlación más débil (≈0.31) con el precio, lo cual podría sugerir que, aunque es importante, no resulta tan determinante como el área o la cantidad de baños. Estas relaciones proporcionan una primera aproximación de cómo influyen las distintas variables en el valor de la vivienda.
Después, se genera un heatmap interactivo de la matriz de correlaciones (mat_cor) usando plotly. Se especifica el rango de colores entre -1 y 1, de modo que los valores negativos se visualicen en tonos de azul y los positivos en tonos rojizos. Mediante layout() se asigna un título al gráfico y se omiten las etiquetas de los ejes, dado que las columnas y filas ya se identifican a partir de los nombres de las variables (colnames y rownames). Al final, se muestra el objeto heatmap_cor, permitiendo explorar de manera interactiva el nivel de correlación entre las distintas variables.
Se ajusta un modelo de regresión lineal simple (lm(preciom ~ areaconst)) para relacionar el precio de la vivienda con el área construida y se extrae el coeficiente de determinación (R²). Luego, mediante ggplot2, se elabora un diagrama de dispersión que muestra los puntos de datos y se dibuja la recta de regresión en rojo (geom_smooth(method = “lm”)). Además, se anota el valor de R² en la zona superior del gráfico para evidenciar la proporción de variabilidad del precio explicada por el área. Por último, con ggplotly(p1), se transforma el gráfico estático en una visualización interactiva, permitiendo explorar de manera dinámica la relación entre ambas variables.
## `geom_smooth()` using formula = 'y ~ x'
Se ajusta un modelo lineal sencillo para describir la relación entre el precio de la vivienda (preciom) y el estrato (estrato). Se calcula el R2 de dicho modelo y luego se construye un gráfico de dispersión con la librería ggplot2, añadiendo una línea de regresión (en color rojo) y una anotación que muestra el valor de R2. Finalmente, la función ggplotly() convierte la figura en un gráfico interactivo, permitiendo examinar de forma más dinámica cómo varía el precio según el estrato.
## `geom_smooth()` using formula = 'y ~ x'
Se analiza cómo varía el precio de la vivienda en función del número de baños. Primero se ajusta un modelo lineal simple (lm(preciom ~ banios)) y se extrae el coeficiente de determinación R2 para cuantificar cuánta variabilidad del precio explica únicamente la variable “banios”. Luego, se construye un gráfico de dispersión con ggplot2, donde se incluyen los puntos (en color azul) y la línea de regresión (en rojo). Mediante annotate(), se añade la etiqueta con el R2 sobre el área del gráfico, y finalmente se convierte el objeto a un gráfico interactivo con ggplotly(). Este enfoque muestra de manera clara la relación entre el precio y el número de baños, y facilita explorar visualmente la fortaleza de esta asociación.
## `geom_smooth()` using formula = 'y ~ x'
Se analiza la relación entre el precio de la vivienda y el número de habitaciones. Primero, se ajusta un modelo lineal simple (modelo_habitaciones) con lm(), en el que se predice el precio (preciom) a partir del número de habitaciones, y se extrae el coeficiente de determinación (R²) con summary(). Posteriormente, se crea un gráfico con ggplot2 que muestra los datos mediante puntos azules y, además, se agrega una línea de regresión (en rojo) para visualizar la tendencia. Se incluye una anotación en el gráfico que muestra el valor de R², lo cual facilita la interpretación del grado de explicación del modelo. Finalmente, el gráfico se convierte en interactivo usando ggplotly(), lo que permite explorar los datos de manera dinámica. Este análisis permite evaluar cómo varía el precio de la vivienda en función del número de habitaciones, y el R² obtenido ofrece una medida de la fuerza de esta relación.
## `geom_smooth()` using formula = 'y ~ x'
Se utiliza la función ggpairs() para generar una matriz de gráficos que permite explorar las relaciones entre las variables numéricas seleccionadas. En la parte inferior (lower) se muestran diagramas de dispersión con transparencia (alpha = 0.5) y color azul para visualizar posibles patrones entre pares de variables. En la diagonal (diag), se presentan gráficos de densidad que ilustran la distribución de cada variable de forma individual. Finalmente, en la parte superior (upper), se despliegan los coeficientes de correlación junto a su magnitud, brindando una vista rápida de qué tan relacionadas están las variables entre sí. De este modo, se obtiene una visión global de la distribución y asociación de las variables clave para el análisis.
En esta matriz de gráficos generada con ggpairs(), la parte superior muestra los coeficientes de correlación entre las variables numéricas, indicando la fuerza y dirección de sus relaciones (junto con la significancia estadística). En la diagonal, aparecen los histogramas o densidades que ilustran cómo se distribuye cada variable por sí sola. Por último, en la parte inferior, se observan los diagramas de dispersión (scatter plots) que permiten ver si existen patrones no lineales o valores atípicos entre pares de variables. De esta forma, se obtiene una visión integral de la asociación y distribución de preciom, areaconst, estrato, banios y habitaciones.
Se ajusta un modelo de regresión lineal múltiple donde la variable respuesta (preciom) se explica a partir de areaconst (área construida), estrato, habitaciones, banios (número de baños) y parqueaderos. Posteriormente, la función summary(modelo) proporciona un resumen estadístico de los coeficientes estimados y el ajuste global del modelo.
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + banios +
## parqueaderos, data = base2_filtrados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1176.29 -46.01 -0.85 42.16 942.62
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -323.1635 14.9539 -21.611 < 0.0000000000000002 ***
## areaconst 1.3863 0.0553 25.069 < 0.0000000000000002 ***
## estrato 67.9190 3.0320 22.401 < 0.0000000000000002 ***
## habitaciones -10.2402 3.8276 -2.675 0.00752 **
## banios 48.1609 3.4224 14.072 < 0.0000000000000002 ***
## parqueaderos 53.0207 3.8756 13.681 < 0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 93.23 on 2159 degrees of freedom
## Multiple R-squared: 0.7411, Adjusted R-squared: 0.7405
## F-statistic: 1236 on 5 and 2159 DF, p-value: < 0.00000000000000022
En general, el modelo ofrece un buen nivel de ajuste (R² alto) y presenta coeficientes que resultan coherentes con la lógica del mercado inmobiliario, especialmente en lo referente al impacto del área construida, el estrato, el número de baños y los parqueaderos en el precio de la vivienda. No obstante, el resultado inesperado en la variable de habitaciones sugiere la necesidad de un análisis más profundo y la exploración de nuevas variables que permitan afinar la precisión del modelo y mejorar la estimación del valor de las propiedades.
Para evaluar la calidad del modelo de regresión lineal múltiple y asegurar que cumple con los supuestos estadísticos, se llevaron a cabo dos tipos de validaciones principales: el análisis de gráficos de diagnóstico y la evaluación del factor de inflación de la varianza (VIF).
## areaconst estrato habitaciones banios parqueaderos
## 1.897869 1.587158 1.405535 2.426640 1.314407
Para descartar problemas de multicolinealidad, se calculó el VIF (vif(modelo)). En este caso, los valores obtenidos fueron relativamente bajos, por ejemplo:
Después, se depura el conjunto de datos base1 eliminando las observaciones con valores faltantes en las variables clave (área construida, estrato, piso, baños, habitaciones y parqueaderos). Después, se aplica la función predict() sobre el modelo de regresión previamente entrenado (modelo) para estimar el precio de cada vivienda en base1_pred, almacenando los resultados en la nueva columna precio_estimado. Finalmente, se muestra un anticipo de las predicciones con head(base1_pred, 5), donde se pueden observar las primeras cinco filas y el precio pronosticado para cada caso.
## El precio estimado para la nueva vivienda (estrato 5) en la Zona Sur es de 684.68 millones de pesos.
## El precio estimado para la nueva vivienda (estrato 6) en la Zona Sur es de 752.6 millones de pesos.
Primero se filtran las viviendas cuya predicción de precio no excede los 850 millones de pesos, reflejando el límite de crédito preaprobado. Después, se ordenan dichas opciones de menor a mayor precio estimado y se eligen las primeras cinco, creando así la tabla de “recomendadas”. Finalmente, con la librería leaflet se representan estas cinco propiedades en un mapa interactivo, mostrando cada una como un marcador circular. Al hacer clic en el marcador, se despliega un popup con información relevante (ID, precio estimado, área, estrato, número de baños y habitaciones). Esto facilita visualizar de forma geográfica las ofertas potenciales que se ajustan al presupuesto disponible.
## # A tibble: 0 × 14
## # ℹ 14 variables: id <dbl>, zona <chr>, piso <chr>, estrato <dbl>,
## # preciom <dbl>, areaconst <dbl>, parqueaderos <dbl>, banios <dbl>,
## # habitaciones <dbl>, tipo <chr>, barrio <chr>, longitud <dbl>,
## # latitud <dbl>, precio_estimado <dbl>
Al ejecutarse, la consulta no arroja resultados, lo que significa que, en la base de datos (base2_pred), no existen registros que cumplan con todos esos criterios de manera simultánea.
Esto puede suceder por varios motivos:
Por esta razón, podría ser necesario revisar si en la Zona Sur hay más disponibilidad de casas en lugar de apartamentos
## [1] 0
## tibble [1,298 × 7] (S3: tbl_df/tbl/data.frame)
## $ preciom : num [1:1298] 400 500 175 240 650 500 490 490 550 220 ...
## $ areaconst : num [1:1298] 280 354 102 75 200 392 250 250 294 80 ...
## $ estrato : num [1:1298] 4 3 3 3 5 4 4 5 4 4 ...
## $ banios : num [1:1298] 5 2 2 3 4 2 4 4 4 3 ...
## $ habitaciones: num [1:1298] 3 4 4 5 3 3 4 4 4 3 ...
## $ zona : chr [1:1298] "Zona Sur" "Zona Sur" "Zona Sur" "Zona Sur" ...
## $ parqueaderos: num [1:1298] 3 1 2 2 2 2 2 2 3 1 ...
## tibble [1,298 × 7] (S3: tbl_df/tbl/data.frame)
## $ preciom : num [1:1298] 400 500 175 240 650 500 490 490 550 220 ...
## $ areaconst : num [1:1298] 280 354 102 75 200 392 250 250 294 80 ...
## $ estrato : num [1:1298] 4 3 3 3 5 4 4 5 4 4 ...
## $ banios : num [1:1298] 5 2 2 3 4 2 4 4 4 3 ...
## $ habitaciones: num [1:1298] 3 4 4 5 3 3 4 4 4 3 ...
## $ zona : Factor w/ 1 level "Zona Sur": 1 1 1 1 1 1 1 1 1 1 ...
## $ parqueaderos: num [1:1298] 3 1 2 2 2 2 2 2 3 1 ...
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 3777 Zona S… 02 5 430 350 4 4 5
## 2 4874 Zona S… 02 5 450 300 3 5 5
## 3 7435 Zona S… 02 5 450 420 8 3 5
## 4 7506 Zona S… 02 5 450 450 6 4 5
## 5 5956 Zona S… 01 5 500 340 4 5 6
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_estimado <dbl>
En este mapa interactivo, se observan cinco ofertas de casas recomendadas que cumplen con el límite de precio (≤ 850 millones de pesos) y las condiciones de la segunda solicitud. Cada marcador azul representa una vivienda ubicada en la zona sur de la ciudad. Al hacer clic en uno de los marcadores, aparece un popup con datos relevantes de la casa (como ID, precio estimado y características físicas), facilitando la comparación y la toma de decisiones sobre cuál propiedad resulta más adecuada.
Estimada Maria,
De acuerdo con su solicitud para la búsqueda de dos viviendas en la Ciudad de Cali, utilizando la base de datos proporcionada, hemos encontrado varias opciones de vivienda para el cliente que necesita una casa de 200m2 las cuales se presentan a continuación:
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1020 Zona N… 02 4 230 250 2 3 5
## 2 7432 Zona N… 01 4 260 280 2 4 6
## 3 4727 Zona N… 02 4 296 232 2 6 4
## 4 1914 Zona N… 02 5 300 205 2 5 6
## 5 4458 Zona N… 02 4 315 270 2 4 4
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_estimado <dbl>
Para el segundo cliente, que requiere un apartamento de 300m2 en la zona sur, no hemos encontrado una oferta que se adapte a las necesidades, pues en esta zona y con las características suministradas, hay solamente casas que respetan los requisitos.
## # A tibble: 5 × 14
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 3777 Zona S… 02 5 430 350 4 4 5
## 2 4874 Zona S… 02 5 450 300 3 5 5
## 3 7435 Zona S… 02 5 450 420 8 3 5
## 4 7506 Zona S… 02 5 450 450 6 4 5
## 5 5956 Zona S… 01 5 500 340 4 5 6
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # precio_estimado <dbl>
Esperamos que este informe haya sido de ayuda para las necesidades del cliente y que puedan tomar una decisión sobre las sugerencias realizadas.