INFORME: ANÁLISIS MERCADO INMOBILIARIO CALI

1. Objetivo:

El presente informe tiene como objetivo proporcionar una asesoría integral para la selección de las mejores opciones de vivienda en la ciudad de Cali, Colombia, que cumplan con las necesidades específicas de dos familias de empleados de una compañía internacional. La solicitud incluye la identificación de propiedades que satisfagan criterios particulares en términos de tipo de vivienda, tamaño, número de parqueaderos, baños, habitaciones, estrato y ubicación, dentro de los límites de un crédito preaprobado.

2. Mercado Inmobiliario: contexto general

t1=table(vivienda1$zona)
summarytools::freq(vivienda1$zona)
## Frequencies  
## vivienda1$zona  
## Type: Character  
## 
##                      Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## ------------------ ------ --------- -------------- --------- --------------
##        Zona Centro     36      0.75           0.75      0.75           0.75
##         Zona Norte    886     18.43          19.18     18.43          19.18
##         Zona Oeste    753     15.66          34.84     15.66          34.84
##       Zona Oriente     97      2.02          36.86      2.02          36.86
##           Zona Sur   3036     63.14         100.00     63.14         100.00
##               <NA>      0                               0.00         100.00
##              Total   4808    100.00         100.00    100.00         100.00
pie (t1)

El 63% de las viviendas fueron vendidas en la zona sur de la ciudad, la zona norte y oeste llegan casi al 35% del mercado y las zonas oriente y centro son las zonas de menores ventas, la última con solo 0,7% de las ventas, es decir 36 inmuebles.

#area
intervalos <- c(0, 100, 200, 300, 400, 500, Inf)  
etiquetas <- c("Menores de 99", "100-199", "200-299", "300-399", "400-499", "Mayores de 500")
vivienda1$categoria_area <- cut(vivienda1$areaconst, breaks = intervalos, labels = etiquetas, right = FALSE)
summarytools::freq(vivienda1$categoria_area)
## Frequencies  
## vivienda1$categoria_area  
## Type: Factor  
## 
##                        Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
## -------------------- ------ --------- -------------- --------- --------------
##        Menores de 99   1757     36.54          36.54     36.54          36.54
##              100-199   1636     34.03          70.57     34.03          70.57
##              200-299    688     14.31          84.88     14.31          84.88
##              300-399    362      7.53          92.41      7.53          92.41
##              400-499    206      4.28          96.69      4.28          96.69
##       Mayores de 500    159      3.31         100.00      3.31         100.00
##                 <NA>      0                               0.00         100.00
##                Total   4808    100.00         100.00    100.00         100.00

El 84% de las viviendas son de menos de 300 metros. La mayor frecuencia se encuentra en las viviendas de menos de 100 metros seguido por las vivienas entre 100 y 200 metros.

boxplot(vivienda1$preciom, las=1,
        main=" ",
        ylab=" ",
        xlab = " ",
        col="#ee964b")
grid()

summary(vivienda1$preciom)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    58.0   244.5   350.0   457.2   560.0  1999.0

En promedio el precio de la vivienda fue de $457 millones, con un mínimo de $58 millones y un máximo de $1.999 millones. Una mediana de $350 lo que describe una alta frecuencia de valores por debajo del promedio y unos pocas viviendas de alto valor.

El diagrama de cajas deja ver que el 75% de las viviendas costaron hasta $540 millones y el 25% más costos estuvo por encima de ese valor, los valores más altos de vivienda y menos frecuentes se encontraron por encima de los $1000 millones de pesos.

boxplot(vivienda1$preciom~vivienda1$zona,
main = "Distribución de precio por zona",
ylab="millones",
xlab = "zona", las=1,
)

La zona más costosa fue la zona oeste con $677 millones en promedio, en contraste el valor de las viviendas de la zona oriente fue la menor. La zona de mayor venta, que fue el sur, tuvo un costo promedio de $426 millones, cercano al promedio de la ciudad.

3. Metodología

Para llevar a cabo el análisis, se iniciará con la selección de información, que consiste en depurar y filtrar la base de datos inmobiliaria para extraer las viviendas que se ajusten a las características específicas solicitadas. Posteriormente, se aplicará un modelo de regresión lineal múltiple para predecir el valor de las viviendas, asegurando la fiabilidad y precisión del modelo mediante la validación de sus supuestos estadísticos. Con el modelo ajustado, se realizará la predicción del valor de las viviendas que cumplen con los requisitos establecidos para cada solicitud. Finalmente, se llevará a cabo la selección de las mejores ofertas basándose en las predicciones obtenidas y la disponibilidad presupuestaria, que en este caso corresponde a créditos preaprobados de 350 millones y 850 millones de pesos.

Resultados de la Solicitud 1:

Para responder a la solicitud de la empresa con respecto a la compra de una casa con las características específicas (área construida de 200 m², 1 parqueadero, 2 baños, 4 habitaciones, estrato 4 o 5, ubicada en la zona Norte), se construyó un modelo de regresión lineal múltiple con transformación logarítmica de la variable dependiente (precio de la vivienda).

lm(formula = log_preciom ~ areaconst + estrato + parqueaderos + banios, data = base1)

Intercepto: 4.45 (p < 2e-16) - Representa el valor esperado del logaritmo del precio de la vivienda cuando todas las variables independientes son iguales a cero. Área construida: 0.00114 (p < 2e-16) - Aumentar 1 m² en el área construida se asocia con un incremento del 0.11% en el precio de la vivienda, manteniendo constantes las demás variables. Estrato: 0.2158 (p < 2e-16) - Subir en un nivel de estrato está asociado con un aumento de aproximadamente un 21.6% en el precio, manteniendo constantes las demás variables. Parqueaderos: 0.0489 (p = 4.23e-05) - Cada parqueadero adicional está relacionado con un incremento del 4.9% en el precio, manteniendo constantes las demás variables. Baños: 0.0556 (p = 8.40e-05) - Cada baño adicional se asocia con un aumento del 5.6% en el precio, manteniendo constantes las demás variables. Bondad de ajuste:

R-cuadrado ajustado: 0.6627 - El modelo explica aproximadamente el 66.3% de la variabilidad del precio de las viviendas en función de las variables seleccionadas.

El modelo muestra que las variables seleccionadas (área construida, estrato, número de parqueaderos y número de baños) son estadísticamente significativas y tienen un impacto considerable en el precio de la vivienda. El estrato y el área construida son las variables más influyentes.

Se realizaron predicciones para dos escenarios de viviendas con las características solicitadas (área construida de 200 m², 1 parqueadero, 2 baños, 4 habitaciones, tipo de vivienda: casa, zona: Norte):

Vivienda 1 (Estrato 4): Predicción del precio: 300.6214 millones de pesos. Vivienda 2 (Estrato 5): Predicción del precio: 373.0342 millones de pesos.

La Vivienda 1 (estrato 4) se encuentra dentro del límite del crédito preaprobado de 350 millones de pesos, por lo que es una opción viable. La Vivienda 2 (estrato 5) supera el presupuesto establecido, con un valor predicho de 373 millones de pesos, lo que implica que, si se desea esta opción, se requeriría ajustar las condiciones de financiamiento o buscar alternativas en el mercado.

Otras opciones viables

##### Ofertas según crédito
# intalar dply
#install.packages("dplyr")

# Cargar el paquete dplyr
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.3
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:gridExtra':
## 
##     combine
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library (gridExtra)
library (stats)


# Filtrar la base de datos original para obtener solo las casas en la zona norte
base1 <- vivienda1 %>%
  filter(zona == "Zona Norte" & tipo == "Casa")

# Filtrar ofertas que se ajusten a la predicción del modelo y al presupuesto máximo
ofertas_potenciales <- subset(base1, preciom <= 350)  # Filtrar por presupuesto

# Calcular la diferencia entre el precio máximo y el precio de cada oferta
ofertas_potenciales$diferencia_precio <- abs(ofertas_potenciales$preciom - 350)

# Ordenar por la diferencia en precio
ofertas_potenciales <- ofertas_potenciales[order(ofertas_potenciales$diferencia_precio), ]

# Seleccionar las primeras 5 ofertas
top_5_ofertas <- head(ofertas_potenciales, 5)


# Instalar y cargar el paquete leaflet si no está instalado
# install.packages("leaflet")
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.3.3
# Crear el mapa sin el popup
mapa <- leaflet(data = top_5_ofertas) %>%
  addTiles() %>%
  addMarkers(lng = ~longitud, lat = ~latitud)

# Mostrar el mapa
mapa
top_5_ofertas

Conclusión:

Se han identificado cinco viviendas que cumplen con la restricción presupuestal establecida para la primera familia. De estas, cuatro se encuentran en estrato 5, y todas tienen un área construida de 200 metros cuadrados o más, así como más de dos parqueaderos. Estas propiedades representan opciones atractivas y se recomienda considerarlas como posibles alternativas para la reubicación de la primera familia, dada su alineación con los criterios especificados.

Resultados de la Solicitud 2:

Para la segunda solicitud, correspondiente a la compra de un apartamento, se utilizó un modelo de regresión lineal múltiple que incluyó las variables: área construida, estrato, número de parqueaderos y número de baños. Los resultados del modelo fueron los siguientes:

Ecuación del modelo:

log(preciom)=3.7667+0.0023×areaconst+0.2286×estrato+0.1785×parqueaderos+0.1116× banios

Todas las variables del modelo resultaron altamente significativas (p < 0.001), lo que demuestra una fuerte relación con el precio de la vivienda en logaritmos.

Área construida (areaconst): Tiene un coeficiente de 0.0023, lo que indica que, manteniendo constantes las demás variables, un incremento de un metro cuadrado en el área construida está asociado con un aumento del 0.23% en el precio.

Estrato: Con un coeficiente de 0.2286, se observa que aumentar un nivel de estrato incrementa el precio en un 22.86%.

Parqueaderos: Cada parqueadero adicional incrementa el precio en un 17.85%.

Baños: Un baño adicional se asocia con un incremento del 11.16% en el precio.

El valor de R-cuadrado ajustado de 0.7833 indica que el modelo explica aproximadamente el 78.3% de la variabilidad en los precios de los apartamentos, lo que sugiere un buen nivel de ajuste.

Las predicciones del modelo para las viviendas con las características dadas fueron las siguientes:

Área construida Estrato Parqueaderos Baños Tipo Zona Predicción Precio (Millones de pesos) 300 m² 5 3 3 Casa Norte 649.7540 300 m² 6 3 3 Casa Norte 816.6013

Vivienda 1: Predicción de Precio: 649.7540 millones de pesos. Este valor se encuentra por debajo del crédito preaprobado de 850 millones de pesos, lo que sugiere que esta opción es viable dentro del presupuesto establecido.

Vivienda 2: Predicción de Precio: 816.6013 millones de pesos. Esta opción también se encuentra dentro del límite de crédito preaprobado, ofreciendo una opción ajustada al presupuesto con un mayor margen.

Las dos viviendas propuestas cumplen con los requisitos presupuestarios y las características solicitadas. Se recomienda considerar ambas opciones para la compra, dado que ambas se ajustan adecuadamente al presupuesto y cumplen con las especificaciones requeridas.

Otras opciones viables

##### Ofertas según crédito
# Filtrar la base de datos original para obtener solo las casas en la zona norte
base2 <- vivienda1 %>%
  filter(zona == "Zona Sur" & tipo == "Apartamento")
# Filtrar ofertas que se ajusten a la predicción del modelo y al presupuesto máximo
ofertas_potenciales2 <- subset(base2, preciom <= 850)  # Filtrar por presupuesto

# Calcular la diferencia entre el precio máximo y el precio de cada oferta
ofertas_potenciales2$diferencia_precio <- abs(ofertas_potenciales2$preciom - 850)

# Ordenar por la diferencia en precio
ofertas_potenciales2 <- ofertas_potenciales2[order(ofertas_potenciales2$diferencia_precio), ]

# Seleccionar las primeras 5 ofertas
top_5_ofertas2 <- head(ofertas_potenciales2, 5)


# Instalar y cargar el paquete leaflet si no está instalado
# install.packages("leaflet")
library(leaflet)

# Crear el mapa sin el popup
mapa <- leaflet(data = top_5_ofertas2) %>%
  addTiles() %>%
  addMarkers(lng = ~longitud, lat = ~latitud)

# Mostrar el mapa
mapa
top_5_ofertas2

Conclusion:

Para la segunda solicitud, dado el alto monto del crédito preaprobado, se han encontrado excelentes opciones de vivienda que cumplen con las condiciones especificadas, ubicadas en el estrato 6 y en la zona sur de la ciudad. Estas alternativas ofrecen características que se ajustan a las necesidades de la familia, por lo que se recomienda evaluarlas como opciones viables para la reubicación.

Anexo 1: Metodología

Los pasos para el análisis serán los siguientes:

  • Selección de Información: Se realizará una depuración y filtrado de la base de datos inmobiliaria para extraer aquellas viviendas que se ajusten a las características específicas solicitadas para cada caso.

  • Análisis de Correlación: se efectuará un análisis de correlación entre las variables relevantes de las viviendas, como precio, área construida, estrato, número de habitaciones, parqueaderos y baños. Este análisis permitirá identificar la relación entre estas características y su impacto en el precio de la vivienda.

  • Modelo de Regresión Lineal Múltiple: Con el fin de predecir el valor de las viviendas en función de las características especificadas, se aplicará un modelo de regresión lineal múltiple. Este modelo será sometido a la validación de supuestos estadísticos necesarios para asegurar su fiabilidad y precisión. Los coeficientes obtenidos permitirán entender cómo cada variable contribuye al precio final de la vivienda.

  • Predicción del Valor de la Vivienda: Utilizando el modelo de regresión ajustado, se procederá a predecir el valor de las viviendas que cumplen con los requisitos establecidos para cada una de las solicitudes. Estas predicciones servirán como base para identificar las opciones más adecuadas.

  • Selección de las Mejores Ofertas: Finalmente, con base en las predicciones obtenidas y considerando la disponibilidad presupuestaria (créditos preaprobados de 350 millones y 850 millones de pesos).

Anexo 2: Aplicación metodología solicitud 1

  1. Selección de información: Filtro de datos para casas, de la zona norte de la ciudad.
# intalar dply
#install.packages("dplyr")

# Cargar el paquete dplyr
library(dplyr)
library (gridExtra)
library (stats)


# Filtrar la base de datos original para obtener solo las casas en la zona norte
base1 <- vivienda1 %>%
  filter(zona == "Zona Norte" & tipo == "Casa")

Primeros 3 registros de las bases:

# Mostrar los primeros 3 registros de la nueva base de datos
head(base1, 3)

Tablas caso 1:

# Tabla de conteo por zona
table(base1$zona)
## 
## Zona Norte 
##        254
# Tabla de conteo por tipo
table(base1$tipo)
## 
## Casa 
##  254
tabla_tipo_est <- addmargins(table(base1$tipo, base1$estrato))
tabla_tipo_est
##       
##          3   4   5   6 Sum
##   Casa  34  70 134  16 254
##   Sum   34  70 134  16 254
tabla_tipo_parq <- addmargins(table(base1$tipo, base1$parqueaderos))
tabla_tipo_parq
##       
##          1   2   3   4   5   6   7   8   9  10 Sum
##   Casa  81  92  30  30   8   5   5   1   1   1 254
##   Sum   81  92  30  30   8   5   5   1   1   1 254
tabla_tipo_hab <- addmargins(table(base1$tipo, base1$habitaciones))
tabla_tipo_hab
##       
##          0   1   2   3   4   5   6   7   8   9  10 Sum
##   Casa   3   1   2  37  86  61  26  13   8   9   8 254
##   Sum    3   1   2  37  86  61  26  13   8   9   8 254

Mapa con los puntos de las bases.

## Mapa
#install.packages("leaflet")
library(leaflet)

# Crear el mapa con leaflet
mapa <- leaflet(base1) %>%
  addTiles() %>%  # Añadir capa base de OpenStreetMap
  addMarkers(~longitud, ~latitud, popup = ~paste("Precio:", preciom, "<br>", "Habitaciones:", habitaciones)) %>%
  addCircleMarkers(~longitud, ~latitud, radius = 5, color = "blue", stroke = FALSE, fillOpacity = 0.7)

# Mostrar el mapa
mapa

Aunque se realiza el filtro con el parámetro de localización, se ve en el mapa que existen varios puntos que no están ubicados al norte de la ciudad.

  1. Análisis de correlación: Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.
library(plotly)
## Warning: package 'plotly' was built under R version 4.3.3
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
# Instalar plotly si no lo tienes instalado
# install.packages("plotly")

# Cargar el paquete
library(plotly)
# Gráfico interactivo para precio vs área construida
plot_area <- plot_ly(base1, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
                     marker = list(color = 'blue')) %>%
  layout(title = "Precio vs Área Construida",
         xaxis = list(title = "Área Construida (m²)"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs estrato
plot_estrato <- plot_ly(base1, x = ~estrato, y = ~preciom, type = 'box',
                        marker = list(color = 'green')) %>%
  layout(title = "Precio vs Estrato",
         xaxis = list(title = "Estrato"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs número de baños
plot_banios <- plot_ly(base1, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers',
                       marker = list(color = 'orange')) %>%
  layout(title = "Precio vs Número de Baños",
         xaxis = list(title = "Número de Baños"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs número de habitaciones
plot_habitaciones <- plot_ly(base1, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers',
                             marker = list(color = 'purple')) %>%
  layout(title = "Precio vs Número de Habitaciones",
         xaxis = list(title = "Número de Habitaciones"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs zona
plot_zona <- plot_ly(base1, x = ~zona, y = ~preciom, type = 'box',
                     marker = list(color = 'red')) %>%
  layout(title = "Precio vs Zona",
         xaxis = list(title = "Zona"),
         yaxis = list(title = "Precio (millones)"))

# Combinar todos los gráficos en una sola visualización
subplot(plot_area, plot_estrato, plot_banios, plot_habitaciones, plot_zona, 
        nrows = 3, shareX = FALSE, shareY = FALSE, titleX = TRUE, titleY = TRUE)
  1. Modelo de Regresión Lineal Múltiple: Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).
# Estimar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base1)

# Resumen del modelo
summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -761.11  -84.10  -16.36   52.22  925.67 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -245.62878   60.86958  -4.035 7.27e-05 ***
## areaconst       0.66444    0.06703   9.913  < 2e-16 ***
## estrato        85.58184   13.17690   6.495 4.51e-10 ***
## habitaciones    8.91428    7.14129   1.248    0.213    
## parqueaderos   28.05949    6.77575   4.141 4.74e-05 ***
## banios         11.49860    9.51130   1.209    0.228    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 152.8 on 248 degrees of freedom
## Multiple R-squared:  0.5952, Adjusted R-squared:  0.587 
## F-statistic: 72.92 on 5 and 248 DF,  p-value: < 2.2e-16

Ajuste del modelo y implicaciones:

Un R² de aproximadamente 60% sugiere que el modelo es bastante útil, pero hay espacio para mejoras. El ajuste podría ser mejorado incluyendo variables adicionales que podrían influir en el precio de las casas o quitando la variable habitaciones

Otra forma de mejorar el modelo puede ser explorar transformaciones de las variables existentes, como logaritmos, para capturar relaciones no lineales.

  1. Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).
#Validación de supuestos
#Linealidad
# Gráfico de residuos vs. valores ajustados
plot(modelo$fitted.values, modelo$residuals,
     xlab = "Valores Ajustados",
     ylab = "Residuos",
     main = "Residuos vs. Valores Ajustados")
abline(h = 0, col = "red")

En un modelo lineal, los residuos deben estar distribuidos aleatoriamente alrededor de cero sin patrones evidentes.

# Supuesto de independencia
# install.packages("lmtest")

library(lmtest)
## Warning: package 'lmtest' was built under R version 4.3.3
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
# Test de Durbin-Watson
dwtest(modelo)
## 
##  Durbin-Watson test
## 
## data:  modelo
## DW = 1.9309, p-value = 0.268
## alternative hypothesis: true autocorrelation is greater than 0

El test de Durbin-Watson proporciona arrojó un valor cercano a 2 y significancia p>0,05, lo que sugiere que no hay autocorrelación en los residuos.

# Gráfico Q-Q de los residuos
qqnorm(modelo$residuals, main = "Gráfico Q-Q de los Residuos")
qqline(modelo$residuals, col = "red")

# Prueba de Shapiro-Wilk para normalidad
shapiro.test(modelo$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo$residuals
## W = 0.87822, p-value = 2.263e-13

En el gráfico Q-Q, los puntos deben seguir aproximadamente la línea recta. En este caso se nota una significativa desviación de esta línea, lo que puede indicar que los residuos no siguen una distribución normal.

La prueba de Shapiro-Wilk muestra que los residuos no siguen una distribución normal. Esto es evidente por el valor p muy bajo, que sugiere que la distribución de los residuos es significativamente diferente de una normal.

Ajuste del modelo

Se propone un ajuste para mejorar el modelo, haciendo una transformación logaritmica de la variable precio

#modelo 2
#transformando
# Crear una nueva variable con el logaritmo de 'preciom'
base1$log_preciom <- log(base1$preciom)
# Ajustar el modelo de regresión lineal con la variable transformada
modelo_log <- lm(log_preciom ~ areaconst + estrato + parqueaderos + banios, data = base1)
# Ver el resumen del modelo ajustado
summary(modelo_log)
## 
## Call:
## lm(formula = log_preciom ~ areaconst + estrato + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.10451 -0.16294 -0.01539  0.14701  1.05844 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  4.4538292  0.0974986  45.681  < 2e-16 ***
## areaconst    0.0011425  0.0001106  10.326  < 2e-16 ***
## estrato      0.2158183  0.0221666   9.736  < 2e-16 ***
## parqueaderos 0.0489749  0.0117473   4.169 4.23e-05 ***
## banios       0.0556371  0.0139136   3.999 8.40e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.265 on 249 degrees of freedom
## Multiple R-squared:  0.668,  Adjusted R-squared:  0.6627 
## F-statistic: 125.2 on 4 and 249 DF,  p-value: < 2.2e-16
# Gráfico de residuos vs. valores ajustados para el modelo logarítmico
plot(modelo_log$fitted.values, modelo_log$residuals,
     xlab = "Valores Ajustados",
     ylab = "Residuos",
     main = "Residuos vs. Valores Ajustados")
abline(h = 0, col = "red")

# Gráfico Q-Q de los residuos del modelo logarítmico
qqnorm(modelo_log$residuals, main = "Gráfico Q-Q de los Residuos")
qqline(modelo_log$residuals, col = "red")

# Prueba de Shapiro-Wilk para los residuos del modelo logarítmico
shapiro.test(modelo_log$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo_log$residuals
## W = 0.97957, p-value = 0.001026

Este segundo modelo tiene un mejor desempeño y cumple el supuesto de normalidad de los errores, por lo que este será el utilizado para la predicción

  1. Predicción del Valor de la Vivienda: Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.
######predicción
# Crear un DataFrame con las características para la predicción
nuevas_caracteristicas <- data.frame(
  areaconst = c(200, 200),
  estrato = c(4, 5),
  parqueaderos = c(1, 1),
  banios = c(2, 2),
  habitaciones = c(4, 4),
  tipo = c("Casa", "Casa"),
  zona = c("Norte", "Norte")
)

# Convertir las variables categóricas en factores
nuevas_caracteristicas$tipo <- as.factor(nuevas_caracteristicas$tipo)
nuevas_caracteristicas$zona <- as.factor(nuevas_caracteristicas$zona)

# Realizar las predicciones en el logaritmo del precio
predicciones_log <- predict(modelo_log, nuevas_caracteristicas)

# Convertir las predicciones de vuelta a la escala original
predicciones_precios <- exp(predicciones_log)

# Añadir las predicciones al DataFrame original
nuevas_caracteristicas$prediccion_precio <- predicciones_precios

# Mostrar las predicciones
print(nuevas_caracteristicas)
##   areaconst estrato parqueaderos banios habitaciones tipo  zona
## 1       200       4            1      2            4 Casa Norte
## 2       200       5            1      2            4 Casa Norte
##   prediccion_precio
## 1          300.6214
## 2          373.0342
  1. Selección de las Mejores Ofertas: Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda. Tenga en cuenta que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.
##### Ofertas según crédito
# Filtrar ofertas que se ajusten a la predicción del modelo y al presupuesto máximo
ofertas_potenciales <- subset(base1, preciom <= 350)  # Filtrar por presupuesto

# Calcular la diferencia entre el precio máximo y el precio de cada oferta
ofertas_potenciales$diferencia_precio <- abs(ofertas_potenciales$preciom - 350)

# Ordenar por la diferencia en precio
ofertas_potenciales <- ofertas_potenciales[order(ofertas_potenciales$diferencia_precio), ]

# Seleccionar las primeras 5 ofertas
top_5_ofertas <- head(ofertas_potenciales, 5)


# Instalar y cargar el paquete leaflet si no está instalado
# install.packages("leaflet")
library(leaflet)

# Crear el mapa sin el popup
mapa <- leaflet(data = top_5_ofertas) %>%
  addTiles() %>%
  addMarkers(lng = ~longitud, lat = ~latitud)

# Mostrar el mapa
mapa
top_5_ofertas

Anexo 2: Aplicación metodología solicitud 2

  1. Selección de Información:
# Filtrar la base de datos original para obtener solo las casas en la zona norte
base2 <- vivienda1 %>%
  filter(zona == "Zona Sur" & tipo == "Apartamento")

Primeros 3 registros de las bases:

# Mostrar los primeros 3 registros de la nueva base de datos
head(base2, 3)

Tablas caso 2:

# Tabla de conteo por zona
table(base2$zona)
## 
## Zona Sur 
##     1860
# Tabla de conteo por tipo
table(base2$tipo)
## 
## Apartamento 
##        1860
tabla_tipo_est <- addmargins(table(base2$tipo, base2$estrato))
tabla_tipo_est
##              
##                  3    4    5    6  Sum
##   Apartamento   79  657  784  340 1860
##   Sum           79  657  784  340 1860
tabla_tipo_parq <- addmargins(table(base2$tipo, base2$parqueaderos))
tabla_tipo_parq
##              
##                  1    2    3    4  Sum
##   Apartamento 1210  578   53   19 1860
##   Sum         1210  578   53   19 1860
tabla_tipo_hab <- addmargins(table(base2$tipo, base2$habitaciones))
tabla_tipo_hab
##              
##                  0    1    2    3    4    5    6  Sum
##   Apartamento    4   14  243 1298  287   12    2 1860
##   Sum            4   14  243 1298  287   12    2 1860

Mapa con los puntos de las bases.

## Mapa
#install.packages("leaflet")
library(leaflet)

# Crear el mapa con leaflet
mapa <- leaflet(base2) %>%
  addTiles() %>%  # Añadir capa base de OpenStreetMap
  addMarkers(~longitud, ~latitud, popup = ~paste("Precio:", preciom, "<br>", "Habitaciones:", habitaciones)) %>%
  addCircleMarkers(~longitud, ~latitud, radius = 5, color = "blue", stroke = FALSE, fillOpacity = 0.7)

# Mostrar el mapa
mapa

A pesar de estar filtrada la base con la variable zona, en el mapa se nota que no todos los puntos ubicados coinciden con las zonas deseadas.

  1. Análisis de correlación: Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.
library(plotly)
# Instalar plotly si no lo tienes instalado
# install.packages("plotly")

# Cargar el paquete
library(plotly)
# Gráfico interactivo para precio vs área construida
plot_area <- plot_ly(base1, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers',
                     marker = list(color = 'blue')) %>%
  layout(title = "Precio vs Área Construida",
         xaxis = list(title = "Área Construida (m²)"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs estrato
plot_estrato <- plot_ly(base1, x = ~estrato, y = ~preciom, type = 'box',
                        marker = list(color = 'green')) %>%
  layout(title = "Precio vs Estrato",
         xaxis = list(title = "Estrato"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs número de baños
plot_banios <- plot_ly(base1, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers',
                       marker = list(color = 'orange')) %>%
  layout(title = "Precio vs Número de Baños",
         xaxis = list(title = "Número de Baños"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs número de habitaciones
plot_habitaciones <- plot_ly(base1, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers',
                             marker = list(color = 'purple')) %>%
  layout(title = "Precio vs Número de Habitaciones",
         xaxis = list(title = "Número de Habitaciones"),
         yaxis = list(title = "Precio (millones)"))

# Gráfico interactivo para precio vs zona
plot_zona <- plot_ly(base1, x = ~zona, y = ~preciom, type = 'box',
                     marker = list(color = 'red')) %>%
  layout(title = "Precio vs Zona",
         xaxis = list(title = "Zona"),
         yaxis = list(title = "Precio (millones)"))

# Combinar todos los gráficos en una sola visualización
subplot(plot_area, plot_estrato, plot_banios, plot_habitaciones, plot_zona, 
        nrows = 3, shareX = FALSE, shareY = FALSE, titleX = TRUE, titleY = TRUE)
  1. Modelo de Regresión Lineal Múltiple: Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).
# Estimar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = base1)

# Resumen del modelo
summary(modelo)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -761.11  -84.10  -16.36   52.22  925.67 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -245.62878   60.86958  -4.035 7.27e-05 ***
## areaconst       0.66444    0.06703   9.913  < 2e-16 ***
## estrato        85.58184   13.17690   6.495 4.51e-10 ***
## habitaciones    8.91428    7.14129   1.248    0.213    
## parqueaderos   28.05949    6.77575   4.141 4.74e-05 ***
## banios         11.49860    9.51130   1.209    0.228    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 152.8 on 248 degrees of freedom
## Multiple R-squared:  0.5952, Adjusted R-squared:  0.587 
## F-statistic: 72.92 on 5 and 248 DF,  p-value: < 2.2e-16

Ajuste del modelo y implicaciones:

Un R² de aproximadamente 60% sugiere que el modelo es bastante útil, pero hay espacio para mejoras. El ajuste podría ser mejorado incluyendo variables adicionales que podrían influir en el precio de las casas o quitando la variable habitaciones

Otra forma de mejorar el modelo puede ser explorar transformaciones de las variables existentes, como logaritmos, para capturar relaciones no lineales.

  1. Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).
#Validación de supuestos
#Linealidad
# Gráfico de residuos vs. valores ajustados
plot(modelo$fitted.values, modelo$residuals,
     xlab = "Valores Ajustados",
     ylab = "Residuos",
     main = "Residuos vs. Valores Ajustados")
abline(h = 0, col = "red")

En un modelo lineal, los residuos deben estar distribuidos aleatoriamente alrededor de cero sin patrones evidentes.

# Supuesto de independencia
# install.packages("lmtest")

library(lmtest)

# Test de Durbin-Watson
dwtest(modelo)
## 
##  Durbin-Watson test
## 
## data:  modelo
## DW = 1.9309, p-value = 0.268
## alternative hypothesis: true autocorrelation is greater than 0

El test de Durbin-Watson proporciona arrojó un valor cercano a 2 y significancia p>0,05, lo que sugiere que no hay autocorrelación en los residuos.

# Gráfico Q-Q de los residuos
qqnorm(modelo$residuals, main = "Gráfico Q-Q de los Residuos")
qqline(modelo$residuals, col = "red")

# Prueba de Shapiro-Wilk para normalidad
shapiro.test(modelo$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo$residuals
## W = 0.87822, p-value = 2.263e-13

En el gráfico Q-Q, los puntos deben seguir aproximadamente la línea recta. En este caso se nota una significativa desviación de esta línea, lo que puede indicar que los residuos no siguen una distribución normal.

La prueba de Shapiro-Wilk muestra que los residuos no siguen una distribución normal. Esto es evidente por el valor p muy bajo, que sugiere que la distribución de los residuos es significativamente diferente de una normal.

Ajuste del modelo

Se propone un ajuste para mejorar el modelo, haciendo una transformación logaritmica de la variable precio

#modelo 2
#transformando
# Crear una nueva variable con el logaritmo de 'preciom'
base1$log_preciom <- log(base1$preciom)
# Ajustar el modelo de regresión lineal con la variable transformada
modelo_log <- lm(log_preciom ~ areaconst + estrato + parqueaderos + banios, data = base1)
# Ver el resumen del modelo ajustado
summary(modelo_log)
## 
## Call:
## lm(formula = log_preciom ~ areaconst + estrato + parqueaderos + 
##     banios, data = base1)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.10451 -0.16294 -0.01539  0.14701  1.05844 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  4.4538292  0.0974986  45.681  < 2e-16 ***
## areaconst    0.0011425  0.0001106  10.326  < 2e-16 ***
## estrato      0.2158183  0.0221666   9.736  < 2e-16 ***
## parqueaderos 0.0489749  0.0117473   4.169 4.23e-05 ***
## banios       0.0556371  0.0139136   3.999 8.40e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.265 on 249 degrees of freedom
## Multiple R-squared:  0.668,  Adjusted R-squared:  0.6627 
## F-statistic: 125.2 on 4 and 249 DF,  p-value: < 2.2e-16
# Gráfico de residuos vs. valores ajustados para el modelo logarítmico
plot(modelo_log$fitted.values, modelo_log$residuals,
     xlab = "Valores Ajustados",
     ylab = "Residuos",
     main = "Residuos vs. Valores Ajustados")
abline(h = 0, col = "red")

# Gráfico Q-Q de los residuos del modelo logarítmico
qqnorm(modelo_log$residuals, main = "Gráfico Q-Q de los Residuos")
qqline(modelo_log$residuals, col = "red")

# Prueba de Shapiro-Wilk para los residuos del modelo logarítmico
shapiro.test(modelo_log$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo_log$residuals
## W = 0.97957, p-value = 0.001026

Este segundo modelo tiene un mejor desempeño y cumple el supuesto de normalidad de los errores, por lo que este será el utilizado para la predicción

  1. Predicción del Valor de la Vivienda: Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.
######predicción
# Crear un DataFrame con las características para la predicción
nuevas_caracteristicas <- data.frame(
  areaconst = c(200, 200),
  estrato = c(4, 5),
  parqueaderos = c(1, 1),
  banios = c(2, 2),
  habitaciones = c(4, 4),
  tipo = c("Casa", "Casa"),
  zona = c("Norte", "Norte")
)

# Convertir las variables categóricas en factores
nuevas_caracteristicas$tipo <- as.factor(nuevas_caracteristicas$tipo)
nuevas_caracteristicas$zona <- as.factor(nuevas_caracteristicas$zona)

# Realizar las predicciones en el logaritmo del precio
predicciones_log <- predict(modelo_log, nuevas_caracteristicas)

# Convertir las predicciones de vuelta a la escala original
predicciones_precios <- exp(predicciones_log)

# Añadir las predicciones al DataFrame original
nuevas_caracteristicas$prediccion_precio <- predicciones_precios

# Mostrar las predicciones
print(nuevas_caracteristicas)
##   areaconst estrato parqueaderos banios habitaciones tipo  zona
## 1       200       4            1      2            4 Casa Norte
## 2       200       5            1      2            4 Casa Norte
##   prediccion_precio
## 1          300.6214
## 2          373.0342
  1. Selección de las Mejores Ofertas: Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda. Tenga en cuenta que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.
##### Ofertas según crédito
# Filtrar ofertas que se ajusten a la predicción del modelo y al presupuesto máximo
ofertas_potenciales <- subset(base1, preciom <= 350)  # Filtrar por presupuesto

# Calcular la diferencia entre el precio máximo y el precio de cada oferta
ofertas_potenciales$diferencia_precio <- abs(ofertas_potenciales$preciom - 350)

# Ordenar por la diferencia en precio
ofertas_potenciales <- ofertas_potenciales[order(ofertas_potenciales$diferencia_precio), ]

# Seleccionar las primeras 5 ofertas
top_5_ofertas <- head(ofertas_potenciales, 5)


# Instalar y cargar el paquete leaflet si no está instalado
# install.packages("leaflet")
library(leaflet)

# Crear el mapa sin el popup
mapa <- leaflet(data = top_5_ofertas) %>%
  addTiles() %>%
  addMarkers(lng = ~longitud, lat = ~latitud)

# Mostrar el mapa
mapa
top_5_ofertas