Descripción del problema

Con base en los datos de ofertas de vivienda descargadas del portal Fincaraiz para apartamento de estrato 4 con área construida menor a \(200 m^2\) (vivienda4.RDS) la inmobiliaria A&C requiere el apoyo de un cientifico de datos en la construcción de un modelo que lo oriente sobre los precios de inmuebles.

Con este propósito el equipo de asesores a diseñado los siguientes pasos para obtener un modelo y así poder a futuro determinar los precios de los inmuebles a negociar

Solución

1) Instalación del set de datos

#install.packages('devtools')
#devtools::install_github('dgonxalex80/paqueteMETODOS')
library(paqueteMETODOS)
data(vivienda4)

#Se filtran solo los apartamentos
vivienda4 <- vivienda4[vivienda4$tipo == 'Apartamento',]

2) Análisis exploratorio univariado

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.

2.1) Limpieza de los datos

2.1.1) Eliminando registros duplicados
sprintf("Cantidad de registros (con duplicados): %d", dim(vivienda4)[1])
## [1] "Cantidad de registros (con duplicados): 1363"
duplicados <- duplicated(vivienda4)
vivienda4 <- vivienda4[!duplicados, ]
sprintf("Cantidad de registros (sin duplicados): %d", dim(vivienda4)[1])
## [1] "Cantidad de registros (sin duplicados): 932"

Se puede observar que el set de datos tenía 431 registros repetidos

2.1.2) Eliminando valores faltantes
sprintf("Cantidad de registros (con valores faltantes): %d", dim(vivienda4)[1])
## [1] "Cantidad de registros (con valores faltantes): 932"
vivienda4 <- na.omit(vivienda4)
sprintf("Cantidad de registros (sin valores faltantes): %d", dim(vivienda4)[1])
## [1] "Cantidad de registros (sin valores faltantes): 932"

No se encuentran valores faltantes dentro del set de datos

2.2) Análisis exploratorio de la variable precio

2.2.1) Estadísticos básicos
summary(vivienda4$preciom)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    78.0   155.0   197.5   210.0   248.0   645.0

Cómo la mediana es menor que la media, existe un sesgo positivo en los datos.

2.2.2) Distribución de los datos
hist(
  x = vivienda4$preciom,
  main = "Histograma Variable Precio"
)

library(e1071)
cof_asi <- skewness(vivienda4$preciom)
sprintf("Coeficiente asimetría: %.2f", cof_asi)
## [1] "Coeficiente asimetría: 1.33"

Cómo el coeficiente de asimetría es mayor que cero, confirma que si hay un sesgo a la derecha.

2.2.3) Valores atípicos
boxplot(
  x = vivienda4$preciom,
  main = "Diagrama Boxplot Variable Precio"
)  

2.3) Análisis exploratorio de la variable área construida

2.3.1) Estadísticos básicos
summary(vivienda4$areaconst)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   40.00   61.00   73.00   78.93   90.00  200.00

Cómo la mediana es menor que la media, existe un sesgo positivo en los datos.

2.3.2) Distribución de los datos
hist(
  x = vivienda4$areaconst,
  main = "Histograma Variable Área Construida"
)

cof_asi <- skewness(vivienda4$areaconst)
sprintf("Coeficiente asimetría: %.2f", cof_asi)
## [1] "Coeficiente asimetría: 1.82"

Cómo el coeficiente de asimetría es mayor que cero, confirma que si hay un sesgo a la derecha.

2.3.3) Valores atípicos
boxplot(
  x = vivienda4$areaconst,
  main = "Diagrama Boxplot Variable Área Construida"
)

3) Análisis exploratorio bivariado

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 (area construida) - incluir gráficos e indicadores apropiados interpretados.

3.1) Graficando la relación entre las dos variables

plot(
  x = vivienda4$areaconst,
  y = vivienda4$preciom,
  main = "Gráfico dispersión Precio - Área Construida",
  ylab = 'Precio',
  xlab = 'Área'
)

3.2) Coeficiente de correlación

cof_cor <- cor(
  x = vivienda4$areaconst,
  y = vivienda4$preciom,
  method = "pearson"
)
sprintf("Coeficiente de correlación Pearson: %0.2f", cof_cor)
## [1] "Coeficiente de correlación Pearson: 0.73"

Utilizando la gráfica y el coeficiente de correlación de Pearson como apoyo, podemos observar que efectivamente existe una relación lineal positiva entre las variables de área construida y precio. Sin embargo, es importante destacar que esta relación se considera relativamente débil, ya que el coeficiente de correlación de Pearson es igual a 0.73.

4) Creación del primer modelo

Estime el modelo de regresión lineal simple entre \(precio = f(area) + 𝞮\). Interprete los coeficientes del modelo \(𝝱_0\), \(𝝱_1\) en caso de ser correcto.

modelo1 <- lm(preciom ~ areaconst, data = vivienda4)
summary(modelo1)
## 
## Call:
## lm(formula = preciom ~ areaconst, data = vivienda4)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -218.237  -28.758   -5.133   29.776  216.955 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 46.17974    5.25478   8.788   <2e-16 ***
## areaconst    2.07536    0.06344  32.716   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 48.68 on 930 degrees of freedom
## Multiple R-squared:  0.5351, Adjusted R-squared:  0.5346 
## F-statistic:  1070 on 1 and 930 DF,  p-value: < 2.2e-16

La ecuación del primer modelo obtenido es la siguiente:

\[precio = 46.17974 + 2.07536*área + 48.68\] Podemos observar que el valor t para el coeficiente de la intersección (\(𝝱_0\)) es 8.788, lo que indica que es poco probable que este valor sea igual a cero. Esta inferencia se ve respaldada por el valor de Pr(>|t|), que es significativamente menor que 0.05. Estos resultados sugieren que \(𝝱_0\) es un componente relevante en el modelo.

De manera similar, el valor t para el coeficiente de la pendiente (\(𝝱_1\)) es 32.716, lo que sugiere que es altamente improbable que este coeficiente sea igual a cero. Además, al observar el valor de Pr(>|t|) para \(𝝱_1\), notamos que este coeficiente es aún más significativo para el modelo que \(𝝱_1\).

5) Intervalo de confianza para el coeficiente \(𝝱_1\)

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 para el modelo 1
int_conf_mol1 <- confint(modelo1)
print(int_conf_mol1)
##                 2.5 %    97.5 %
## (Intercept) 35.867132 56.492350
## areaconst    1.950862  2.199851

Basándonos en el resultado anterior, podemos afirmar con un nivel de confianza del 95% que la pendiente del modelo se encuentra dentro del intervalo definido por el límite inferior de 1.950862 y el límite superior de 2.199851. Por lo tanto, podemos concluir que existe evidencia sólida de que la pendiente es distinta de cero, lo que sugiere que el precio tiene un impacto significativo en el modelo.

6) Calcule e interprete el indicador de bonda \(R^2\)

Al analizar el resultado en el punto 4, podemos notar que el coeficiente de determinación \(R^2\) obtenido es igual a 0.5351. Esto significa que la variable independiente “área” tiene la capacidad de explicar el 53.51% del comportamiento de la variable dependiente “precio”.

7) Predicción de precio

¿Cuál sería el precio promedio estimado para un apartamento de 110 metros cuadrados? Considera entonces con este resultado que un apartamento en la misma zona con 110 metros cuadrados en un precio de 200 millones sería una atractiva esta oferta? ¿Qué consideraciones adicionales se deben tener?.

predict(
  modelo1,
  newdata = data.frame(areaconst=110),
  interval = "confidence",
  level = 0.95
)
##       fit      lwr      upr
## 1 274.469 269.4937 279.4443

El modelo 1, con un nivel de confianza del 95%, nos sugiere que en promedio, los apartamentos con una superficie de 110 metros cuadrados tienen un rango de valor entre 269 y 279 millones de pesos. Por lo tanto, un apartamento de 110 metros cuadrados a un precio de 200 millones de pesos sería considerado una oferta muy atractiva.

8) Validación de supuestos

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.

8.1) Normalidad de los errores

#Obteniendo los residuos del modelo
residuos <- residuals(modelo1)

#Gráfico Q-Q
qqnorm(residuos)
qqline(residuos)

hist(
  residuos,
  breaks = 20,
  main = "Histograma de residuos"
)

shapiro.test(residuos)
## 
##  Shapiro-Wilk normality test
## 
## data:  residuos
## W = 0.97322, p-value = 4.511e-12

Al combinar los resultados obtenidos a través de los métodos gráficos y la prueba de Shapiro-Wilk, se hace evidente que los residuos de los errores no exhiben una distribución normal.

8.2) Homoscedasticidad

plot(
  fitted(modelo1),
  residuos,
  xlab = "Valores predichos",
  ylab = "Residuos",
  main = "Gráfico de Residuos vs. Valores Predichos"
)
abline(h = 0, col = 'red')

lmtest::bptest(modelo1)
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo1
## BP = 174.88, df = 1, p-value < 2.2e-16

Como sugiere tanto la gráfica como la prueba estadística realizada (con un valor p significativamente inferior a 0), se puede concluir que el modelo no exhibe homocedasticidad.

8.3) No autocorrelación

plot(
  1:length(residuos),
  residuos,
  xlab = "Orden de Observación",
  ylab = "Residuales",
  main = "Gráfico de Residuales vs. Orden de Observación"
)

lmtest::dwtest(modelo1)
## 
##  Durbin-Watson test
## 
## data:  modelo1
## DW = 1.436, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0

Al analizar la gráfica, se observa que los residuos no están distribuidos de manera aleatoria en el gráfico, lo que sugiere la presencia de autocorrelación. Esta observación se respalda aún más por los resultados de la prueba, donde se obtiene un valor p significativamente menor que cero.

9) Función para evaluar los supuestos

Función tiene como objetivo evaluar los supuestos de un modelo de regresión lineal.

supuestos <- function(modelo){
  #Esfunción se encarga de evaluar los diferentes supuestos
  #de un modelo de regresión lineal y de cálcular el 
  #coeficiente de determinación
  
  errores <- residuals(modelo)
  
  #Coeficiente de determinación
  r_cuadrado <- summary(modelo)$r.squared
  
  #normalidad de los errores
  normalidad <- shapiro.test(errores)$p.value
  
  #homoscedasticidad
  homoscedasticidad <- lmtest::bptest(modelo)$p.value
  
  #No autocorrelación
  no_auto <- lmtest::dwtest(modelo)$p.value
  
  print(sprintf("R2: %0.2f", r_cuadrado))
  
  #Evaluando la hipótesis nula en la prueba shapiro
  if(normalidad < 0.05){
    print("Los residuales no siguen una distribución normal :(")
  }else{
    print("Los residuales siguen una distribución normal :)")
  }
  #Evaluando la hipótesis nula para verificar homoscedasticidad
  if(homoscedasticidad < 0.05){
    print("Los residuales no son homocedásticos :(")
  }else{
    print("Los residuales son homocedásticos :)")
  }
  #Evaluando la hipótesis nula para verificar la no autocorrelación
  if(no_auto < 0.05){
    print("Los residuales muestran autocorrelación :(")
  }else{
    print("Los residuales no muestran autocorrelación :)")
  }
  
}

10) Aplicación de transformación

De ser necesario realice una transformación apropiada para mejorar el ajuste y supuestos del modelo.

#Creando un segundo modelo, aplicando una transformación potencia en 
#las dos variables
modelo2 <- lm(log(preciom) ~ log(areaconst), data = vivienda4)
supuestos(modelo = modelo2)
## [1] "R2: 0.55"
## [1] "Los residuales no siguen una distribución normal :("
## [1] "Los residuales no son homocedásticos :("
## [1] "Los residuales muestran autocorrelación :("

11) Comparación modelo1 y modelo2

De ser necesario compare el ajuste y supuestos del modelo inicial y el transformado.

Resultados del modelo 1

supuestos(modelo = modelo1)
## [1] "R2: 0.54"
## [1] "Los residuales no siguen una distribución normal :("
## [1] "Los residuales no son homocedásticos :("
## [1] "Los residuales muestran autocorrelación :("

Resultados del modelo 2

supuestos(modelo = modelo2)
## [1] "R2: 0.55"
## [1] "Los residuales no siguen una distribución normal :("
## [1] "Los residuales no son homocedásticos :("
## [1] "Los residuales muestran autocorrelación :("

Al comparar ambos modelos, es evidente que ninguno de ellos cumple con los supuestos. Sin embargo, se nota una ligera mejora en el coeficiente de determinación del modelo 2 después de aplicar la transformación.

12) Estimación de varios modelos

Estime varios modelos y compare los resultados obtenidos. En el mejor de los modelos, ¿se cumplen los supuestos sobre los errores?

12.1) Creación del modelo 3

Aplicación de una transformación exponencial para linealizar el modelo

modelo3 <- lm(log(preciom) ~ areaconst, data = vivienda4)
supuestos(modelo = modelo2)
## [1] "R2: 0.55"
## [1] "Los residuales no siguen una distribución normal :("
## [1] "Los residuales no son homocedásticos :("
## [1] "Los residuales muestran autocorrelación :("

12.2) Creación del modelo 4

Aplicación de una transformación logaritmica para linealizar el modelo

modelo4 <- lm(preciom ~ log(areaconst), data = vivienda4)
supuestos(modelo4)
## [1] "R2: 0.56"
## [1] "Los residuales no siguen una distribución normal :("
## [1] "Los residuales no son homocedásticos :("
## [1] "Los residuales muestran autocorrelación :("

12.3) Creación del modelo 5

Aplicación de la transformación BOX-COX para linealizar el modelo

bc <- boxcox(preciom ~ areaconst, data = vivienda4)

lambda <- bc$x[which.max(bc$y)]
print(lambda)
## [1] 0.02020202
nuevo_y <- ((vivienda4$preciom^lambda)-1) / lambda
modelo5 <- lm(nuevo_y ~ areaconst, data = vivienda4)
supuestos(modelo = modelo5)
## [1] "R2: 0.50"
## [1] "Los residuales no siguen una distribución normal :("
## [1] "Los residuales no son homocedásticos :("
## [1] "Los residuales muestran autocorrelación :("

13) Conclusión

Tras analizar los cinco modelos generados, resulta evidente que ninguno de ellos cumple con los supuestos relacionados con los residuos, en términos de la validez de las hipótesis nulas. No obstante, el modelo 4 se destaca como el más sólido, ya que muestra una mejora ligeramente superior en su coeficiente de determinación, alcanzando un puntaje del 56%. Por lo tanto, se recomienda la utilización de este modelo para realizar estimaciones de precios basadas en el área construida de los apartamentos.