Instalación y cargue de librerias

#install.packages("devtools") 
#devtools::install_github("centromagis/paqueteMETODOS") 
#install.packages("tinytex")
#install.packages("dplyr")
#install.packages("modeest")
#install.packages("e1071")
#install.packages("summarytools")
#install.packages("read")
#install.packages("readxl")
#install.packages("patchwork")
#install.packages("magrittr")
#install.packages("naniar")
library(patchwork)
library(summarytools)
library(dplyr)
library(patchwork)
library(summarytools)
library(modeest)  
library(ggplot2)
library(nortest)
library(e1071)
library(naniar)
library(tinytex)
library(readxl)
library(magrittr) 
library(plotly) 
library(paqueteMETODOS)
library(lmtest)
library(tidyr)
library(gridExtra)
library(GGally)
library(patchwork)
library(MASS)
library(stargazer)

1.Realice un análisis exploratorio de las variables precio de vivienda (millones de pesos COP) y área de la vivienda (metros cuadrados) - incluir gráficos e indicadores apropiados interpretados.

data(vivienda4)
head(vivienda4)
## # A tibble: 6 × 5
##   zona       estrato preciom areaconst tipo       
##   <fct>      <fct>     <dbl>     <dbl> <fct>      
## 1 Zona Norte 4          232.        52 Apartamento
## 2 Zona Norte 4          272.       160 Casa       
## 3 Zona Norte 4          255.       108 Apartamento
## 4 Zona Sur   4          258.        96 Apartamento
## 5 Zona Norte 4          250.        82 Apartamento
## 6 Zona Norte 4          261.       117 Casa

Observar la existencia de datos faltantes:

colSums(is.na(vivienda4)) %>% as.data.frame()
##           .
## zona      0
## estrato   0
## preciom   0
## areaconst 0
## tipo      0
gg_miss_var(vivienda4)

Histograma de precios.

h = ggplot(data = vivienda4, aes(x = preciom)) +
  geom_histogram(binwidth = 5, fill = "blue", color = "black", alpha = 0.7) +
  labs(title = "Histograma de precios", 
       x = "Precio (millones de pesos)", 
       y = "Frecuencia") +
  geom_vline(aes(xintercept = mean(preciom, na.rm = TRUE)), 
             color = "red", linetype = "dashed", size = 1) +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
ggplotly(h)

Histograma de area construida.

z = ggplot(data = vivienda4, aes(x = areaconst)) +
  geom_histogram(binwidth = 5, fill = "blue", color = "black", alpha = 0.7) +
  labs(title = "Histograma de area construida", 
       x = "Area en metros cuadrados", 
       y = "Frecuencia") +
  geom_vline(aes(xintercept = mean(areaconst, na.rm = TRUE)), 
             color = "red", linetype = "dashed", size = 1) +
  theme_minimal()

ggplotly(z)

Distribucion del area por zona.

boxplot(vivienda4$areaconst ~ vivienda4$zona, 
        main = "Distribucion del area por zona",
        ylab = "Metros cuadrados",
        xlab = "Zona", 
        col = c("sienna", "darkolivegreen", "burlywood", "peru", "tan"), 
        border = "black",  
        outline = TRUE)

abline(h = mean(vivienda4$areaconst, na.rm = TRUE), col = "red", lwd = 2, lty = 2)

Precio y area promedio por zona.

promedios_por_zona = vivienda4 %>%
  group_by(zona) %>%
  summarise(
    Precio_Promedio = mean(preciom, na.rm = TRUE),
    Area_Promedio = mean(areaconst, na.rm = TRUE)
  )
print(promedios_por_zona)
## # A tibble: 5 × 3
##   zona         Precio_Promedio Area_Promedio
##   <fct>                  <dbl>         <dbl>
## 1 Zona Centro             257.         112. 
## 2 Zona Norte              244.          87.8
## 3 Zona Oeste              241.          81.1
## 4 Zona Oriente            265.         125. 
## 5 Zona Sur                244.          87.6

Cantidad de edificaciones por zona.

casas_por_zona = vivienda4 %>%
  group_by(zona) %>%
  summarise(Edificaciones = n())
print(casas_por_zona)
## # A tibble: 5 × 2
##   zona         Edificaciones
##   <fct>                <int>
## 1 Zona Centro              8
## 2 Zona Norte             288
## 3 Zona Oeste              60
## 4 Zona Oriente             6
## 5 Zona Sur              1344
  • La Zona Oriente tiene el precio promedio más alto de 265.22 millones de pesos y también la mayor área promedio construida con 125.17 m².
  • La Zona Centro tiene un precio promedio alto de 257.26 millones de pesos, con un área promedio construida de 112.13 m².
  • La Zona Norte, Zona Oeste y Zona Sur tienen precios promedio similares, alrededor de 243 millones de pesos, pero difieren en el área promedio, siendo la Zona Norte y la Zona Sur de aproximadamente 87 m², mientras que la Zona Oeste tiene un área promedio ligeramente menor con 81.12 m².

Relación entre precio y Area construida.

t2 = ggplot(data = vivienda4, aes(x = areaconst, y = preciom, color = tipo)) +
  geom_point(alpha = 0.5)+
  labs(title = "Relacion entre precio y area construida",
    x = "Area construida (metros cuadrados)",
    y = "Precio (millones de pesos COP)") + 
 theme_minimal() 
ggplotly (t2)

Relación entre precio y área construida por tipo de edificación.

t= ggplot(vivienda4, aes(y=preciom , x=areaconst))+
  geom_point()+
  facet_wrap(~ tipo) 
ggplotly(t)

Precio y area construida promedio por tipo de edificación.

promedios = vivienda4 %>%
  group_by(tipo) %>%
  summarise(
    Promedio_precio = mean(preciom, na.rm = TRUE),
    Promedio_area = mean(areaconst, na.rm = TRUE)
  )
print(as.data.frame(promedios))
##          tipo Promedio_precio Promedio_area
## 1 Apartamento        237.6831      75.47836
## 2        Casa        267.6249     135.91545

Prueba de Shapiro para conocer la distribución de las varaibles.

shapiro.test(vivienda4$preciom)
## 
##  Shapiro-Wilk normality test
## 
## data:  vivienda4$preciom
## W = 0.89151, p-value < 2.2e-16
shapiro.test(vivienda4$areaconst)
## 
##  Shapiro-Wilk normality test
## 
## data:  vivienda4$areaconst
## W = 0.8168, p-value < 2.2e-16

El anterior resultado expone que las variables mencionadas no siguen una distribución normal, y por lo tanto esos datos atipicos pueden ser imputados con la mediana en cuanto on variables numericas.

Calculo del rango intercuartilico e imputacion de los outliers.

mark_outliers_median <- function(x) {
  Q1 = quantile(x, 0.25, na.rm = TRUE)
  Q3 = quantile(x, 0.75, na.rm = TRUE)
  IQR = Q3 - Q1
  lower_bound = Q1 - 1.5 * IQR
  upper_bound = Q3 + 1.5 * IQR
  mediana <- median(x, na.rm = TRUE)
  
  x <- ifelse(x < lower_bound | x > upper_bound, mediana, x)
  return(x)
}

preciom_outliers = vivienda4 %>%
  dplyr::select(tipo, preciom, areaconst) %>%
  mutate(Outliers = "Con Outliers")

preciom_sin_outliers = vivienda4 %>%
  mutate(preciom = mark_outliers_median(preciom),
         areaconst = mark_outliers_median(areaconst)) %>%  
  dplyr::select(tipo, preciom, areaconst) %>%
  mutate(Outliers = "Sin Outliers")


datos_combinados = bind_rows(preciom_outliers, preciom_sin_outliers)

datos_largos = datos_combinados %>%
  pivot_longer(cols = c(preciom, areaconst), names_to = "Tipo_Venta", values_to = "Valores")

grafico_cajas = ggplot(datos_largos, aes(x = tipo, y = Valores, fill = tipo)) + 
  geom_boxplot(alpha = 0.7) + 
  facet_wrap(~ Tipo_Venta + Outliers, scales = "free_y", ncol = 2) +
  labs(title = "Distribucion de Precio y Area Construida",
       x = "Tipo de Vivienda",
       y = "Valores",
       fill = "Tipo de Vivienda") + 
  theme_minimal()

print(grafico_cajas)

Precio y area construida promedio por tipo de edificación para datos imputados.

promedios2 = datos_combinados %>%
  group_by(tipo) %>%
  summarise(
    Promedio_precio = mean(preciom, na.rm = TRUE),
    Promedio_area = mean(areaconst, na.rm = TRUE)
  )
print(as.data.frame(promedios2))
##          tipo Promedio_precio Promedio_area
## 1 Apartamento        237.4157      74.78577
## 2        Casa        259.1858     116.68367

2.Realice un análisis exploratorio bivariado de datos, enfocado en la relación entre la variable respuesta (precio) en función de la variable predictora (área construida) - incluir gráficos e indicadores apropiados interpretados.

Correlaciones para datos con outliers y sin outliers.

a=ggpairs(vivienda4[,4:3], title="Correlaciones con outliers") 
b=ggpairs(datos_combinados[,3:2], title="Correlaciones sin outliers") 
g_a = ggmatrix_gtable(a)
g_b = ggmatrix_gtable(b)
grid.arrange(g_a, g_b, nrow = 1)

3.Estime el modelo de regresión lineal simple entre precio = f(área) + ε. Interprete los coeficientes del modelo β0 y β1 en caso de ser correcto.

Regresión lineal.

modelo1 = lm(vivienda4$preciom ~ vivienda4$areaconst, data=vivienda4)
summary(modelo1)
## 
## Call:
## lm(formula = vivienda4$preciom ~ vivienda4$areaconst, data = vivienda4)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -26.5997  -5.0198  -0.0056   4.6648  24.4010 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         1.998e+02  4.514e-01   442.7   <2e-16 ***
## vivienda4$areaconst 5.009e-01  4.758e-03   105.3   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 7.141 on 1704 degrees of freedom
## Multiple R-squared:  0.8667, Adjusted R-squared:  0.8666 
## F-statistic: 1.108e+04 on 1 and 1704 DF,  p-value: < 2.2e-16

Para \(βo\) =199.8 representa el precio cuando el área construida es igual a 0 metros cuadrados. En este caso, el intercepto expone en este ejemplo que el precio estimado de una vivienda con un área construida de 0 m² es 199.8 millones de pesos. Por otro lado \(β1\), indica que por cada metro cuadrado adicional de área construida, se espera que el precio de la vivienda aumente en 0.5009 millones de pesos.

4.Interprete el indicador de bondad R2.

El R2 es 0.8776 y este resultado implica que la variabilidad en los precios de las viviendas es explicada por el área construida en un 86%. En otras palabras, el modelo de regresión basado en el área construida tiene un buen ajuste a los datos, ya que puede explicar una gran parte de la variabilidad de los precios de las viviendas.

Hipotesis para pruebas.

\(Ho\)= Hipotesis nula de distribución normal para un p-valor mayor al 5%.

\(Hi\)= Hipotesis alternativa de no distribucion normal para un p-valor menor al 5%.

5.Realice la validación de los supuestos del modelo por medio de gráficos apropiados, interpretarlos y sugerir posibles soluciones si se violan algunos de ellos. Utilice las pruebas de hipótesis para la validación de supuestos y compare los resultados con lo observado en los gráficos asociados.

Gráfico de residuos.

par(mfrow=c(2,2))
plot(modelo1)

Prueba de Shapiro

shapiro.test(modelo1$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modelo1$residuals
## W = 0.99911, p-value = 0.5907

Para la prueba Shapiro los residuos se distribuyen normalmente.

Prueba de Anderson-Darling.

nortest::ad.test(modelo1$residuals)
## 
##  Anderson-Darling normality test
## 
## data:  modelo1$residuals
## A = 0.37464, p-value = 0.4148

Tanto la prueba de Shapiro-Wilk como la prueba de Anderson-Darling indican que los residuos del modelo parecen seguir una distribución normal.

Prueba de Kolmogorov-Smirnov.

lillie.test(modelo1$residuals)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  modelo1$residuals
## D = 0.016639, p-value = 0.3019

Al igual que las pruebas de Shapiro-Wilk y Anderson-Darling, la prueba de Lilliefors (Kolmogorov-Smirnov) también confirma que los residuos del modelo parecen seguir una distribución normal.

Homocedasticidad.

Hipotesis para Homocedasticidad

\(Ho\)= Hipotesis nula - los residuos del modelo tienen varianza constante (homocedasticidad) para un p-valor mayor al 5%.

\(Hi\)= Hipotesis alternativa - los residuos no tienen varianza constante (heterocedasticidad)para un p-valor menor al 5%.

Prueba de Breusch-Pagan.

bptest(modelo1)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo1
## BP = 0.089882, df = 1, p-value = 0.7643

Dado que el p-value = 0.7643 es mucho mayor que 0.05, se acepta la hipótesis nula.

*Gráfico de residuos vs. valores ajustados.

valores_ajustados = fitted(modelo1)  
residuos = residuals(modelo1)    
plot(valores_ajustados, residuos,
     main = "Residuos vs Valores Ajustados", xlab = "Valores Ajustados", ylab = "Residuos", pch = 20, col = "black")
abline(h = 0, col = "red", lwd = 2)

Autocorrelación de los residuos.

Hipotesis para Durbin

\(Ho\)= Hipotesis nula de que No hay autocorrelación entre los residuos del modelo - DW = 2 y p- valor mayor a 0.5.

\(Hi\)= Existe autocorrelación positiva o negativa entre los residuos cuando DW es <2 o >2.

lmtest::dwtest(modelo1)
## 
##  Durbin-Watson test
## 
## data:  modelo1
## DW = 2.0651, p-value = 0.9092
## alternative hypothesis: true autocorrelation is greater than 0

Para esta prueba si bien DW es mayor que 2, esta superioridad es muy ligera, ademas se da validez al la hipotesis nula cuando p valor es mayor a 5% (0.9092) indica que no hay autocorrelación significativa.

Construir un intervalo de confianza (95%) para el coeficiente β1, interpretar y concluir si el coeficiente es igual a cero o no. Compare este resultado con una prueba de hipótesis t..

Intervalo de confianza.

b1 = 0.5009
errorb1 = 0.004758
valorz <- 1.96 
lower_bound <- b1 - valorz * errorb1
upper_bound <- b1 + valorz * errorb1

cat("Intervalo de confianza del 95% para β1:", lower_bound, "a", upper_bound, "\n")
## Intervalo de confianza del 95% para β1: 0.4915743 a 0.5102257

Prueba T.

pruebat = b1 / errorb1
cat("Valor t:", pruebat, "\n")
## Valor t: 105.2753

6.¿Cuál sería el precio promedio estimado para un apartamento de 110 metros cuadrados?

precio_estimado = coef(modelo1)["(Intercept)"] + coef(modelo1)["vivienda4$areaconst"] * 110
cat("El precio estimado para un apartamento de 110 metros cuadrador es: ", precio_estimado, "millones de pesos\n")
## El precio estimado para un apartamento de 110 metros cuadrador es:  254.9082 millones de pesos

Conclusión general sobre el modelo:

  • Normalidad: Cumple con el supuesto de normalidad de los residuos.
  • Independencia: Cumple con el supuesto de independencia de los residuos.
  • Homoscedasticidad: Cumple con el supuesto de varianza constante de los errores (homoscedasticidad).
  • Linealidad: Cumple con el supuesto de una relación lineal entre el área construida y el precio.
  • R2: El modelo tiene un buen ajuste con un R2 alto.

El modelo cumple con todos los supuestos importantes de la regresión lineal y tiene un R2 elevado. Esto es importante para explicar que el área construida es un predictor importante y que el modelo es robusto en términos de ajuste a los datos y cumplimiento de los supuestos.

7.Estime varios modelos y compare los resultados obtenidos?

Modelos.

modelo2_loglin = lm(log(vivienda4$preciom) ~ vivienda4$areaconst, data = vivienda4)
modelo3_linlog = lm(vivienda4$preciom ~ log(vivienda4$areaconst), data = vivienda4)
modelo4_loglog = lm(log(vivienda4$preciom) ~ log(vivienda4$areaconst), data = vivienda4)

Comparación de los resultados.

stargazer::stargazer(modelo1, modelo2_loglin, modelo3_linlog, modelo4_loglog, type="text", df=FALSE)
## 
## ========================================================================
##                                     Dependent variable:                 
##                     ----------------------------------------------------
##                        preciom      preciom)     preciom      preciom)  
##                          (1)          (2)          (3)          (4)     
## ------------------------------------------------------------------------
## areaconst             0.501***      0.002***                            
##                        (0.005)     (0.00002)                            
##                                                                         
## areaconst)                                      50.224***     0.197***  
##                                                  (0.549)      (0.002)   
##                                                                         
## Constant             199.810***     5.322***    22.521***     4.624***  
##                        (0.451)      (0.002)      (2.427)      (0.010)   
##                                                                         
## ------------------------------------------------------------------------
## Observations            1,706        1,706        1,706        1,706    
## R2                      0.867        0.852        0.831        0.829    
## Adjusted R2             0.867        0.852        0.831        0.829    
## Residual Std. Error     7.141        0.030        8.050        0.032    
## F Statistic         11,081.520*** 9,803.025*** 8,357.863*** 8,268.827***
## ========================================================================
## Note:                                        *p<0.1; **p<0.05; ***p<0.01

El Modelo 1 tiene el mejor R2 de 0.867, lo que significa que es el modelo que mejor ajusta los datos y explica más variabilidad en el precio de las viviendas.

Modelo BOXCOC.

modelob4 = lm(preciom ~ areaconst, data = vivienda4)
boxcoxlm = boxcox(modelob4, lambda = seq(-2, 2, by = 0.1))

Interpretación del valor de λ:

  • Si λ ≈ 1: No se necesita transformación; el modelo ya es adecuado.
  • Si λ ≈ 0: Es apropiado aplicar una transformación logarítmica a la variable dependiente.
  • Si λ está entre 0 y 1: Se debe aplicar una transformación de potencia a la variable dependiente.

Calculo de \(𝜆\).

lambda_optimo = boxcoxlm$x[which.max(boxcoxlm$y)]
cat("El valor óptimo de lambda es:", lambda_optimo, "\n")
## El valor óptimo de lambda es: 0.8686869

Para un \(λ=0.8686869\) está cercano a 1, lo que implica que los datos no requieren una transformación severa.Como no es exactamente 1, sí hay una leve asimetría o problema con la homocedasticidad, que la transformación Box-Cox puede corregir. La transformación con este \(𝜆\) suaviza los datos de la variable dependiente, ayudando a que los residuos se distribuyan más normalmente y tengan una varianza constante.

Ta transformación usando el valor de \(𝜆\).

vivienda4$preciom_transformado = (vivienda4$preciom^0.8686869 - 1) / 0.8686869
modelo_transformado = lm(preciom_transformado ~ areaconst, data = vivienda4)
summary(modelo_transformado)
## 
## Call:
## lm(formula = preciom_transformado ~ areaconst, data = vivienda4)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -12.794  -2.415   0.000   2.288  11.843 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 1.139e+02  2.194e-01   519.3   <2e-16 ***
## areaconst   2.417e-01  2.313e-03   104.5   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.471 on 1704 degrees of freedom
## Multiple R-squared:  0.865,  Adjusted R-squared:  0.865 
## F-statistic: 1.092e+04 on 1 and 1704 DF,  p-value: < 2.2e-16