De acuerdo a los datos obtenidos de la base de datos “vivienda” del
paquete devtools:
1. Realice un filtro a la base de datos e incluya solo las ofertas
de casas, de la zona norte de la ciudad. Presente los primeros 3
registros de las bases y algunas tablas que comprueben la consulta.
(Adicional un mapa con los puntos de las bases. Discutir si todos los
puntos se ubican en la zona correspondiente o se presentan valores en
otras zonas, por que?).
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>
Hacemos uso de la librería leaflet para generar un mapa de Cali
donde se ubican las viviendas tipo Casa en la Zona Norte.
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, 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 posibles
errores en los datos, como errores de entrada o errores de
digitación.
2. 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.
* 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.
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"))
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"))
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"))
box_plot_zona
3. 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).
* Para esta finalidad utilizaremos la función lm() en R 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 que 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.
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:
Norte:
model <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = filtered_data)
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
te 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 te 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 otros estadísticos 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 problema.
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
4. 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).
* 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 términos más simples, 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. Esto se refleja en la ecuación de un modelo de regresión
lineal.
# 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")

# 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")

# 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")

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

## 513 405
## 309 239
# Prueba de Shapiro-Wilk para la normalidad
#shapiro.test(model$residuals)
# 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
# Prueba de multicolinealidad
vif(model)
## areaconst estrato habitaciones parqueaderos banios
## 1.460998 1.307757 1.721015 1.226334 1.967421
# 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")

# 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")

# Gráfico de residuos estandarizados vs. una variable relevante (si aplica)
#plot(rstandard(model) ~ vivienda$estrato, xlab = "Variable Relevante", ylab = "Residuos Estandarizados", main = "Heteroscedasticidad Condicional")
Con el modelo identificado se predecirá el precio de la vivienda con
las características de la primera solicitud en R
# Datos de la primera solicitud
nueva_solicitud <- data.frame(
areaconst = 200,
estrato = 4,
habitaciones = 4,
parqueaderos = 1,
banios = 2
)
# Construir la predicción
prediccion_precio <- predict(model, newdata = nueva_solicitud)
prediccion_precio
## 1
## 312.101
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>
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
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"))
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"))
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"))
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
* 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")

# 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")

# 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")

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

## 2383 1533
## 2042 1316
# Prueba de Shapiro-Wilk para la normalidad
#shapiro.test(model$residuals)
# 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
# Prueba de multicolinealidad
vif(model_2)
## areaconst estrato habitaciones parqueaderos banios
## 2.066518 1.545162 1.429280 1.737878 2.529494
# 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")

# 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")

# Gráfico de residuos estandarizados vs. una variable relevante (si aplica)
#plot(rstandard(model) ~ vivienda$estrato, xlab = "Variable Relevante", ylab = "Residuos Estandarizados", main = "Heteroscedasticidad Condicional")
Con el modelo identificado debe predecir el precio de la vivienda
con las características de la segunda solicitud en R
# Datos de la primera solicitud
nueva_solicitud_2 <- data.frame(
areaconst = 300,
estrato = 5,
habitaciones = 5,
parqueaderos = 3,
banios = 3
)
#falta poner que el estrato sean 5 o 6 de acuerdo a la solicitud
# Construir la predicción #2
prediccion_precio_2 <- predict(model_2, newdata = nueva_solicitud_2)
prediccion_precio_2
## 1
## 675.0247
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