Primeramente, para conocer la data que se realiza un resumen de estadísticas descriptivas. De esta manera se puede observar:
summary(vivienda4)
## zona estrato preciom areaconst
## Zona Centro : 8 3: 0 Min. :207.4 Min. : 40.00
## Zona Norte : 288 4:1706 1st Qu.:230.7 1st Qu.: 60.00
## Zona Oeste : 60 5: 0 Median :238.8 Median : 75.00
## Zona Oriente: 6 6: 0 Mean :243.7 Mean : 87.63
## Zona Sur :1344 3rd Qu.:251.5 3rd Qu.: 98.00
## Max. :309.7 Max. :200.00
## tipo
## Apartamento:1363
## Casa : 343
##
##
##
##
summarytools::descr(vivienda4[,c(3,4)])
## Descriptive Statistics
## vivienda4
## N: 1706
##
## areaconst preciom
## ----------------- ----------- ---------
## Mean 87.63 243.70
## Std.Dev 36.35 19.56
## Min 40.00 207.41
## Q1 60.00 230.73
## Median 75.00 238.77
## Q3 98.00 251.51
## Max 200.00 309.70
## MAD 22.24 14.19
## IQR 38.00 20.77
## CV 0.41 0.08
## Skewness 1.53 1.26
## SE.Skewness 0.06 0.06
## Kurtosis 1.68 1.25
## N.Valid 1706.00 1706.00
## Pct.Valid 100.00 100.00
# Filtrar solo los registros que corresponden a 'Apartamento'
apartamentos <- vivienda4 %>% filter(tipo == "Apartamento")
casas <- vivienda4 %>% filter(tipo == "Casa")
# Visualizar el resumen de apartamentos
summary(apartamentos)
## zona estrato preciom areaconst
## Zona Centro : 7 3: 0 Min. :207.4 Min. : 40.00
## Zona Norte : 237 4:1363 1st Qu.:228.8 1st Qu.: 60.00
## Zona Oeste : 52 5: 0 Median :236.1 Median : 70.00
## Zona Oriente: 2 6: 0 Mean :237.7 Mean : 75.48
## Zona Sur :1065 3rd Qu.:243.6 3rd Qu.: 84.00
## Max. :305.2 Max. :200.00
## tipo
## Apartamento:1363
## Casa : 0
##
##
##
##
Después de tener solo los datos de las ofertas de apartamentos por zonas es muy similar. La zona sur es la que más oferta tiene con 1.065 viviendas (78.14%%), seguido de la zona norte 237 (17.39%), zona oeste 52 (3.8%), zona centro 8 (0.5%) y por último zona oriente 6 (0.4%).
# Histogramas de precios y área construida
hist(apartamentos$preciom, main = "Distribucion de Precios", xlab = "Precio")
hist(apartamentos$areaconst, main = "Distribucion de Area Construida", xlab = "Area Construida")
Se puede observar en el histograma de precios que existe un sesgo
positivo.
# Gráfico de correlación
ggpairs(vivienda4[,3:4], title="Viviendas estrato 4")
ggpairs(apartamentos[,3:4], title="Apartamentos estrato 4")
ggpairs(casas[,3:4], title="Casas estrato 4")
Se realizó un análisis gráfico y se calculó la correlación para el total de las viviendas, así como para apartamentos y casas, con el objetivo de identificar si existen cambios significativos o datos atípicos en función del tipo de vivienda.
boxplot(vivienda4[,3:4])
boxplot(apartamentos[,3:4])
boxplot(casas[,3:4])
Cuando se ve las gráficas de correlaciones se evidencia que en general las viviendas tiene una correlación lineal positiva fuerte.
No obstante, cuando se ve solo los aparamentos, si bien se mantiene la correlación positiva fuerte, esta disminuye un poco. Esto se debe a que existen datos atipicos en los apartamentos como se observa en los gráficos boxplot.
ggplot(apartamentos, aes(x = zona, y = preciom, fill = zona)) +
geom_boxplot() +
stat_summary(fun = mean, geom = "point", shape = 20, size = 3, color = "red", fill = "red") +
labs(title = "Distribucion de Precios por Zona con Media y Mediana", x = "Zona", y = "Precio de la Propiedad") +
theme_minimal()
Mirando la distribución de precios por zonas vemos que los datos atipicos se encuentran principalmente en la Zona Sur y Zona Norte, lo cual se puede explicar al ser las zonas donde más apartamentos ofertados.
# Modelo de regresión lineal
modelo <- lm(preciom ~ areaconst, data = apartamentos)
# Resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst, data = apartamentos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -26.5139 -5.0886 -0.0031 4.6406 24.3309
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.001e+02 6.698e-01 298.67 <2e-16 ***
## areaconst 4.984e-01 8.503e-03 58.62 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.081 on 1361 degrees of freedom
## Multiple R-squared: 0.7163, Adjusted R-squared: 0.7161
## F-statistic: 3436 on 1 and 1361 DF, p-value: < 2.2e-16
Intercepto (β0 = 200.1): El precio de un apartamento con 0 metros cuadrados sería 200.1 millones de pesos, lo cual no tiene un sentido práctico en sí, pero sirve para la construcción del modelo como punto de partida.
Pendiente (β1 = 0.4984): Indica que, en promedio, por cada metro cuadrado adicional de área construida, el precio del apartamento aumenta en 0.4984 millones de pesos. En otras palabras, por cada metro cuadrado adicional, el precio sube aproximadamente 498 mil pesos COP.
Teniendo los resultados del modelo se puede realizar las siguientes interpretaciones:
Existe una relación positiva significativa entre el área construida y el precio de los apartamentos, que se comprueba con el valor p bajo (menor a 2e-16). A medida que el área construida de un apartamento aumenta, su precio también tiende a aumentar.
Cada metro cuadrado adicional en el área construida se asocia con un aumento de aproximadamente 498 mil pesos COP en el precio del apartamento (valor estimado 0.4984).
# Obtener el intervalo de confianza del 95% para los coeficientes del modelo
confint(modelo, level = 0.95)
## 2.5 % 97.5 %
## (Intercept) 198.7494103 201.377500
## areaconst 0.4817357 0.515097
Para B1 (el coeficiente de areaconst), el intervalo de confianza es (0.4817, 0.5151). Como este intervalo no incluye el valor cero, podemos afirmar que el área construida tiene un efecto significativo sobre el precio
Ahora se realiza una comparación con la prueba t:
# Alternativamente, puedes extraer el valor t manualmente
t_value <- coef(summary(modelo))["areaconst", "t value"]
p_value <- coef(summary(modelo))["areaconst", "Pr(>|t|)"]
# Mostrar valor t y p-value
t_value
## [1] 58.61576
p_value
## [1] 0
# Definir los coeficientes del modelo
intercept <- 200.1 # Intercepto en millones de COP
slope <- 0.4984 # Coeficiente de areaconst (precio por metro cuadrado)
# Área del apartamento en metros cuadrados
area <- 110
# Calcular el precio estimado
estimated_price <- intercept + (slope * area)
# Mostrar el resultado
estimated_price
## [1] 254.924
El precio estimado que da de avuerdo al modelo es de COP 254.9 mm por lo que si hay un apartametno en la misma zona de 200 mm sí sería atractivo.
# Filtrar apartamentos con área construida de 110
apartamentos_filtrados <- apartamentos[apartamentos$areaconst == 110, ]
# Mostrar los resultados filtrados
print(apartamentos_filtrados)
## # A tibble: 16 × 5
## zona estrato preciom areaconst tipo
## <fct> <fct> <dbl> <dbl> <fct>
## 1 Zona Sur 4 253. 110 Apartamento
## 2 Zona Sur 4 262. 110 Apartamento
## 3 Zona Sur 4 265. 110 Apartamento
## 4 Zona Oeste 4 263. 110 Apartamento
## 5 Zona Sur 4 260. 110 Apartamento
## 6 Zona Sur 4 251. 110 Apartamento
## 7 Zona Sur 4 259. 110 Apartamento
## 8 Zona Sur 4 267. 110 Apartamento
## 9 Zona Sur 4 259. 110 Apartamento
## 10 Zona Sur 4 244. 110 Apartamento
## 11 Zona Sur 4 245. 110 Apartamento
## 12 Zona Sur 4 245. 110 Apartamento
## 13 Zona Sur 4 246. 110 Apartamento
## 14 Zona Sur 4 256. 110 Apartamento
## 15 Zona Sur 4 263. 110 Apartamento
## 16 Zona Sur 4 256. 110 Apartamento
summary(apartamentos_filtrados)
## zona estrato preciom areaconst tipo
## Zona Centro : 0 3: 0 Min. :244.3 Min. :110 Apartamento:16
## Zona Norte : 0 4:16 1st Qu.:249.6 1st Qu.:110 Casa : 0
## Zona Oeste : 1 5: 0 Median :257.6 Median :110
## Zona Oriente: 0 6: 0 Mean :255.9 Mean :110
## Zona Sur :15 3rd Qu.:262.5 3rd Qu.:110
## Max. :267.0 Max. :110
Despues de que se revisa los apartamentos de 110 metros cuadrados que se encuentran en la data, se puede ver que en promedio se encuentran en COP 255.9 mm por lo que la oferta de COP 200 mm sigue siendo muy atractiva. Ya una consideración adicional sería ver el estado del apartamento.
# Grafica de los residuos vs los valores ajustados (homocedasticidad)
plot(modelo$fitted.values, modelo$residuals,
main = "Residuos vs Valores Ajustados",
xlab = "Valores Ajustados",
ylab = "Residuos")
abline(h = 0, col = "red")
# Gráfico QQ-Plot para la normalidad de los residuos
qqnorm(modelo$residuals, main = "QQ-Plot de los Residuos")
qqline(modelo$residuals, col = "red")
# Histograma de los residuos
hist(modelo$residuals, main = "Histograma de los Residuos", xlab = "Residuos", breaks = 20)
# Shapiro Test para validación de normalidad
shapiro.test(modelo$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo$residuals
## W = 0.99885, p-value = 0.5419
# Test de Breusch-Pagan para validación Homoscedasticidad
lmtest::bptest(modelo)
##
## studentized Breusch-Pagan test
##
## data: modelo
## BP = 0.83288, df = 1, p-value = 0.3614
# Test de Durbin-Watson para ver No autocorrelación de errores
lmtest::dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 2.0204, p-value = 0.6435
## alternative hypothesis: true autocorrelation is greater than 0
Con base a los resultados, se puede decir que cumplen los supuestos sobre los errores en este modelo, lo que sugiere que los residuos no presentan problemas de normalidad, homoscedasticidad o autocorrelación. Asimismo, al ver el gráfico de Residuos vs Valores parece ser que la linealidad e independencia parecen cumplirse.
modelo <- lm(preciom ~ areaconst, data = apartamentos) # Lin - Lin
modelo2=lm(preciom ~ log(areaconst), data=apartamentos) # Lin - Log
modelo3=lm(log(preciom) ~ areaconst, data=apartamentos) # Log - Lin
modelo4=lm(log(preciom) ~ log(areaconst), data=apartamentos) # Log - Log
library(stargazer)
##
## Please cite as:
## Hlavac, Marek (2022). stargazer: Well-Formatted Regression and Summary Statistics Tables.
## R package version 5.2.3. https://CRAN.R-project.org/package=stargazer
stargazer(modelo, modelo2, modelo3, modelo4, type="text", df=FALSE)
##
## =======================================================================
## Dependent variable:
## ---------------------------------------------------
## preciom log(preciom)
## (1) (2) (3) (4)
## -----------------------------------------------------------------------
## areaconst 0.498*** 0.002***
## (0.009) (0.00004)
##
## log(areaconst) 42.878*** 0.174***
## (0.794) (0.003)
##
## Constant 200.063*** 53.820*** 5.318*** 4.723***
## (0.670) (3.409) (0.003) (0.014)
##
## -----------------------------------------------------------------------
## Observations 1,363 1,363 1,363 1,363
## R2 0.716 0.682 0.696 0.674
## Adjusted R2 0.716 0.682 0.695 0.674
## Residual Std. Error 7.081 7.496 0.030 0.031
## F Statistic 3,435.808*** 2,919.088*** 3,110.029*** 2,814.311***
## =======================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Se puede decir que el Modelo 1 (Modelo de regresion lineal) es el mejor basado en el \(R^2\), el \(R^2\) ajustado y el error estándar residual, ya que muestra la mejor capacidad de explicación de la variabilidad en los datos y un mejor ajuste.
Dado que el Modelo 1 es el más adecuado para orientar los precios de los inmuebles, una estrategia adicional para un análisis más profundo sería filtrar los datos según las zonas de interés para la compra. Esto permitirá evitar la inclusión de datos de otras áreas que puedan afectar negativamente las características y objetivos de búsqueda.
Por ejemplo, consideremos el caso en el que el interés de compra se centra en la zona sur:
apartamentos2 <- apartamentos %>% filter(zona == "Zona Sur")
summary(apartamentos2)
## zona estrato preciom areaconst
## Zona Centro : 0 3: 0 Min. :207.4 Min. : 40.00
## Zona Norte : 0 4:1065 1st Qu.:228.6 1st Qu.: 60.00
## Zona Oeste : 0 5: 0 Median :235.8 Median : 70.00
## Zona Oriente: 0 6: 0 Mean :237.2 Mean : 74.57
## Zona Sur :1065 3rd Qu.:243.3 3rd Qu.: 83.00
## Max. :305.2 Max. :200.00
## tipo
## Apartamento:1065
## Casa : 0
##
##
##
##
modelo_apartamentos2 <- lm(preciom ~ areaconst, data = apartamentos2) # Lin - Lin
summary(modelo_apartamentos2)
##
## Call:
## lm(formula = preciom ~ areaconst, data = apartamentos2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -26.7112 -5.0879 0.0108 4.6395 21.5644
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 199.7297 0.7840 254.74 <2e-16 ***
## areaconst 0.5023 0.0101 49.73 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.109 on 1063 degrees of freedom
## Multiple R-squared: 0.6994, Adjusted R-squared: 0.6991
## F-statistic: 2473 on 1 and 1063 DF, p-value: < 2.2e-16
# Gráfico QQ-Plot para la normalidad de los residuos
qqnorm(modelo_apartamentos2$residuals, main = "QQ-Plot de los Residuos")
qqline(modelo_apartamentos2$residuals, col = "red")
# Shapiro Test para validación de normalidad
shapiro.test(modelo_apartamentos2$residuals)
##
## Shapiro-Wilk normality test
##
## data: modelo_apartamentos2$residuals
## W = 0.99886, p-value = 0.7481
# Test de Breusch-Pagan para validación Homoscedasticidad
lmtest::bptest(modelo_apartamentos2)
##
## studentized Breusch-Pagan test
##
## data: modelo_apartamentos2
## BP = 0.27608, df = 1, p-value = 0.5993
# Test de Durbin-Watson para ver No autocorrelación de errores
lmtest::dwtest(modelo_apartamentos2)
##
## Durbin-Watson test
##
## data: modelo_apartamentos2
## DW = 2.0038, p-value = 0.5209
## alternative hypothesis: true autocorrelation is greater than 0