El taller se realiza Con base en los datos de ofertas de vivienda descargados en un archivo Excel a partir de los datos disponibles en el portal Fincaraiz.com.co.
A continuación una muestra del conjunto de datos:
viviendas <- read_excel("C:/MCD/SM1/Metodos/Act4/datos_vivienda.xlsx")
head(viviendas)
| area_construida | precio_millon |
|---|---|
| 86 | 250 |
| 118 | 385 |
| 130 | 395 |
| 181 | 419 |
| 86 | 240 |
| 98 | 320 |
par(mfrow=c(1,2))
hist(area_construida, xlab="Metros Cuadrados", col="#6495ED", main="Histograma [Área Construida]", freq=FALSE)
lines(density(area_construida), col = "red", lwd = 2)
boxplot(area_construida, xlab="Metros Cuadrados", col="#6495ED", main="Caja [Área Construida]")
data.frame(media, mediana, minimo, maximo, desviacion, q25, q75, q95)
| media | mediana | minimo | maximo | desviacion | q25 | q75 | q95 | |
|---|---|---|---|---|---|---|---|---|
| 25% | 115.7469 | 97 | 80 | 195 | 35.54332 | 86 | 130 | 178.25 |
Los datos nos revelan que el promedio del área construida de la
oferta de viviendas es de 115.7 m2, para áreas que oscilan entre
los 80 m2 (mínimo) y los 195 m2 (máximo). De acuerdo a lo observado en
el gráfico de caja, la mediana (97 m2) alejada de la media (115.7 m2) y
una alta desviación estándar confirman una dispersión de los datos con
una mayor concentración para viviendas con área construida inferior a
los 100 m2 lo cual se evidencia en la curva de densidad dibujada sobre
el histograma, es decir una asimetría positiva a la
derecha (o a la derecha) que indica la existencia de valores más
separados de la media a la derecha, que se confirma en el gráfico de
caja cuyo rango más amplio está precisamente por encima de la mediana
donde los datos estarán más dispersos. También podemos precisar que
la mitad de las viviendas ofertadas tienen un
área construida menor o igual a los 97 m2 y sólo un 25% superan los 130
m2.
par(mfrow=c(1,2))
hist(precio_millon, xlab="Millón COP$", col="#6495ED", main="Histograma [Precio]", freq=FALSE)
lines(density(precio_millon), col = "red", lwd = 2)
boxplot(precio_millon, xlab="Millón COP$", col="#6495ED", main="Caja [Precio]")
data.frame(media, mediana, minimo, maximo, desviacion, q25, q75, q95)
| media | mediana | minimo | maximo | desviacion | q25 | q75 | q95 | |
|---|---|---|---|---|---|---|---|---|
| 25% | 332.0769 | 305 | 240 | 480 | 82.14423 | 251.25 | 395 | 450 |
Los datos nos revelan que el promedio del precio de la oferta
de viviendas es de 332 millones, para valores que oscilan entre
los 240 millones (mínimo) y los 480 millones (máximo). De acuerdo a lo
observado en el gráfico de caja, la mediana (305 millones) alejada de la
media (332 millones) y una alta desviación estándar confirman una
dispersión de los datos aunque sin una concentración de datos tan bien
definida, lo cual se evidencia en la curva de densidad dibujada sobre el
histograma donde se observa una distribución bimodal con
una concentración de precios más o menos homogéneos por debajo y por
encima de los 340 millones, con una mayor concentración hacia viviendas
más económicas entre los 200 y los 300 millones de pesos colombianos. Lo
anterior confirma una asimetría positiva. También podemos
precisar que la mitad de las viviendas se oferta
a un precio menor o igual a los 305 millones y sólo un 25% están en un
rango de costosas superando los 395 millones de pesos
colombianos.
# Gráfico de dispersión Precio vs. Área
plot( x = area_construida, y = precio_millon
, main = "Precio (x) vs. Área Construida (y)"
, xlab = "COP ($)"
, ylab = "Metros cuadrados (m2)"
, col = "gray52"
, pch = 19
)
# Ajuste lineal
abline(lm(precio_millon ~ area_construida), col="red", lwd=3)
# Ajuste suavizado
lines(lowess(area_construida, precio_millon), col = "orange", lwd = 3)
# Leyenda
legend("topleft", legend = c("Lineal", "Suavizado"),
lwd = 3, lty = c(1, 1), col = c("red", "orange"))
coef_r = cor(area_construida, precio_millon)
print( paste('El coeficiente de correlación de Pearson entre Precio (x) vs. Área Construida (y), es: ', coef_r) )
## [1] "El coeficiente de correlación de Pearson entre Precio (x) vs. Área Construida (y), es: 0.919029470997185"
Observando la gráfica de dispersión podemos destacar una tendencia
directa o creciente en la relación del precio de la vivienda y su área
construida. Sin embargo, si observamos la línea naranja de ajuste
suavizado, esta relación directa con tendencia creciente parece
estabilizarse un poco cuando el precio de la vivienda es mayor a 130
millones de pesos colombianos. Observando el Coeficiente de
Correlación de Pearson (0.91) podemos determinar que la asociación que
mide la relación lineal entre el precio y el área construida
es una relación directa y fuerte
por ser mayor a 0.8, pero no del todo perfecta o que es igual a indicar
que no es clara su linealidad.
Recordemos que este coeficiente es un indicador que nos ayuda a medir la
fuerza de la relación lineal entre un par de variables continuas, en
este caso se puede interpretar que a mayor
precio hay mayor posibilidad a que la vivienda tenga mayor área en
metros cuadrados construidos.
modelo_lineal = lm(precio_millon ~ area_construida)
summary(modelo_lineal)
##
## Call:
## lm(formula = precio_millon ~ area_construida)
##
## 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_construida 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
De acuerdo a los indicadores de regresión lineal simple, tenemos:
La ecuación: Y = β0 + β1X + ε
donde,
X, es
la variable dependiente o de respuesta, en este caso Área
Construida
Y, es la variable independiente o predictora,
en este caso Precio
β0, es el intercepto de la recta
con el eje vertical. En este caso igual a 86,234
β1,
se conoce como pendiente y determina la inclinación de la recta. En este
caso igual a 2,124
Precio = 86.234
+ 2.124(Area) + ε
En cuanto a la interpretación de
los coeficientes, podemos mencionar que β0 no se puede
interpretar porque no es coherente
considerar alguna vivienda sin área construida o lo que es igual a
indicar con cero (0) metros cuadrados construidos. Para
el caso del coeficiente β1 podemos interpretar: que
por cada metro cuadrado adicional que tenga la
vivienda el precio de la misma se incrementa en 2,124 millones de pesos
colombianos.
# Intervalo de confianza del 95%
confint(modelo_lineal, level=0.95)
## 2.5 % 97.5 %
## (Intercept) 39.83983 132.627917
## area_construida 1.74017 2.507771
Con un nivel de confianza del 95% y un 5% de error α, podemos
determinar que el coeficiente β1 para el caso
del área construida podría tomar un valor entre los 1,74 y los 2,50
millones por cada metro cuadrado construido.
Adicionalmente, lo que se logra observar en la prueba de hipotesis t en
la tabla de resumen (summary) del modelo de regresión lineal es un
P-Value igual 3.45e-11 lo que indica un nivel de
confianza del 99.9% (***).
En ninguno de los dos casos el
coeficiente fue igual a cero (0), por lo cual existe evidencia
estadística de que el precio y el área construida están correlacionados
y dicha correlación es significativa.
r2 = summary(modelo_lineal)$r.squared
print( paste("Coeficiente de determinación (R2): ", r2) )
## [1] "Coeficiente de determinación (R2): 0.844615168561367"
El Coeficiente de Determinación, también conocido como R2,
es una medida de ajuste que indica si finalmente las estimaciones
(predicciones) que se logran con la recta de regresión reflejan la
realidad.
El R2 del modelo es del 0.8446
que evidencia un buen ajuste a los datos aunque no excelente y nos
permite determinar que el área construida de una
vivienda explica el 84.46% de la variabilidad de los precios por millón
de dichas viviendas.
# Cálculo de predicción
predict( modelo_lineal, list(area_construida=110), interval="confidence" )
## fit lwr upr
## 1 319.8706 306.3133 333.4279
| Planteamiento | Análisis: |
|---|---|
| ¿Considera entonces con este resultado que un apartamento en la misma zona con 110 metros cuadrados en un precio de 200 millones seria una buena oferta? | El precio promedio esperado de oferta para una vivienda de 110 metros cuadrados es de 319,87 millones de pesos colombianos. El intervalo de confianza para la predicción del precio nos indica que el promedio estaría entre los 306,31 y los 333,42 millones de pesos colombianos con un 95% de confianza. Por lo tanto un apartamento de 110 metros cuadrados en la misma zona a un precio de 200 millones es claramente una excelente oferta. |
| ¿Qué consideraciones adicionales se deben tener? | La predicción puede estar matizada por otras variables que entren en juego como los años de antigüedad del inmueble, el valor de la administración, estrato socio-económico, entre otras, así como la elección del modelo de predicción dependiendo de la naturaleza continua o discreta de sus variables y la correlación entre las mismas. |
Modelo lineal simple:
par(mfrow=c(2,2))
plot(modelo_lineal)
| Supuesto | Análisis: |
|---|---|
| Varianza constante | De acuerdo a lo observado en la Gráfica #1 “Residuales vs. Valores Ajustados” el supuesto de aleatoriedad de los errores no se está cumpliendo, es decir que los residuales no se comportan como una nube aleatoria por tanto la relación entre el precio y el área construida de la vivienda no es propiamente una asociación lineal perfecta, como si lo indicaba la gráfica de dispersión. |
| Normalidad | De acuerdo a lo observado en la Gráfica #2 de Normalidad la mayoría de los datos no se ajustan de forma perfecta aunque ligera a la línea de normalidad del QQ-Plot, por lo tanto no se cumple el supuesto. |
| Linealidad | De acuerdo a lo observado en la Gráfica #1 “Residuales vs. Valores Ajustados” la variable dependiente no parece estar linealmente relacionada con la independiente y lo evidenciamos porque la curva de ajuste en rojo no es recta ni horizontal, lo que señalaría que valores observados y residuos se distribuyen entre sí aleatoriamente y con algunos valores atípicos, por tanto no se cumple el supuesto. |
| Independencia | Dado que los datos no están consolidados en función del tiempo, entonces no será posible validar este supuesto, por lo cual se descarta para esta aproximación lineal y futuras transformaciones. |
Sugerencia: Realizar distintas transformaciones sobre las
variables involucradas a fin de observar si el ajuste hace cumplir los
supuestos. Posiblemente una función de transformación que incluya una
curva sea mejor para el ajuste.
Transformaciones para linealizar el modelo:
modelo_exponencial = lm(formula = log(precio_millon) ~ area_construida)
modelo_logaritmico = lm(formula = precio_millon ~ log10(area_construida))
modelo_doble_logaritmico = lm(formula = log10(precio_millon) ~ log10(area_construida))
modelo_hiperbolico = lm(formula = precio_millon ~ (1/area_construida))
modelo_inverso = lm(formula = (1/precio_millon) ~ area_construida)
Modelo <- c("Lineal", "Exponencial", "Logarítmico", "Doblemente Logarítmico"
, "Hiperbólico", "Doblemente Inverso")
R_Cuadrado <- c(summary(modelo_lineal)$r.squared, summary(modelo_exponencial)$r.squared
, summary(modelo_logaritmico)$r.squared, summary(modelo_doble_logaritmico)$r.squared
, summary(modelo_hiperbolico)$r.squared, summary(modelo_inverso)$r.squared)
data.frame(Modelo, R_Cuadrado)
| Modelo | R_Cuadrado |
|---|---|
| Lineal | 0.8446152 |
| Exponencial | 0.8172345 |
| Logarítmico | 0.8962713 |
| Doblemente Logarítmico | 0.8767264 |
| Hiperbólico | 0.0000000 |
| Doblemente Inverso | 0.7832378 |
Análisis de Residuales:
# Exponencial
grf_modelo_exponencial <- ggplot(data = viviendas, aes(precio_millon, modelo_exponencial$residuals)) +
geom_point() + geom_smooth(color = "firebrick") +
geom_hline(yintercept = 0) + theme_classic() +
labs(title = "",
x = 'Precio/Millón (COP$)',
y = 'Residuos')
# Logarítmico
grf_modelo_logaritmico <- ggplot(data = viviendas, aes(precio_millon, modelo_logaritmico$residuals)) +
geom_point() + geom_smooth(color = "firebrick") +
geom_hline(yintercept = 0) + theme_classic() +
labs(title = "",
x = 'Precio/Millón (COP$)',
y = 'Residuos')
ggarrange(grf_modelo_exponencial, grf_modelo_logaritmico, labels = c("Exponencial", "Logarítmico"))
# Doblemente Logarítmico
grf_modelo_doble_logaritmico <- ggplot(data = viviendas, aes(precio_millon, modelo_doble_logaritmico$residuals)) +
geom_point() + geom_smooth(color = "firebrick") +
geom_hline(yintercept = 0) + theme_classic() +
labs(title = "",
x = 'Precio/Millón (COP$)',
y = 'Residuos')
# Doblemente Inverso
grf_modelo_inverso <- ggplot(data = viviendas, aes(precio_millon, modelo_inverso$residuals)) +
geom_point() + geom_smooth(color = "firebrick") +
geom_hline(yintercept = 0) + theme_classic() +
labs(title = "",
x = 'Precio/Millón (COP$)',
y = 'Residuos')
ggarrange(grf_modelo_doble_logaritmico, grf_modelo_inverso, labels = c("Doblemente Lograrítmico", "Doblemente Inverso"))
Al intentar aplicar diferentes transformaciones a las variables sin
incluir al modelo variables predictoras adicionales, buscamos aumentar
la medida de ajuste y bondad R2.
Sin embargo observando
los R2 obtenidos para las diferentes
transformaciones podemos observar que no mejora el ajuste a los
datos. Además, si observamos los plot de Residuales
vs. Precio, podemos determinar que los errores
no tienden a una media cero (0) ni una varianza constante, por lo cual
se sugiere aplicar técnicas de regresión no líneal.
Cálculo de R2 y análisis de residuales de los
modelos polinomiales (cuadrático y cúbico):
modelo_cuadratico <- lm(precio_millon ~ poly(area_construida, 2))
modelo_cubico <- lm(precio_millon ~ poly(area_construida, 3))
Modelo <- c("Lineal","Polinomial Cuadrático", "Polinomial Cúbico")
R_Cuadrado <- c(summary(modelo_lineal)$r.squared, summary(modelo_cuadratico)$r.squared, summary(modelo_cubico)$r.squared)
data.frame(Modelo, R_Cuadrado)
| Modelo | R_Cuadrado |
|---|---|
| Lineal | 0.8446152 |
| Polinomial Cuadrático | 0.9378497 |
| Polinomial Cúbico | 0.9380455 |
# Doblemente Logarítmico
grf_modelo_cuadratico <- ggplot(data = viviendas, aes(precio_millon, modelo_cuadratico$residuals)) +
geom_point() + geom_smooth(color = "firebrick") +
geom_hline(yintercept = 0) + theme_classic() +
labs(title = "",
x = 'Precio/Millón (COP$)',
y = 'Residuos')
# Doblemente Inverso
grf_modelo_cubico <- ggplot(data = viviendas, aes(precio_millon, modelo_cubico$residuals)) +
geom_point() + geom_smooth(color = "firebrick") +
geom_hline(yintercept = 0) + theme_classic() +
labs(title = "",
x = 'Precio/Millón (COP$)',
y = 'Residuos')
ggarrange(grf_modelo_cuadratico, grf_modelo_cubico, labels = c("Polinomial Cuadrático", "Polinomial Cúbico"))
Gráfica comparativa de los modelos:
ggplot(data=viviendas, aes(x=area_construida, y=precio_millon))+
geom_point()+
stat_smooth(method="lm", formula= y~x, color="red", aes(colour = "Lineal"))+
stat_smooth(method="lm", formula= y~poly(x,2), color="blue", aes(colour = "Cuadrática"))+
stat_smooth(method="lm", formula= y~poly(x,3), color="green", aes(colour = "Cúbica"))
# stat_smooth(method="lm", formula= y~x, color="red")+
# stat_smooth(method="lm", formula= y~poly(x,2), color="blue")+
# stat_smooth(method="lm", formula= y~poly(x,3), color="green")+
# scale_color_manual(labels=c("red", "blue", "green"), values = c("red", "blue", "green"))
Cuando las transformaciones no mejoran mucho los parámetros y
evaluación del modelo, podemos probar modelos polinomiales. Estos son
modelos lineales que contienen la variable X en un polinomio de
potencias de X:
Y = α + β1X + β2X2 + β3X3
+ … + βnXn
Usualmente se llega hasta la potencia
cúbica, para evitar caer en overfitting, aunque en en nuestro caso la
medida de ajuste y bondad es exactamente la misma.
Con cualquiera de los dos modelos polinomiales
se mejora significativamente la aleatoriedad de los residuales y por lo
tanto puede explicar un 93.7% la variación del precio de la vivienda, en
comparación con el 84.46% logrado con el modelo lineal
simple.