De acuerdo a los datos obtenidos de la base de datos “vivienda” del paquete devtools:

Realizaremos un filtro a la base de datos que incluirá solo las ofertas de vivienda tipo casa, de la zona norte de la ciudad. Presentamos los primeros 3 registros de la base de datos e información que comprueba la consulta. (Adicional un mapa con los puntos de las bases.

Iniciamos con un filtro en nuestra muestra para aquellos registros que cumplan las condiciones:

* Tipo = Casa

* Zona = Zona Norte

filtered_data <- vivienda %>%
  filter(tipo == "Casa" & zona == "Zona Norte")

Apartir de esta muestra visualizamos los primeros 3 registros.

head(filtered_data, 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>

Implementamos la función table mediante la cual traemos como resultado una tabla que nos permite observar la sumatoria de registros de acuerdo al estrato de viviendas tipo Casa en la Zona Norte de Cali.

table(filtered_data$estrato)
## 
##   3   4   5   6 
## 235 161 271  55

Hacemos uso de la librería leaflet para generar un mapa de Cali donde se ubican las viviendas tipo Casa en la Zona Norte de Cali.

Mapa de las viviendas tipo Casa en Zona Norte:

map <- leaflet(filtered_data) %>%
  addTiles() %>%
  addMarkers(lat = ~latitud, lng = ~longitud)  
# Display the map
map

Interpretación del mapa anterior:

Al realizar un análisis sobre la ubicación de las propiedades tipo casa, es evidente que la mayoría se concentra en la zona norte de la ciudad. No obstante, se observa que algunas pocas están dispersas de manera poco común en el resto del territorio. Esto posiblemente se deba a errores en los datos, como errores de entrada o errores de digitación.

Realizaremos un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Utilizamos gráficos interactivos con el paquete plotly.

* Gestionamos la instalación y uso del paquete Plotly

install.packages("plotly")
library(plotly)

* Construimos un diagrama de dispersión, también conocido como gráfico de dispersión o scatterplot en inglés, el cual nos permite visualizar la relación entre dos variables cuantitativas. Cada punto en el gráfico representa una observación que tiene valores en ambas variables. Esto proporciona una representación gráfica de cómo los valores de una variable están distribuidos con respecto a los valores de la otra. Mediante este gráfico podemos determinar si existe alguna relación entre las variables, por ejemplo, si son directamente proporcionales, inversamente proporcionales o no tienen relación aparente.

Se pueden presentar valores atípicos, los valores atípicos o outliers son valores inusuales que se alejan significativamente de la mayoría de los datos. Un gráfico de dispersión permite también identificar estos valores atípicos, ya que a menudo se representan como puntos que se alejan del patrón general en el gráfico.

Una visual de dispersión es la base para el análisis de modelos de regresión. Es posible ajustar una línea o una curva a los puntos en el gráfico para predecir o modelar una variable en función de la otra. Esto es especialmente útil cuando se desea realizar predicciones o inferencias basadas en los datos.

scatter_plot <- plot_ly(data = filtered_data, x = ~areaconst, y = ~preciom, color = ~zona,
                        type = 'scatter', mode = 'markers',
                        marker = list(size = 10, opacity = 0.6)) %>%
  layout(title = "Scatter Plot Area construida vs. Precio",
         xaxis = list(title = "Area Construida"),
         yaxis = list(title = "Precio de vivienda en millones"))

scatter_plot
box_plot_estrato <- plot_ly(data = filtered_data, x = ~estrato, y = ~preciom, type = 'box') %>%
  layout(title = "Box Plot de Precio por Estrato",
         xaxis = list(title = "Estrato"),
         yaxis = list(title = "Precio de vivienda en millones"))
box_plot_estrato
box_plot_zona <- plot_ly(data = filtered_data, x = ~zona, y = ~preciom, type = 'box') %>%
  layout(title = "Box Plot de Precio por Zona",
         xaxis = list(title = "Zona"),
         yaxis = list(title = "Precio de vivienda en millones"))
box_plot_zona

Ahora estimaremos un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) y realizaremos la interpretación de los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interpretaremos el coeficiente R2 y discutiremos el ajuste del modelo e implicaciones, así como lo que se podría implementar para mejorarlo.

* Para esta finalidad utilizaremos la función lm() en R, la cual se utiliza para realizar análisis de regresión lineal. La regresión lineal es una técnica estadística que se utiliza para modelar la relación entre una variable dependiente (o respuesta) y una o más variables independientes (o predictores) al encontrar la mejor línea recta (o hiperplano en dimensiones superiores) que se ajusta a los datos.

En particular, lm() se utiliza para:

Ajuste de modelo: Es posible usar lm() para ajustar un modelo de regresión lineal a tus datos. Esto implica encontrar los coeficientes (pendiente y ordenada al origen) que minimizan la suma de los cuadrados de las diferencias entre los valores observados y los valores predichos por el modelo.

Predicción: Una vez ajustado un modelo de regresión lineal, se puede utilizar para predecir valores de la variable dependiente en función de los valores de las variables independientes. Esto es útil en la predicción de resultados futuros o para entender cómo una variable responde a cambios en otras.

Evaluación del modelo: Podemos obtener estadísticas sobre la calidad del ajuste del modelo, como los valores R-squared, los coeficientes de regresión, los intervalos de confianza y las p-values. Estas estadísticas ayudan a evaluar la significancia de las relaciones entre las variables y la bondad del ajuste del modelo.

Visualización: La función lm() puede utilizarse en combinación con otras funciones y paquetes de R, como ggplot2, para crear gráficos que muestren el modelo de regresión y sus resultados de manera visual. Esto lo exploramos más adelante.

En resumen, lm() en R es una herramienta esencial para realizar análisis de regresión lineal, lo que permite modelar y comprender las relaciones entre variables y realizar predicciones basadas en datos observados.

Apartir de lo anterior, generamos el modelo con la función lm() apartir de los datos filtrados por tipo de vivienda: Casa y zona: Zona Norte.

model <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = filtered_data) #usage of filtered data by "tipo" and "zona"

Ahora ejecutamos la función summary mediante la cual obtenemos un resumen estadístico detallado del modelo. El resumen incluye información importante sobre las relaciones entre las variables. La información que proporciona summary() incluye:

Resumen de coeficientes: el resumen mostrará una tabla que incluye los coeficientes estimados para cada variable independiente en el modelo. Esto incluye la estimación de la interceptación (ordenada al origen) y las pendientes de las variables predictoras. Estos coeficientes permiten entender cómo cada variable independiente contribuye al modelo.

Estadísticas de significancia: junto a cada coeficiente, se proporcionan estadísticas como el valor t y la p-value. Estas estadísticas permiten determinar si los coeficientes son significativamente diferentes de cero. Las p-values más pequeñas indican una mayor significancia.

Estadísticas de ajuste del modelo: El resumen incluye estadísticas como el R-squared (R²), que mide la bondad del ajuste del modelo. El R² indica cuánta variabilidad en la variable dependiente es explicada por el modelo. También se proporciona el R² ajustado, que tiene en cuenta el número de variables en el modelo.

Estadísticas de error: se proporciona información sobre la varianza residual, el error estándar residual y otras variable estadísticas relacionados con la precisión del modelo.

Información sobre los residuos: Los residuos son las diferencias entre los valores observados y los valores predichos por el modelo. La revisión de los residuos es importante para verificar si se cumplen las suposiciones de la regresión lineal.

Información sobre la multicolinealidad: Si hay multicolinealidad (alta correlación entre las variables predictoras), el resumen puede proporcionar advertencias o información sobre este inconveniente.

Summary() es una herramienta esencial para evaluar la calidad del ajuste de un modelo de regresión y la importancia de las variables predictoras en el modelo. Ayuda a interpretar el modelo y a determinar si es adecuado para los datos disponibles.

summary(model)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = filtered_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -784.29  -77.56  -16.03   47.67  978.61 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -238.17090   44.40551  -5.364 1.34e-07 ***
## areaconst       0.67673    0.05281  12.814  < 2e-16 ***
## estrato        80.63495    9.82632   8.206 2.70e-15 ***
## habitaciones    7.64511    5.65873   1.351    0.177    
## parqueaderos   24.00598    5.86889   4.090 5.14e-05 ***
## banios         18.89938    7.48800   2.524    0.012 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 155.1 on 429 degrees of freedom
##   (287 observations deleted due to missingness)
## Multiple R-squared:  0.6041, Adjusted R-squared:  0.5995 
## F-statistic: 130.9 on 5 and 429 DF,  p-value: < 2.2e-16

De lo anterior concluimos:

  1. Ajuste del Modelo:

El modelo parece ser un modelo de regresión lineal con la variable dependiente “preciom” y cinco variables independientes: “areaconst”, “estrato”, “habitaciones”, “parqueaderos” y “banios”.

  1. Residuos:

Los residuos son las diferencias entre los valores observados y los valores predichos por el modelo. El resumen muestra estadísticas sobre los residuos, incluyendo los valores mínimo, primer cuartil, mediana, tercer cuartil y máximo.

  1. Coeficientes:

La sección de “Coeficientes” muestra los coeficientes estimados para cada variable independiente en el modelo. La columna “Estimado” representa los coeficientes estimados. La columna “Error estándar” representa el error estándar de los coeficientes. La columna “Valor t” es la estadística t, que mide cuántos errores estándar se encuentra el coeficiente estimado lejos de cero. La columna “Pr(>|t|)” representa el valor p asociado con cada coeficiente. Los valores p indican si cada coeficiente es estadísticamente significativo. En este caso, parece que “areaconst”, “estrato” y “parqueaderos” tienen valores p muy bajos (<< 0.05), lo que indica que son predictores significativos. “banios” también tiene un valor p relativamente bajo (0.012), pero “habitaciones” no parece ser estadísticamente significativo (valor p = 0.177).

Los coeficientes en un modelo de regresión lineal son valores numéricos que indican la relación entre una variable independiente y la variable dependiente. En el summary, estos coeficientes son estimaciones de cómo cada variable independiente (como “areaconst,” “estrato,” “habitaciones,” “parqueaderos,” y “banios”) afecta a la variable dependiente “preciom.”

  1. Error Estándar de los Residuos:

El “Error estándar de los residuos” representa la desviación estándar de los residuos. Mide la desviación promedio de los valores observados con respecto a los valores predichos por el modelo.

  1. R-cuadrado Múltiple y R-cuadrado Ajustado:

R-cuadrado Múltiple (R²): Es una medida de cuánta variabilidad en la variable dependiente (“preciom” en este caso) es explicada por las variables independientes en el modelo. Un R² de 0.6041 significa que aproximadamente el 60.41% de la variabilidad en “preciom” se puede explicar mediante las variables independientes en tu modelo.

R-cuadrado Ajustado: Ajusta el R² en función del número de variables independientes en el modelo. Proporciona una medida más conservadora de la bondad del ajuste, teniendo en cuenta el riesgo de sobreajuste (ajuste excesivo). En tu resumen, el R-cuadrado ajustado es 0.5995.

  1. Estadística F:

La estadística F es una medida de la significancia general del modelo. Evalúa si al menos una de las variables independientes en el modelo tiene un efecto significativo en la variable dependiente. Un valor alto de la estadística F (en este caso, 130.9) y un valor p extremadamente bajo (< 2.2e-16) indican que el modelo en su conjunto es estadísticamente significativo, lo que significa que al menos una de las variables independientes es un predictor significativo de “preciom”.

En conclusión, parece que el modelo se ajusta razonablemente bien a los datos, con “areaconst”, “estrato” y “parqueaderos” como predictores significativos de “preciom”. Sin embargo, “habitaciones” no parece ser un predictor significativo. Puede ser necesario realizar un análisis adicional y posiblemente refinar el modelo para mejorar su capacidad predictiva.

Realizaremos la validación de supuestos del modelo y la interpretación de los resultados.

* Para realizar esta validación de supuestos, calculamos la linealidad.

* Partiremos por realizar un gráfico de dispersión de residuos vs. valores ajustados del modelo. La linealidad es uno de los supuestos fundamentales en la validación de modelos estadísticos, especialmente en el contexto de modelos de regresión lineal. Este supuesto establece que la relación entre las variables independientes y la variable dependiente es lineal, es decir, se puede representar mediante una línea recta en un espacio bidimensional o un hiperplano en espacios de mayor dimensión.

En otras palabras, la linealidad implica que un cambio unitario en una variable independiente debe producir un cambio constante en la variable dependiente, manteniendo todas las demás variables constantes.

# 1. Linealidad
# Gráfico de dispersión de residuos vs. valores ajustados
plot(model$residuals ~ model$fitted.values, xlab = "Valores Ajustados", ylab = "Residuos", main = "Linealidad")

Si los puntos en el gráfico de dispersión están distribuidos alrededor de una línea horizontal que pasa por el cero (la línea de referencia), esto sugiere que la relación entre las variables independientes y la variable dependiente es lineal. En otras palabras, indica que el modelo de regresión lineal es una buena elección. En este caso se puede apreciar que los datos están distribuidos alrededor de una línea horizontal que pasa por el cero.

# 2. Independencia de Residuos
# Gráfico de residuos en función del orden de observación
plot(model$residuals, xlab = "Orden de Observación", ylab = "Residuos", main = "Independencia de Residuos")

El gráfico de residuos en función del orden de observación es una herramienta que ayuda a evaluar la independencia de los residuos en el modelo de regresión. Aquí hay algunas conclusiones:

Se logra observar que la mayoría de los puntos en el gráfico de residuos se posicionan alrededor de 0 en el eje vertical (una línea horizontal), esto es una señal positiva y sugiere que los residuos en tu modelo de regresión están centrados alrededor de cero. Esto tiene implicaciones importantes:

Cumplimiento del Supuesto de Linealidad:

Cuando los residuos están centrados alrededor de cero, esto sugiere que el supuesto de linealidad en el modelo de regresión es probablemente válido. Los residuos siguen una distribución aleatoria en relación con la línea de regresión, lo que es deseable en un modelo de regresión lineal.

Ausencia de Correlación Sistemática:

La agrupación de residuos cerca de cero indica que no hay una correlación sistemática entre los errores del modelo y las observaciones. Esto es un buen indicativo de que el modelo no está sesgado sistemáticamente en ninguna dirección.

Independencia Aparente:

Un gráfico de residuos centrados alrededor de cero sugiere que los residuos son, en su mayoría, independientes entre sí. No hay patrones obvios de correlación serial o tendencias en los residuos a medida que avanzas en el orden de observación.

Validación del Modelo:

Cuando los residuos están centrados en torno a cero, es más probable que el modelo sea válido y que las predicciones basadas en él sean confiables.

Outliers o Valores Atípicos:

Se puede identificar valores atípicos o outliers en el gráfico, puntos que están muy alejados del rango de los residuos en la mayoría de las observaciones. Estos valores indican que existen observaciones inusuales que pueden afectar la independencia de los residuos.

# 3. Homocedasticidad
# Gráfico de dispersión de residuos vs. valores ajustados
plot(model$fitted.values, abs(model$residuals), xlab = "Valores Ajustados", ylab = "|Residuos|", main = "Homocedasticidad")

Se observa que la dispersión de los residuos es constante y no cambia a medida que avanza en los valores ajustados, esto es una señal positiva de homocedasticidad. Los puntos en el gráfico deberían dispersarse de manera uniforme alrededor de alguna línea horizontal, sin un patrón evidente

# 4. Normalidad de Residuos
# Gráfico Q-Q para verificar la normalidad
qqPlot(model$residuals, main = "Normalidad de Residuos")

## 513 405 
## 309 239

En un gráfico Q-Q, si los puntos siguen aproximadamente una línea diagonal (la línea de referencia), esto sugiere que los residuos se distribuyen de manera cercana a una distribución normal. En otras palabras, los residuos son razonablemente normales si los puntos se ajustan a la línea diagonal, como sucede en este caso.

# 5. Multicolinealidad
# Matriz de correlación entre variables predictoras
cor_matrix <- cor(filtered_data[, c("areaconst", "estrato", "habitaciones", "parqueaderos", "banios")])
print(cor_matrix)
##              areaconst   estrato habitaciones parqueaderos    banios
## areaconst    1.0000000 0.4573818    0.3753323           NA 0.4628152
## estrato      0.4573818 1.0000000    0.1073141           NA 0.4083039
## habitaciones 0.3753323 0.1073141    1.0000000           NA 0.5755314
## parqueaderos        NA        NA           NA            1        NA
## banios       0.4628152 0.4083039    0.5755314           NA 1.0000000

De la matriz de correlación podemos deducir que:

Correlaciones Positivas:

Las correlaciones positivas indican que a medida que una variable aumenta, la otra también tiende a aumentar. En este caso, observamos correlaciones positivas entre “areaconst” y “estrato” (0.457), “areaconst” y “banios” (0.463), “estrato” y “banios” (0.408), y “habitaciones” y “banios” (0.576).

Correlaciones Bajas o No Disponibles:

Algunas de las correlaciones son bajas o no están disponibles (“NA”). Por ejemplo, no se proporciona una correlación entre “parqueaderos” y otras variables, lo que podría deberse a la falta de variabilidad en “parqueaderos” en el conjunto de datos.

Multicolinealidad Potencial:

La matriz de correlación muestra algunas correlaciones moderadas entre las variables, como la correlación entre “areaconst” y “estrato” (0.457) y entre “areaconst” y “banios” (0.463). También hay una correlación moderada entre “habitaciones” y “banios” (0.576). Estas correlaciones moderadas sugieren una cierta multicolinealidad potencial entre estas variables predictoras.

Consideraciones para el Modelo:

La multicolinealidad puede dificultar la interpretación de los coeficientes del modelo y hacer que las estimaciones sean menos estables. Si la multicolinealidad se considera un problema, podrías explorar opciones como eliminar una de las variables altamente correlacionadas o utilizar técnicas de regularización (por ejemplo, regresión ridge o regresión lasso) para mitigar sus efectos.

# Prueba de multicolinealidad
vif(model)
##    areaconst      estrato habitaciones parqueaderos       banios 
##     1.460998     1.307757     1.721015     1.226334     1.967421

La función VIF (Factor de Inflación de la Varianza, por sus siglas en inglés) se utiliza para evaluar la multicolinealidad entre las variables predictoras en un modelo de regresión. El VIF cuantifica cuánto aumenta la varianza de un coeficiente de regresión debido a la multicolinealidad entre las variables predictoras. Aquí hay algunas conclusiones del resultado obtenido:

Valores de VIF:

Cada valor de VIF corresponde a una variable predictora del modelo.

Los valores de VIF que obtenidos son: VIF para “areaconst” es aproximadamente 1.461. VIF para “estrato” es aproximadamente 1.308. VIF para “habitaciones” es aproximadamente 1.721. VIF para “parqueaderos” es aproximadamente 1.226. VIF para “banios” es aproximadamente 1.967.

Interpretación de VIF:

En general, un VIF cercano a 1 indica que la variable predictora correspondiente no está altamente correlacionada con las otras variables en el modelo, lo que es bueno. Cuando el VIF es mayor que 1, esto indica que la variable está correlacionada con al menos una de las otras variables predictoras. Cuanto mayor sea el VIF, mayor será la multicolinealidad.

Impacto en la Interpretación:

Los valores de VIF que se han obtenido son relativamente bajos, lo que sugiere que la multicolinealidad no parece ser un problema grave en el modelo. Los valores de VIF cercanos a 1 indican que las variables predictoras no están altamente correlacionadas entre sí, lo que facilita la interpretación de los coeficientes.

Acciones a Tomar:

En general, si los valores de VIF son significativamente mayores que 1 (por ejemplo, mayores que 5 o 10), esto podría ser una señal de multicolinealidad problemática. En tal caso, es posible considerar tomar medidas como eliminar una de las variables altamente correlacionadas o utilizar técnicas de regularización. En resumen, los valores de VIF que se han obtenido sugieren que la multicolinealidad no es un problema grave de este modelo de regresión. Los valores cercanos a 1 indican que las variables predictoras no están altamente correlacionadas entre sí, lo cual es beneficioso para la interpretación del modelo.

# 6. Outliers e Influential Points
# Gráfico de valores ajustados vs. residuos estandarizados
plot(model$fitted.values, rstandard(model), xlab = "Valores Ajustados", ylab = "Residuos Estandarizados", main = "Outliers e Influential Points")

Se observan puntos que están muy lejos de la línea central en el gráfico, estos pueden ser considerados outliers. Los outliers pueden tener un impacto desproporcionado en el modelo y pueden afectar la precisión de las predicciones.

# 7. Heteroscedasticidad Condicional
# Calcula los residuos estandarizados
residuals <- rstandard(model)

# Calcula los valores ajustados
fitted_values <- fitted(model)

# Crea un gráfico de residuos estandarizados vs. valores ajustados
plot(fitted_values, residuals, 
     main = "Heteroscedasticidad Condicional",
     xlab = "Valores Ajustados",
     ylab = "Residuos Estandarizados")

La heteroscedasticidad condicional implica que la dispersión (variabilidad) de los residuos cambia a medida que cambian los valores ajustados. En otras palabras, la varianza de los residuos no es constante en todo el rango de valores ajustados. La heteroscedasticidad condicional a menudo se manifiesta como una forma de embudo o cono, donde la dispersión de los residuos tiende a aumentar o disminuir a medida que los valores ajustados aumentan. En este caso no se observa una tendencia de disperción en forma de embudo en el gráfico, esto es una indicación de que no se presenta heteroscedasticidad condicional.

Con el modelo identificado se predecirá el precio de la vivienda con las características de la primera solicitud en R

# Data from the first requirement
nueva_solicitud_1_0 <- data.frame(
  areaconst = 200,   
  estrato = 4,             
  habitaciones = 4,      
  parqueaderos = 1, 
  banios = 2         
)

nueva_solicitud_1_1 <- data.frame(
  areaconst = 200,   
  estrato = 5,             
  habitaciones = 4,      
  parqueaderos = 1, 
  banios = 2         
)


nueva_solicitud <- rbind(nueva_solicitud_1_0, nueva_solicitud_1_1)
print(nueva_solicitud)
##   areaconst estrato habitaciones parqueaderos banios
## 1       200       4            4            1      2
## 2       200       5            4            1      2
# Build the prediction
prediccion_precio <- predict(model, newdata = nueva_solicitud)

prediccion_precio
##        1        2 
## 312.1010 392.7359

El precio para vivienda estrato 4 es 312 Millones y para vivienda estrato 5, 392.7 Millones.

Con las predicciones del modelo se sugerirá potenciales ofertas que respondan a la solicitud de la vivienda 1. Teniendo en cuenta que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Se realizará un análisis de los resultados y se generará en un mapa al menos 5 ofertas potenciales.

# Realizar la predicción del precio de la vivienda 1
prediccion_precio_vivienda1 <- predict(model, newdata = nueva_solicitud)

# Definir el presupuesto máximo (350 millones de pesos)
presupuesto_maximo <- 350

# Filtrar las ofertas potenciales dentro del presupuesto
ofertas_potenciales <- filtered_data %>%
  filter(preciom <= presupuesto_maximo) %>%
  select(latitud, longitud, preciom)  # Seleccionar columnas relevantes para el mapa

# Visualizar las ofertas potenciales en un mapa (usando leaflet)
library(leaflet)

# Construccion del mapa
mapa_ofertas <- leaflet(data = ofertas_potenciales) %>%
  addTiles() %>%
  addMarkers(
    ~longitud, ~latitud,
    label = ~paste("Precio: $", preciom, "M"),  # el precio ya está formateado en millones en la muestra
    popup = ~paste("Precio: $", preciom, "M"),
    clusterOptions = markerClusterOptions()
  )

# Mostrar el mapa
mapa_ofertas

Realizaremos los pasos pasos anteriores para la segunda solicitud que tiene un crédito pre-aprobado por valor de $850 millones.

Iniciamos con un filtro en nuestra muestra para aquellos registros que cumplan las condiciones:

* Tipo = Apartamento

* Zona = Zona Sur

filtered_data_2 <- vivienda %>%
  filter(tipo == "Apartamento" & zona == "Zona Sur")

Apartir de esta muestra visualizamos los primeros 3 registros.

head(filtered_data_2, 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>

Implementaremos la función table mediante la cual traemos como resultado una tabla que nos permite observar la sumatoria de registros de acuerdo al estrato de viviendas tipo Apartamento en la Zona Sur de Cali.

table(filtered_data_2$estrato)
## 
##    3    4    5    6 
##  201 1091 1033  462

Hacemos uso de la librería leaflet para generar un mapa de Cali donde se ubican las viviendas tipo Apartamento en la Zona Sur.

Mapa de las viviendas tipo Apartamento en la Zona Sur:

map <- leaflet(filtered_data_2) %>%
  addTiles() %>%
  addMarkers(lat = ~latitud, lng = ~longitud)  
# Display the map
map

Interpretación del mapa anterior:

Al realizar un análisis sobre la ubicación de las propiedades tipo casa, es evidente que la mayoría se concentra en la zona sur de la ciudad. No obstante, se observa que algunas pocas están dispersas de manera poco común en el resto del territorio. Esto posiblemente se deba a errores en los datos, como errores de entrada o errores de digitación.

Realizaremos un análisis exploratorio de nuestra muestra

scatter_plot_2 <- plot_ly(data = filtered_data_2, x = ~areaconst, y = ~preciom, color = ~zona,
                        type = 'scatter', mode = 'markers',
                        marker = list(size = 10, opacity = 0.6)) %>%
  layout(title = "Scatter Plot Area construida vs. Precio",
         xaxis = list(title = "Area Construida"),
         yaxis = list(title = "Precio de vivienda en millones"))

scatter_plot_2
box_plot_estrato_2 <- plot_ly(data = filtered_data_2, x = ~estrato, y = ~preciom, type = 'box') %>%
  layout(title = "Box Plot de Precio por Estrato",
         xaxis = list(title = "Estrato"),
         yaxis = list(title = "Precio de vivienda en millones"))
box_plot_estrato_2
box_plot_zona_2 <- plot_ly(data = filtered_data_2, x = ~zona, y = ~preciom, type = 'box') %>%
  layout(title = "Box Plot de Precio por Zona",
         xaxis = list(title = "Zona"),
         yaxis = list(title = "Precio de vivienda en millones"))
box_plot_zona_2

Construiremos un modelo de regresión lineal con la función lm()

model_2 <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = filtered_data_2)

El resumen del modelo nos permitirá evaluar la calidad del ajuste de un modelo de regresión y la importancia de las variables predictoras en el modelo

summary(model_2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = filtered_data_2)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1092.02   -42.28    -1.33    40.58   926.56 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -261.62501   15.63220 -16.736  < 2e-16 ***
## areaconst       1.28505    0.05403  23.785  < 2e-16 ***
## estrato        60.89709    3.08408  19.746  < 2e-16 ***
## habitaciones  -24.83693    3.89229  -6.381 2.11e-10 ***
## parqueaderos   72.91468    3.95797  18.422  < 2e-16 ***
## banios         50.69675    3.39637  14.927  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 98.02 on 2375 degrees of freedom
##   (406 observations deleted due to missingness)
## Multiple R-squared:  0.7485, Adjusted R-squared:  0.748 
## F-statistic:  1414 on 5 and 2375 DF,  p-value: < 2.2e-16

Del resultado anterior concluimos:

Descripción del Modelo:

El modelo de regresión lineal se ajustó utilizando la fórmula “preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios” en un conjunto de datos llamado “filtered_data_2”.

Residuos:

La sección “Residuals” muestra estadísticas descriptivas de los residuos del modelo, que son las diferencias entre los valores observados y los valores predichos por el modelo. Las estadísticas incluyen el valor mínimo, el primer cuartil (25%), la mediana (50%), el tercer cuartil (75%) y el valor máximo de los residuos.

Coeficientes:

La sección “Coefficients” muestra los coeficientes de regresión estimados para cada variable independiente en el modelo, incluyendo el intercepto. Junto a cada coeficiente se proporciona su estimación, el error estándar, el valor t y el valor p correspondiente. Los valores t y los valores p se utilizan para determinar la significancia estadística de cada coeficiente. En este caso, se utilizan asteriscos para indicar el nivel de significancia.

La “Residual standard error” es una medida de la dispersión de los residuos alrededor de la línea de regresión. En este caso, es aproximadamente 98.02.

Coeficiente de Determinación (R-cuadrado):

El coeficiente de determinación (R-squared) es una medida de cuánta variabilidad en la variable dependiente es explicada por el modelo. En este caso, el R-cuadrado es aproximadamente 0.7485.

El R-cuadrado ajustado (Adjusted R-squared) tiene en cuenta el número de variables independientes en el modelo y proporciona una medida ajustada de la bondad de ajuste.

F-statistic:

El F-statistic es una estadística utilizada para evaluar la significancia global del modelo. En este caso, el valor del F-statistic es 1414, y el valor p asociado (p-value) es extremadamente pequeño (< 2.2e-16), lo que indica que el modelo en su conjunto es estadísticamente significativo.

En resumen, el summary() del modelo proporciona información sobre la calidad del ajuste del modelo, la significancia de los coeficientes, la cantidad de variabilidad explicada y la significancia global del modelo. En este caso, el modelo parece tener un buen ajuste, con coeficientes significativos y un alto R-cuadrado, lo que sugiere que explica una gran parte de la variabilidad en la variable dependiente. Sin embargo, es importante tener en cuenta otras consideraciones, como la validez de los supuestos del modelo.

* Realizaremos la validación de supuestos de nuestro segundo modelo.

# 1. Linealidad
# Gráfico de dispersión de residuos vs. valores ajustados
plot(model_2$residuals ~ model_2$fitted.values, xlab = "Valores Ajustados", ylab = "Residuos", main = "Linealidad")

Los puntos en el gráfico de dispersión están distribuidos alrededor de una línea horizontal que pasa por el cero (la línea de referencia), esto sugiere que la relación entre las variables independientes y la variable dependiente es lineal. En otras palabras, indica que el modelo de regresión lineal es una buena elección.

# 2. Independencia de Residuos
# Gráfico de residuos en función del orden de observación
plot(model_2$residuals, xlab = "Orden de Observación", ylab = "Residuos", main = "Independencia de Residuos")

El patrón aparentemente aleatorio y sin tendencias en el gráfico es deseable y sugiere que el supuesto de independencia de los residuos se cumple adecuadamente. Los residuos están centrados alrededor de cero, esto sugiere que el supuesto de linealidad en el modelo de regresión es probablemente válido.

# 3. Homocedasticidad
# Gráfico de dispersión de residuos vs. valores ajustados
plot(model_2$fitted.values, abs(model_2$residuals), xlab = "Valores Ajustados", ylab = "|Residuos|", main = "Homocedasticidad")

No hay indicios claros de heteroscedasticidad.

# 4. Normalidad de Residuos
# Gráfico Q-Q para verificar la normalidad
qqPlot(model_2$residuals, main = "Normalidad de Residuos")

## 2383 1533 
## 2042 1316

Se puede observar tendencia a la normalidad.

# 5. Multicolinealidad
# Matriz de correlación entre variables predictoras
cor_matrix_2 <- cor(filtered_data_2[, c("areaconst", "estrato", "habitaciones", "parqueaderos", "banios")])
print(cor_matrix_2)
##              areaconst   estrato habitaciones parqueaderos    banios
## areaconst    1.0000000 0.4815593    0.4339608           NA 0.6618179
## estrato      0.4815593 1.0000000    0.2125953           NA 0.5686171
## habitaciones 0.4339608 0.2125953    1.0000000           NA 0.5149227
## parqueaderos        NA        NA           NA            1        NA
## banios       0.6618179 0.5686171    0.5149227           NA 1.0000000

Correlaciones Positivas:

Las correlaciones positivas indican que a medida que una variable aumenta, la otra también tiende a aumentar. En este caso, observamos correlaciones positivas entre “areaconst” y “banios” (0.662), “estrato” y “banios” (0.569), “habitaciones” y “banios” (0.515).

Correlaciones Bajas o No Disponibles:

Algunas de las correlaciones son bajas o no están disponibles (“NA”). Por ejemplo, no se proporciona una correlación entre “parqueaderos” y otras variables, lo que podría deberse a la falta de variabilidad en “parqueaderos” en el conjunto de datos.

Multicolinealidad Potencial:

La matriz de correlación muestra algunas correlaciones moderadas entre las variables predictoras, como la correlación entre “areaconst” y “banios” (0.662) y entre “estrato” y “banios” (0.569).

Estas correlaciones moderadas sugieren una cierta multicolinealidad potencial entre estas variables predictoras, lo cual no es deseable.

# Prueba de multicolinealidad
vif(model_2)
##    areaconst      estrato habitaciones parqueaderos       banios 
##     2.066518     1.545162     1.429280     1.737878     2.529494

La función Vif permite hacer una prueba de multicolinealidad y como resultado obtenemos que en el modelo esto no se presenta ya que no obtenemos resultados muy alejados de 1.

# 6. Outliers e Influential Points
# Gráfico de valores ajustados vs. residuos estandarizados
plot(model_2$fitted.values, rstandard(model_2), xlab = "Valores Ajustados", ylab = "Residuos Estandarizados", main = "Outliers e Influential Points")

Claramente sí existe outliers que pudieran afectar las predicciones. Sería necesario revisar estos valores tan dispersos.

# 7. Heteroscedasticidad Condicional
# Calcula los residuos estandarizados
residuals_2 <- rstandard(model_2)

# Calcula los valores ajustados
fitted_values_2 <- fitted(model_2)

# Crea un gráfico de residuos estandarizados vs. valores ajustados
plot(fitted_values_2, residuals_2, 
     main = "Heteroscedasticidad Condicional",
     xlab = "Valores Ajustados",
     ylab = "Residuos Estandarizados")

La heteroscedasticidad condicional a menudo se manifiesta como una forma de embudo o cono, donde la dispersión de los residuos tiende a aumentar o disminuir a medida que los valores ajustados aumentan. No se logra determinar un patrón claro en forma de embudo en el gráfico, esto es una indicación de la no presencia de heteroscedasticidad condicional.

Con el modelo identificado debe predecir el precio de la vivienda con las características de la segunda solicitud en R

# Data from the second requirement
nueva_solicitud_2_0 <- data.frame(
  areaconst = 300,   
  estrato = 5,             
  habitaciones = 5,      
  parqueaderos = 3, 
  banios = 3         
)
nueva_solicitud_2_1 <- data.frame(
  areaconst = 300,   
  estrato = 6,             
  habitaciones = 5,      
  parqueaderos = 3, 
  banios = 3         
)
nueva_solicitud_2 <- rbind(nueva_solicitud_2_0, nueva_solicitud_2_1)

# Build the second prediction
prediccion_precio_2 <- predict(model_2, newdata = nueva_solicitud_2)

prediccion_precio_2
##        1        2 
## 675.0247 735.9218

Para una vivienda tipo Apartamento en la zona sur con las características requeridas estrato 5 se obtuvo un precio de 675 M y para una vivienda con las mismas características estrato 6 se obtuvo un precio de 736 M.

Con las predicciones del modelo se sugerirá potenciales ofertas que respondan a la solicitud de la vivienda 2. Teniendo en cuenta que la empresa tiene crédito pre-aprobado de máximo 850 millones de pesos.

# Realizar la predicción del precio de la vivienda 2
prediccion_precio_vivienda2 <- predict(model_2, newdata = nueva_solicitud_2)

# Definir el presupuesto máximo (350 millones de pesos)
presupuesto_maximo_2 <- 850

# Filtrar las ofertas potenciales dentro del presupuesto
ofertas_potenciales_2 <- filtered_data_2 %>%
  filter(preciom <= presupuesto_maximo_2) %>%
  select(latitud, longitud, preciom)  # Seleccionar columnas relevantes para el mapa

# Visualizar las ofertas potenciales en un mapa (usando leaflet)
library(leaflet)

# Construccion del mapa
mapa_ofertas_2 <- leaflet(data = ofertas_potenciales_2) %>%
  addTiles() %>%
  addMarkers(
    ~longitud, ~latitud,
    label = ~paste("Precio: $", preciom, "M"),  # el precio ya está formateado en millones en la muestra
    popup = ~paste("Precio: $", preciom, "M"),
    clusterOptions = markerClusterOptions()
  )

# Mostrar el mapa
mapa_ofertas_2

Por Alix Chaparro.