Con base en los datos de ofertas de vivienda descargadas del portal Fincaraiz (datos_vivienda) realizar los siguientes puntos:
Se realiza el cargue de la base de datos.
library(readxl)
datos_vivienda <- read_excel("datos_vivienda1.xlsx")
View(datos_vivienda)
str(datos_vivienda)
## tibble [26 × 2] (S3: tbl_df/tbl/data.frame)
## $ Area_contruida: num [1:26] 86 118 130 181 86 98 170 96 85 170 ...
## $ precio_millon : num [1:26] 250 385 395 419 240 320 480 268 240 450 ...
attach(datos_vivienda)
A continuación se realiza un análisis exploratorio de cada una de las variables.
a = table1::table1(~ Area_contruida, data = datos_vivienda)
a
| Overall (N=26) |
|
|---|---|
| Area_contruida | |
| Mean (SD) | 116 (35.5) |
| Median [Min, Max] | 97.0 [80.0, 195] |
library('ggplot2')
library('ggpubr')
a1 = ggplot(datos_vivienda, aes(x = "", y = Area_contruida)) +
stat_boxplot(geom = "errorbar", width = 0.15,
color = 1) +
geom_boxplot(fill = "#4A708B", alpha = 0.5, color = 1) +
labs(title = "Box Plot Area Construida", x = "Area Construida (m2)", y = "Frecuencia") + geom_jitter(color = "#8B0000")
a2 = ggplot(datos_vivienda,aes(x=Area_contruida))+
geom_histogram(fill = "#4A708B", alpha = 0.5, color = 1, bins = 30) +
labs(title = "Histograma Area Construida", x = "Area Construida (m2)", y = "Frecuencia")
ggarrange(a1,a2,ncol = 2, nrow = 1)
Para la variable Área Construida se observa una media de 116 m2, con una desviación estándar 35,5 m2, por su parte la mediana es de 97 m2. Como se observa en el diagrama de caja (Box Plot) el primer cuartil está 86 m2, mientras que el tercero está en 130 m2, es decir, el 75% de los apartamentos de la base de datos cuenta con un área inferior o igual a este valor, mientras que el valor máximo alcanza los 195 m2. El histograma refleja una asimetría positiva debido a la alta frecuencia de apartamentos con niveles de área construida bajos.
p = table1::table1(~ precio_millon, data = datos_vivienda)
p
| Overall (N=26) |
|
|---|---|
| precio_millon | |
| Mean (SD) | 332 (82.1) |
| Median [Min, Max] | 305 [240, 480] |
library('ggplot2')
library('ggpubr')
pr1 = ggplot(datos_vivienda, aes(x = "", y = precio_millon)) +
stat_boxplot(geom = "errorbar", width = 0.15,
color = 1) +
geom_boxplot(fill = "darkseagreen3", alpha = 0.5, color = 1) +
labs(title = "Box Plot Precio de Vivienda", x = "Precio de Vivienda (Millones)", y = "Frecuencia")+ geom_jitter(color = "#8B0000")
pr2 = ggplot(datos_vivienda,aes(x=Area_contruida))+
geom_histogram(fill = "darkseagreen3", alpha = 0.5, color = 1, bins = 30) +
labs(title = "Histograma Precio de Vivienda", x = "Precio de Vivienda (Millones)", y = "Frecuencia")
ggarrange(pr1,pr2,ncol = 2, nrow = 1)
El Precio de Vivienda (MIllones) registra un valor promedio de 332 millones con una desviación estándar de 82,1 millones, con una mediana de 305 millones. Como se observa en el diagrama de caja (Box Plot) el primer cuartil está 251,2 mill., mientras que el tercero está en 251,2 mill., es decir, el 75% de los apartamentos de la base de datos cuenta con un precio inferior o igual a este valor, mientras que el valor máximo alcanza los 480 millones. El histograma refleja un comportamiento muy distinto al de una distribución normal.
library('ggplot2')
library('ggpubr')
ggplot(data = datos_vivienda, aes(x=Area_contruida, y= precio_millon)) + geom_point(colour = "#8B0000") + scale_fill_gradient(low = "light blue", high = "light blue") + ggtitle("Gráfico de Dispersión") + labs(x = "Area Construida (m2)") + labs(y = "Precio Vivienda millones COP")
Se realiza un gráfico de dispersión para verificar la relación que existe entre las dos variables, se pueda apreciar que existe una relación lineal directa o positiva, la cual se contrasta con el coeficiente de correlación de pearson donde se obtiene un valor de 0,9190, es decir, entre mayor sea el área de la vivienda mayor será su precio.
correlacion = cor(Area_contruida, precio_millon)
correlacion
## [1] 0.9190295
modelo = lm(precio_millon ~ Area_contruida, datos_vivienda)
summary(modelo)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida, data = datos_vivienda)
##
## Residuals:
## Min 1Q Median 3Q Max
## -51.673 -25.612 -6.085 24.875 67.650
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 86.234 22.479 3.836 0.000796 ***
## Area_contruida 2.124 0.186 11.422 3.45e-11 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 33.05 on 24 degrees of freedom
## Multiple R-squared: 0.8446, Adjusted R-squared: 0.8381
## F-statistic: 130.5 on 1 and 24 DF, p-value: 3.45e-11
Se realizar la estimación del modelo para determinar el precio de la vivienda a partir del área construida bajo la siguiente ecuación Precio_est = 𝛽0_est + 𝛽1_Est AreaConstruida + e, obteniendo un valor de 𝛽0_est = 86,23 millones y el 𝛽1_Est = 2,124 millones, este valor representa la pendiente de la recta del modelo lineal, es decir, por cada incremento en el área de la vivienda el precio se incrementa en 2,124 millones de pesos.
confint(modelo, level = 0.95)
## 2.5 % 97.5 %
## (Intercept) 39.83983 132.627917
## Area_contruida 1.74017 2.507771
Con un intervalo de confianza del 95% se realiza el cálculo de los estimadores del modelo obteniendo los resultados que aparecen en la tabla anterior, que permiten evidenciar la relación positiva que existe entre las dos variables y a su vez con permite corroborar lo evidenciado en el contraste de los estimadores con el p -valor donde se determina que 𝛽0_est y 𝛽1_Est son significativos para el modelo, rechazando la hipótesis nula que establecia que estos eran iguales a cero.
library(kableExtra)
R_cuadrado = matrix(c(summary(modelo)$r.squared,summary(modelo)$adj.r.squared), ncol=1)
rownames(R_cuadrado)<- c("R Cuadrado","R Cuadrado ajustado")
R_cuadrado %>%
kbl(booktabs = T,) %>%
kable_classic_2(full_width = F)
| R Cuadrado | 0.8446152 |
| R Cuadrado ajustado | 0.8381408 |
El coeficiente de determinación (R2) muestra la bondad de ajuste del modelo, el cual permite determinar la proporción de la variabilidad en el precio de la vivienda que es explicada por el área de esta, por tanto, para este caso el 84% de los cambios en el precio de la vivienda son explicados por el área que tiene cada un de estas.
predict(modelo, list(Area_contruida = 110), interval = "confidence", level = 0.95)
## fit lwr upr
## 1 319.8706 306.3133 333.4279
El precio promedio estimado de un apartamento de 110 metros cuadrados según el modelo es de 319,87 millones de pesos, dentro de un intervalo de 306.31 y 333,43 millones. Por tanto, tener un apartamento con la igual área dentro de la misma zona es una buena oferta, cabe anotar que es importante considerar otros factores relevantes como el tiempo de construcción de la edificiación, su estado actual, las condiciones de acceso, seguridad e inmuebles vecinos.
Validación de los Supuestos del Modelo
par(mfrow=c(2,2))
plot(modelo)
Normalidad de los errores
library(nortest)
resid = residuals(modelo)
lillie.test(resid)
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: resid
## D = 0.17382, p-value = 0.04198
A través de la Prueba de Kolmogorov - Smirnov (Lilliefors), se pudo contrastar que el p-valor es inferior al nivel de significancia, por tanto, se rechaza la hipótesis nula lo cual indica que los datos no siguen una distribución normal, lo cual tambien se pudo inferir en el Gráfico Residuals Vs. Fitter.
Errores con Media Cero
t.test(resid)
##
## One Sample t-test
##
## data: resid
## t = -5.9215e-17, df = 25, p-value = 1
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -13.0787 13.0787
## sample estimates:
## mean of x
## -3.760347e-16
Debido a que el p - valor es superior al nivel de significancia (0.05), se acepta que la media de los errores es igual a cero.
Errores con varianza constante (Homocedasticidad)
library(lmtest)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
bptest(modelo)
##
## studentized Breusch-Pagan test
##
## data: modelo
## BP = 5.8737, df = 1, p-value = 0.01537
COn el test Breusch - Pagan se evidencia que no se cumple el supuesto de homocedasticidad, ya que el p - valor es inferior al nivel de significancia (0.05), se acepta la hipótesis nula de los errores se distribuyen con la misma varianza.
Si los errores no están correlacionados (Independencia)
library('carData')
library('car')
dwtest(modelo, alternative= "two.sided", data = datos_vivienda)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.8831, p-value = 0.7661
## alternative hypothesis: true autocorrelation is not 0
Según el test de Durbin Watson, a partir del p- valor el cual es superior al nivel de significancia, se acepta la hipótesis nula por tanto los residuos están autocorrelacionados.
Transformaciones
library(MASS)
bc = boxcox(modelo)
plot(bc)
lamda = bc $ x [which.max(bc $y)]
lamda
## [1] 1.474747
Los resultados obtenidos del lamda indican que esta es muy superior a cero, asi que no se puede optar por una transformación logarítmica sino que se realizará una regresión polinómica.
modelo_pol2 =lm(precio_millon ~ poly(Area_contruida, 2), data = datos_vivienda)
summary(modelo_pol2)
##
## Call:
## lm(formula = precio_millon ~ poly(Area_contruida, 2), data = datos_vivienda)
##
## Residuals:
## Min 1Q Median 3Q Max
## -34.927 -14.471 -3.777 16.504 35.073
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 332.077 4.187 79.309 < 2e-16 ***
## poly(Area_contruida, 2)1 377.465 21.350 17.680 6.98e-15 ***
## poly(Area_contruida, 2)2 -125.411 21.350 -5.874 5.49e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 21.35 on 23 degrees of freedom
## Multiple R-squared: 0.9378, Adjusted R-squared: 0.9324
## F-statistic: 173.5 on 2 and 23 DF, p-value: 1.332e-14
Se realiza la transformación del modelo a través de una Regresión Polinomial, logrando mejorar su bondad de ajuste al alcanzar un coeficiente de determinación de 93,78%, a su vez constrastando los estimadores por el p - valor se observa que estos son significativos.
Validación de los Supuestos del Modelo
par(mfrow=c(2,2))
plot(modelo_pol2)
Normalidad de los errores
library(nortest)
resid = residuals(modelo_pol2)
lillie.test(resid)
##
## Lilliefors (Kolmogorov-Smirnov) normality test
##
## data: resid
## D = 0.12336, p-value = 0.3913
A través de la Prueba de Kolmogorov - Smirnov (Lilliefors), se pudo contrastar que el p-valor es superior al nivel de significancia, por tanto, se acepta la hipótesis nula lo cual indica que los datos siguen una distribución normal, lo cual tambien se pudo evidenciar en el Gráfico Residuals Vs. Fitter.
Errores con Media Cero
t.test(resid)
##
## One Sample t-test
##
## data: resid
## t = 9.8946e-17, df = 25, p-value = 1
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## -8.271458 8.271458
## sample estimates:
## mean of x
## 3.973851e-16
Debido a que el p - valor es superior al nivel de significancia (0.05), se acepta que la media de los errores es igual a cero.
Errores con varianza constante (Homocedasticidad)
library(lmtest)
library(zoo)
bptest(modelo_pol2)
##
## studentized Breusch-Pagan test
##
## data: modelo_pol2
## BP = 1.5272, df = 2, p-value = 0.466
COn el test Breusch - Pagan se evidencia se cumple el supuesto de homocedasticidad, ya que el p - valor es superior al nivel de significancia (0.05), se rechaza la hipótesis nula, por tanto, los errores no se distribuyen con la misma varianza.
Si los errores no están correlacionados (Independencia)
dwtest(modelo_pol2, alternative = "two.sided", data = datos_vivienda)
##
## Durbin-Watson test
##
## data: modelo_pol2
## DW = 1.8769, p-value = 0.7814
## alternative hypothesis: true autocorrelation is not 0
Según el test de Durbin Watson, a partir del p- valor el cual es superior al nivel de significancia, se acepta la hipótesis nula por tanto los residuos están autocorrelacionados.
Modelo de Regresión Lineal
ggplot() + geom_point(data = datos_vivienda, aes(x = Area_contruida, y = precio_millon)) + geom_line(aes( x = Area_contruida, y = predict(modelo, datos_vivienda)), color = "red")
Modelo de Regresión Polinominal
ggplot() + geom_point(data = datos_vivienda, aes(x = Area_contruida, y = precio_millon)) + geom_line(aes( x = Area_contruida, y = predict(modelo_pol2, datos_vivienda)), color = "red")
Tal como se puede apreciar en las gráficas anteriores, el modelo polinomial logra un mayor bondad de ajuste con el conjunto de datos analizados, lo cual se tradujo en un mayor R2, logrando además un mejor resultado en la validación de los supuestos del modelo.