Se cargan los paquetes
library(dplyr)
library(tidyr)
library(readr)
library(corrr)
library(GGally)
library(ggthemes)
library(broom)
library(tidyverse)
library(modelr)
theme_set(theme_solarized()) #carga un theme para todos los gráficos
Carga dedatos
df <- readRDS("D:/OneDrive/Ciencia de Datos/06 Enfoque estadistico/TP01/TP02/ar_properties.rds")
Visualización de los contenidos
glimpse(df)
## Observations: 45,904
## Variables: 8
## $ id <chr> "AfdcsqUSelai1ofCAq2B0Q==", "ESzybdH7YU2uIU1/k...
## $ l3 <chr> "Velez Sarsfield", "Nuñez", "Almagro", "Almagr...
## $ rooms <dbl> 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1...
## $ bathrooms <dbl> 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1...
## $ surface_total <dbl> 95, 44, 40, 49, 40, 40, 40, 49, 40, 40, 40, 32...
## $ surface_covered <dbl> 69, 38, 37, 44, 37, 37, 37, 44, 37, 37, 37, 30...
## $ price <dbl> 199900, 147000, 92294, 115000, 77000, 88900, 8...
## $ property_type <chr> "Casa", "Departamento", "Departamento", "Depar...
Ajustes varios al df
#cambio de nombre l3 por barrio
df = rename(df, barrio = l3)
#transformación a factores de variables tipo character
charcol = c('id', 'barrio', "property_type")
df[charcol] <- lapply(df[charcol], factor)
Visualización de la correlación
df %>%
select(-c(charcol)) %>% #elimino las columnas no numéricas
correlate(use = 'complete.obs')%>%
network_plot(min_cor = 0.4)
##
## Correlation method: 'pearson'
## Missing treated using: 'complete.obs'
En el gráfico se aprecia que precio está correlacionado en mayor medida con la superficie total y cubierta. Estas dos variables están fuertemente correlacionadas. Todas las variables están correlacionadas con el precio de manera positiva. En este punto se puede prever problemas en el modelo producto de la alta correlación entre las variables.
lm01 = lm(price ~ rooms + bathrooms + surface_total + surface_covered + property_type + barrio, df)
summary(lm01)
##
## Call:
## lm(formula = price ~ rooms + bathrooms + surface_total + surface_covered +
## property_type + barrio, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -400904 -33817 -3307 24660 560915
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -109406.61 4788.67 -22.847 < 2e-16 ***
## rooms -3961.27 444.58 -8.910 < 2e-16 ***
## bathrooms 34040.98 644.28 52.836 < 2e-16 ***
## surface_total 919.08 23.52 39.069 < 2e-16 ***
## surface_covered 1457.18 28.73 50.715 < 2e-16 ***
## property_typeDepartamento 92653.32 2191.23 42.284 < 2e-16 ***
## property_typePH 46779.37 2274.94 20.563 < 2e-16 ***
## barrioAgronomía 623.53 8846.14 0.070 0.943807
## barrioAlmagro -4520.04 4295.24 -1.052 0.292650
## barrioBalvanera -24788.27 4551.65 -5.446 5.18e-08 ***
## barrioBarracas -10128.24 5351.06 -1.893 0.058397 .
## barrioBarrio Norte 49921.81 4417.82 11.300 < 2e-16 ***
## barrioBelgrano 69648.12 4283.55 16.259 < 2e-16 ***
## barrioBoca -47540.60 7076.20 -6.718 1.86e-11 ***
## barrioBoedo -19034.38 5219.54 -3.647 0.000266 ***
## barrioCaballito 6220.15 4301.29 1.446 0.148153
## barrioCatalinas -76321.95 33563.74 -2.274 0.022974 *
## barrioCentro / Microcentro -29046.49 6781.80 -4.283 1.85e-05 ***
## barrioChacarita 11903.39 5299.02 2.246 0.024687 *
## barrioCoghlan 40820.55 5462.90 7.472 8.02e-14 ***
## barrioColegiales 34073.02 4816.54 7.074 1.52e-12 ***
## barrioCongreso -32314.97 5494.75 -5.881 4.10e-09 ***
## barrioConstitución -47292.98 6321.63 -7.481 7.50e-14 ***
## barrioFlores -22510.27 4536.15 -4.962 6.99e-07 ***
## barrioFloresta -28315.65 5069.38 -5.586 2.34e-08 ***
## barrioLas Cañitas 90455.90 5883.38 15.375 < 2e-16 ***
## barrioLiniers -20080.34 5366.27 -3.742 0.000183 ***
## barrioMataderos -33863.43 5424.79 -6.242 4.35e-10 ***
## barrioMonserrat -32431.49 5228.46 -6.203 5.59e-10 ***
## barrioMonte Castro -8770.72 5949.63 -1.474 0.140445
## barrioNuñez 56958.42 4559.69 12.492 < 2e-16 ***
## barrioOnce -30757.83 5456.51 -5.637 1.74e-08 ***
## barrioPalermo 66169.58 4221.50 15.674 < 2e-16 ***
## barrioParque Avellaneda -34398.95 7598.09 -4.527 5.99e-06 ***
## barrioParque Centenario -12288.30 5016.45 -2.450 0.014305 *
## barrioParque Chacabuco -22537.83 5314.36 -4.241 2.23e-05 ***
## barrioParque Chas 5195.26 7542.97 0.689 0.490981
## barrioParque Patricios -36808.02 5973.29 -6.162 7.24e-10 ***
## barrioPaternal -13314.50 5189.69 -2.566 0.010304 *
## barrioPompeya -79977.17 8035.74 -9.953 < 2e-16 ***
## barrioPuerto Madero 259015.83 5095.12 50.836 < 2e-16 ***
## barrioRecoleta 64088.22 4360.34 14.698 < 2e-16 ***
## barrioRetiro 26067.40 5281.27 4.936 8.01e-07 ***
## barrioSaavedra 19492.00 4914.18 3.966 7.31e-05 ***
## barrioSan Cristobal -23739.75 4955.13 -4.791 1.67e-06 ***
## barrioSan Nicolás -26247.55 5168.96 -5.078 3.83e-07 ***
## barrioSan Telmo -5653.85 4877.12 -1.159 0.246356
## barrioTribunales -34608.17 8924.63 -3.878 0.000106 ***
## barrioVelez Sarsfield -25943.69 8303.75 -3.124 0.001783 **
## barrioVersalles -22232.13 6758.40 -3.290 0.001004 **
## barrioVilla Crespo 1595.26 4317.54 0.369 0.711770
## barrioVilla del Parque -3290.17 4866.59 -0.676 0.498997
## barrioVilla Devoto 13301.39 4807.08 2.767 0.005659 **
## barrioVilla General Mitre -19170.08 6802.25 -2.818 0.004831 **
## barrioVilla Lugano -83039.18 6533.35 -12.710 < 2e-16 ***
## barrioVilla Luro -7579.11 5404.78 -1.402 0.160833
## barrioVilla Ortuzar 18667.61 6829.18 2.734 0.006269 **
## barrioVilla Pueyrredón 10516.80 5349.56 1.966 0.049314 *
## barrioVilla Real -8823.37 8745.56 -1.009 0.313030
## barrioVilla Riachuelo -32775.66 17171.10 -1.909 0.056298 .
## barrioVilla Santa Rita -5767.71 6383.86 -0.903 0.366274
## barrioVilla Soldati -136489.91 18944.29 -7.205 5.90e-13 ***
## barrioVilla Urquiza 30648.43 4418.91 6.936 4.09e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 66580 on 45841 degrees of freedom
## Multiple R-squared: 0.7764, Adjusted R-squared: 0.7761
## F-statistic: 2568 on 62 and 45841 DF, p-value: < 2.2e-16
En primer lugar se debe puntualizar que el modelo utiliza como variables categóricas basales el barrio “Abasto”" y el tipo de propiedad “Casa”.
Los p valores indican que todas los coeficientes de las variables explicativas a excepción de algunos barrios son estadísticamente diferentes de 0 (alfa 0.05). Esto es de esperar puesto que algunos barrios deberían ser similares entre sí.
El modelo de regresión lineal múltiple tiene la siguiente forma:
Precio medio estimado = -109 406 -3961cuartos + 34040baños + 919superficie total + 1457superficie cubierta +92652Departamento + 46779PH + ….*Barrio
El coeficiente de la variable baños es de 34.040, esto indica que si se mantienen las demás variables constantes (ceteris paribus), el precio medio estimado de una vivienda aumentará 34040 USD por cada baño que tenga. En general esta interpretación se puede realizar de la misma manera para las variables numéricas.
Resulta interesante que la variable superfice total y cubierta se influyen entre sí. Y la frase mantener todo lo demás constantes puede no aplicarse en este caso o estar sujetas a restricciones como que la variable cubierta no puede ser mayor a la superficie total y asumir un cambio en la cobertura del uso del suelo dentro de la vivienda.
Estas condiciones pueden hacer que estos coeficientes sean inconsistentes y no representen la explicación de los coeficientes convencional.
En el caso del coeficiente de la variable dummy “Departamento”" indica que si la vivienda es un departamento, el precio medio esperado respecto a una “Casa” aumentará 92652 USD si todas las demás variables permanecen constantes. Lo mismo se puede interpretar de las demás variables categóricas (dummies en el modelo) notando que en el caso de los barrios la variable basal es “Abasto”.
De todos los coeficientes resalta el coeficiente de “Cuartos” ya que es negativo. Como es sabido este valor debería ser positivo si se tomara como la unica variable del modelo. Sin embargo, como el modelo contempla los aportes de otras variables que están correlacionadas con la variable “Cuartos”, el coeficiente podría tomar ese valor por una inconsistencia en el modelo o que efectivamente tenga ese comportamiento no tan obvio. Por ejemplo que esté relacionado con que las nuevas viviendas tienen menos cuartos que anteriormente y por ende refleje la antiguedad del inmueble o que represente una vivienda más hacinada que otra.
El modelo resulta en un valor de R cuadrado ajustado de 0.78 que indica una relación lineal fuerte entre el precio y las variables explicativas. El valor indica que un 78% de la variabilidad observada en el precio de las propiedades es explicada por una relación lineal de las variables explicativas.
(La media de los residuos es similar a 0, sin embargo si se observa el gráfico de los residuos se puede observar que la varianza no es constante.)
1- Un departamento de 120 mts cuadrados cubiertos en abasto, con 3 dormitorios y 2 baños
2- Un PH en balvanera, con 80 mts cuadrados cubiertos, 20 mts cuadrados no cubiertos, 2 dormitorios y 3 baños.
#se genera un data frame con las caracteristicas de las viviendas
viv_prueba = data.frame(id = c(1, 2),
barrio = as.factor(c('Abasto', 'Balvanera')),
rooms = c(3,2),
bathrooms = c(2,3),
surface_total = c(120, 100),
surface_covered = c(120,80),
property_type = as.factor(c('Departamento', 'PH')))
#se predice el precio medio de ambas viviendas
predict(lm01, viv_prueba)
## 1 2
## 324596.4 215267.6
El resultado indica que es preferible vender la vivienda 1 ya que supera la vivienda 2 en más de $100 000 USD.
#a. Creación de un modelo con todas las covariables menos barrio
lm02 = lm(price ~ rooms + bathrooms + surface_total + surface_covered + property_type, df)
summary(lm02)
##
## Call:
## lm(formula = price ~ rooms + bathrooms + surface_total + surface_covered +
## property_type, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -518799 -36177 -9643 25740 724251
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -131096.86 2750.50 -47.66 <2e-16 ***
## rooms -13348.53 519.02 -25.72 <2e-16 ***
## bathrooms 42664.68 756.37 56.41 <2e-16 ***
## surface_total 877.03 27.59 31.79 <2e-16 ***
## surface_covered 1783.80 33.53 53.21 <2e-16 ***
## property_typeDepartamento 135177.47 2513.93 53.77 <2e-16 ***
## property_typePH 68598.52 2677.46 25.62 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 79210 on 45897 degrees of freedom
## Multiple R-squared: 0.6832, Adjusted R-squared: 0.6831
## F-statistic: 1.649e+04 on 6 and 45897 DF, p-value: < 2.2e-16
Al aplicar el modelo se observa que al igual que en el modelo anterior, todas los coeficientes que no son barrios son estadísticamente diferentes de 0. Los resultados se pueden interpretar de la misma manera que el modelo original que incluye los barrios. Se resalta que el coeficiente de los “Cuartos” sigue siendo negativo.
Puesto que el valor de R cuadrado ajustado es mejor en el modelo original 0,78 vs 0,68, se puede concluir que el modelo que incluye los barrios (lm01), explica de mejor manera la variabilidad datos observados.
En primer lugar se genera una visualización de los datos para conocer su distribución.
#genero una matriz con el precio promedio por metro cuadrado de cada barrio
prec_prom_barrio = df %>%
group_by(barrio)%>%
summarize(prec_prom = mean(price/surface_total))%>%
arrange(prec_prom)
ggplot(prec_prom_barrio, aes(x= factor(barrio, levels = prec_prom_barrio$barrio), y = prec_prom))+
geom_point(col = 'blue')+
labs(title =" Precio promedio por barrio", x = "Barrio", y = "Precio Promedio")+
theme(axis.text.x = element_text(angle = 90, hjust = 1, size = 8))
ggplot(prec_prom_barrio, aes(prec_prom))+
labs(title ="Histograma precios/m2 contra barrios", x = "Precio/m2", y = "Cantidad de barrios")+
geom_histogram(bins = 40)
En los graficos anteriores se puede ver como los barrios siguen una distribución agrupada en los precios por metro cuadrado entre $2000 y $2700. La distribución muestra una asimetría a la izquierda. Se aprecia un valor atípico en Puerto Madero que se aleja de todos los demás barrios.
Puesto que interesa agrupar los valores de los barrios según su precio promedio se realizará un clustering por medio de k-means para ubicar los barrios más similares al valor promedio. Se generará una categoría adicional a los barrios como “muy alta” para separar Puerto Madero.
#Agrupamiento por clústers
df_cluster = prec_prom_barrio %>%
filter(barrio != 'Puerto Madero')#elimino el barrio Puerto Madero
set.seed(100)#semilla para obtener los mismos valores del kmeans
clusters = kmeans(df_cluster$prec_prom,3) #kmeans con 3 grupos
df_cluster$cluster = clusters$cluster
prec_prom_cat = left_join(prec_prom_barrio, df_cluster, by='barrio')
prec_prom_cat[nrow(prec_prom_cat), 'cluster'] = 4 #incluyo Puerto Madero y le asigno el valor de clúster 4.
#transformo la matriz para asignarle la categoría según el clúster
prec_prom_cat = prec_prom_cat %>%
mutate(categoria = as.factor(ifelse(cluster==1, 'medio',
ifelse(cluster==2, 'bajo',
ifelse(cluster == 3, 'alto', 'muy alto')))))%>%
select(barrio, precio = prec_prom.x, categoria)
#Visualización
ggplot(prec_prom_cat, aes(x= factor(barrio, levels = prec_prom_cat$barrio), y = precio, col = categoria))+
geom_point()+
labs(title =" Precio promedio por barrio", x = "Barrio", y = "Precio Promedio")+
theme(axis.text.x = element_text(angle = 90, hjust = 1, size = 8))+
theme(legend.key = element_blank())
#genero el dataset completo con las categorias
barrio_cat = select(prec_prom_cat, barrio, categoria)
df_cat = inner_join(df, barrio_cat, by = 'barrio')
# Creación de un modelo con todas las covariables menos barrio
lm03 = lm(price ~ rooms + bathrooms + surface_total + surface_covered + property_type + categoria, df_cat)
summary(lm03)
##
## Call:
## lm(formula = price ~ rooms + bathrooms + surface_total + surface_covered +
## property_type + categoria, data = df_cat)
##
## Residuals:
## Min 1Q Median 3Q Max
## -418982 -34594 -3546 25195 566941
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -56114.31 2460.58 -22.80 <2e-16 ***
## rooms -5056.85 450.06 -11.24 <2e-16 ***
## bathrooms 35670.17 651.54 54.75 <2e-16 ***
## surface_total 942.42 23.69 39.77 <2e-16 ***
## surface_covered 1451.54 28.89 50.24 <2e-16 ***
## property_typeDepartamento 97499.06 2184.24 44.64 <2e-16 ***
## property_typePH 51283.71 2302.57 22.27 <2e-16 ***
## categoriabajo -100056.47 1646.78 -60.76 <2e-16 ***
## categoriamedio -64974.97 669.26 -97.08 <2e-16 ***
## categoriamuy alto 198875.81 3045.86 65.29 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 67960 on 45894 degrees of freedom
## Multiple R-squared: 0.7668, Adjusted R-squared: 0.7668
## F-statistic: 1.677e+04 on 9 and 45894 DF, p-value: < 2.2e-16
Los resultados de este modelo son similares a los otros dos modelos construidos anteriormente con la salvedad de que la variable basal de categoría de barrio es “alta”.
Por lo tanto, el modelo indica que si una vivienda de las mismas características es evaluada en un barrio “alto” y al mismo tiempo en el barrio “bajo”, el precio medio esperado bajará $100 056 USD. La misma interpretación se puede hacer con los demás coeficientes de las variables de “categoría”.
En este caso todos los coeficientes de las categorías relativas a los barrios son significativamente diferentes de 0. Resulta interesante que a pesar de reducir la cantidad de variables al agrupar los barrios, el valor de r cuadrado ajustado se mantiene muy similar al modelo que contempla cada barrio de manera independiente. El valor de R2adj en el modelo 01 era de 0,78 y este es de 0,77.
Puesto que no hay una reducción muy importante en la variabilidad explicada utilizaría este modelo (lm03) para estimar el valor medio del precio ya que es más sencillo y resulta más entendible.
df_cat_surf= df_cat %>%
mutate(surface_patio = surface_total-surface_covered)%>%
select(-surface_total)
lm04 = lm(price ~ rooms + bathrooms + surface_patio + surface_covered + property_type + categoria, df_cat_surf)
summary(lm04)
##
## Call:
## lm(formula = price ~ rooms + bathrooms + surface_patio + surface_covered +
## property_type + categoria, data = df_cat_surf)
##
## Residuals:
## Min 1Q Median 3Q Max
## -418982 -34594 -3546 25195 566941
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -56114.31 2460.58 -22.80 <2e-16 ***
## rooms -5056.85 450.06 -11.24 <2e-16 ***
## bathrooms 35670.17 651.54 54.75 <2e-16 ***
## surface_patio 942.42 23.69 39.77 <2e-16 ***
## surface_covered 2393.95 15.27 156.75 <2e-16 ***
## property_typeDepartamento 97499.06 2184.24 44.64 <2e-16 ***
## property_typePH 51283.71 2302.57 22.27 <2e-16 ***
## categoriabajo -100056.47 1646.78 -60.76 <2e-16 ***
## categoriamedio -64974.97 669.26 -97.08 <2e-16 ***
## categoriamuy alto 198875.81 3045.86 65.29 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 67960 on 45894 degrees of freedom
## Multiple R-squared: 0.7668, Adjusted R-squared: 0.7668
## F-statistic: 1.677e+04 on 9 and 45894 DF, p-value: < 2.2e-16
dif = tidy(lm03)[2] -tidy(lm04)[2]
dif_name = cbind(tidy(lm03)[1], dif)
dif_name
## term estimate
## 1 (Intercept) -6.184564e-10
## 2 rooms -1.318767e-10
## 3 bathrooms -1.018634e-10
## 4 surface_total 6.821210e-12
## 5 surface_covered -9.424152e+02
## 6 property_typeDepartamento 3.637979e-10
## 7 property_typePH 1.382432e-10
## 8 categoriabajo 1.455192e-11
## 9 categoriamedio -2.182787e-10
## 10 categoriamuy alto -4.947651e-10
Al realizar esta modificación el modelo permanece prácticamente igual. Como la nueva variable está compuesta por la resta de variables previamente utilizadas el valor de R2adj no varía. Es importante notar que el coeficiente de “surface_total” y “surface_patio” es el mismo y el único que se modifica es el de “surface_covered”. Esto implica que la variable “surface_covered” compensa la diferencia en áreas del área total con la del patio.
Este modelo permite explicar de mejor manera el aporte de cada tipo de superficie y no presenta los inconvenientes del primer modelo realizado.
Es de esperar que las variables “surface_total” y “surface_patio” tengan el mismo coeficiente de 942.42 puesto que una unidad de área en el patio es lo mismo que una unidad de superficie total (fijando la superficie cubierta y demás variables).
augment = augment(lm04) #matriz con los residuos
ggplot(augment, aes(.fitted, .std.resid))+
geom_point(alpha = 0.3, shape = 1, col = 'blue')+
labs(title =" Residuos vs valores predichos", x = "Valores predichos", y = "Residuos estandarizados")
ggplot(augment, aes(sample = .std.resid))+
stat_qq() + stat_qq_line()+
labs(title ="Gráfico Q-Q de los residuos", x = "Cuantiles teóricos normales", y = "Cuantiles de los Residuos")
En el gráfico se aprecia una distribución cónica de los residuos en donde se amplían conforme aumenta el precio.
Esto implica que los residuos no son homocedásticos y por ende no se cumple ese supuesto. A su vez se alejan de una distribución normal cuando se observa el Q-Q Plot.
log(price)=β0+β1log(rooms)+β2log(bathrooms)+β3log(surface_covered)+β4property_type+β5barrio+β6surface_patio
lm05 = lm(log(price) ~ log(rooms) + log(bathrooms) + surface_patio + log(surface_covered) + property_type + categoria, df_cat_surf)
summary(lm05)
##
## Call:
## lm(formula = log(price) ~ log(rooms) + log(bathrooms) + surface_patio +
## log(surface_covered) + property_type + categoria, data = df_cat_surf)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.31170 -0.14402 -0.00276 0.13620 1.12680
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 8.7829956 0.0185053 474.621 < 2e-16 ***
## log(rooms) -0.0158978 0.0037455 -4.244 2.2e-05 ***
## log(bathrooms) 0.1852826 0.0037514 49.390 < 2e-16 ***
## surface_patio 0.0041283 0.0000785 52.591 < 2e-16 ***
## log(surface_covered) 0.7802266 0.0044001 177.322 < 2e-16 ***
## property_typeDepartamento 0.2210839 0.0071151 31.073 < 2e-16 ***
## property_typePH 0.0670584 0.0075321 8.903 < 2e-16 ***
## categoriabajo -0.5112497 0.0054432 -93.924 < 2e-16 ***
## categoriamedio -0.2845277 0.0022124 -128.606 < 2e-16 ***
## categoriamuy alto 0.5105121 0.0100744 50.674 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2246 on 45894 degrees of freedom
## Multiple R-squared: 0.8263, Adjusted R-squared: 0.8263
## F-statistic: 2.426e+04 on 9 and 45894 DF, p-value: < 2.2e-16
augment_05 = augment(lm05) #matriz con los residuos
ggplot(augment_05, aes(.fitted, .std.resid))+
geom_point(alpha = 0.3, shape = 1, col = 'blue')+
labs(title =" Residuos vs valores predichos modelo var. transformadas", x = "Valores predichos", y = "Residuos estandarizados")
ggplot(augment_05, aes(sample = .std.resid))+
stat_qq() + stat_qq_line()+
labs(title ="Gráfico Q-Q de los residuos modelo var. transformadas", x = "Cuantiles teóricos normales", y = "Cuantiles de los Residuos")
En cuanto a los supuestos:
Gráficamente se observa una varianza mucho más estable que en el modelo lm04.
El QQ Plot muestra una mayor similitud con la distribución normal que el modelo lm04.
Se puede concluir que el último modelo que incluye variables transformadas (lm05), tiene mejores condiciones en cuanto a los supuestos del modelo de regresión lineal (enfocados en los residuos) que el modelo sin las variables transformadas (lm04).
Al transformar la variable dependiente de manera logarítmica se está considerando que los cambios en las variables dependientes no transformadas (ceteris paribus) influyen en el precio por medio de un porcentaje constante y no de manera lineal como en el modelo original. Por ejemplo, para las variables no transformadas como “surface_patio”, el aumento del precio medio por cada metro cuadrado adicional de patio (ceteris paribus) es del 100*0.004 = 0,4%.
En el caso de las variables dependientes transformadas como “surface_covered”, su coeficiente 0,78 indica la elasticidad de “surface_covered”" respecto al precio medio. Este coeficiente indica que por cada 1% que aumenta la superficie cubierta, hay un aumento del 0,78% en el precio medio de la vivienda.
En el modelo todos, los coeficientes son significativamente diferentes de 0.
Se nota una mejoría en el coeficiente de R2 adj. (0,83 vs 0,77), sin embargo el primero es para explicar log(precio) y el segundo el precio.
Se considera que este modelo es mejor que el anterior ya que explica un mayor porcentaje de la variabilidad de la variable independiente y a su vez se acerca más a los supuestos del modelo de regresión lineal.
df_nested= df_cat_surf %>%
nest(-property_type)
ajuste_lineal_simple <- function(df){
lm(lm(price ~ rooms + bathrooms + surface_patio + surface_covered + categoria, df_cat_surf) ,data = df)
}
models = df_nested %>%
mutate(lm_simple = map(data, ajuste_lineal_simple))%>%
mutate(tdy = map(lm_simple,tidy), gla = map(lm_simple, glance))
print(models%>%
unnest(gla, .drop=TRUE))
## # A tibble: 3 x 12
## property_type r.squared adj.r.squared sigma statistic p.value df
## <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <int>
## 1 Casa 0.581 0.579 87777. 272. 7.05e-218 7
## 2 Departamento 0.794 0.794 65408. 22233. 0. 8
## 3 PH 0.683 0.683 53946. 1568. 0. 7
## # ... with 5 more variables: logLik <dbl>, AIC <dbl>, BIC <dbl>,
## # deviance <dbl>, df.residual <int>
Se observa que los valores de R2ajustado son mejores para el modelo de departamento, seguido por el PH y por último el de Casa.
Respecto al modelo que incluye todas los tipos de propiedades, solamente el modelo de departamento supera el R2ajustado.
También se aprecia que el modelo de Departamento incluye una variable adicional que corresponde a la categoría “muy alto”.
model_tdy = models%>%
unnest(tdy, .drop=TRUE)%>%
filter(term != '(Intercept)')
model_tdy %>%
filter(term != '(Intercept)')%>%
mutate(p.adjusted = p.adjust(p.value))%>% #se aplica el p valor ajustado por la cantidad de modelos que se realizan.
mutate(significante = p.adjusted < 0.05)
## # A tibble: 19 x 8
## property_type term estimate std.error statistic p.value p.adjusted
## <fct> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Casa rooms 5721. 2496. 2.29 2.21e- 2 4.41e- 2
## 2 Casa bath~ 29120. 3699. 7.87 7.89e- 15 3.16e- 14
## 3 Casa surf~ 491. 97.8 5.02 5.86e- 7 1.76e- 6
## 4 Casa surf~ 1179. 64.4 18.3 4.41e- 66 3.53e- 65
## 5 Casa cate~ -161900. 8511. -19.0 1.53e- 70 1.38e- 69
## 6 Casa cate~ -105983. 6717. -15.8 5.25e- 51 2.63e- 50
## 7 Departamento rooms -9652. 478. -20.2 3.71e- 90 3.71e- 89
## 8 Departamento bath~ 31641. 694. 45.6 0. 0.
## 9 Departamento surf~ 1142. 29.2 39.1 0. 0.
## 10 Departamento surf~ 2768. 16.9 163. 0. 0.
## 11 Departamento cate~ -87792. 1928. -45.5 0. 0.
## 12 Departamento cate~ -61751. 677. -91.2 0. 0.
## 13 Departamento cate~ 193564. 2938. 65.9 0. 0.
## 14 PH rooms 764. 1072. 0.713 4.76e- 1 4.76e- 1
## 15 PH bath~ 23428. 1532. 15.3 1.73e- 51 1.04e- 50
## 16 PH surf~ 550. 35.4 15.6 4.01e- 53 2.81e- 52
## 17 PH surf~ 1368. 31.7 43.2 0. 0.
## 18 PH cate~ -109526. 2963. -37.0 1.73e-260 2.07e-259
## 19 PH cate~ -65585. 1972. -33.3 2.06e-216 2.27e-215
## # ... with 1 more variable: significante <lgl>
ggplot(model_tdy, aes(term, estimate, colour=property_type))+
geom_jitter(height=0, width=0.2)+
labs(title ="Variación de coeficientes", x = "Variable", y = "Coeficiente")+
theme(axis.text.x = element_text(angle = 90, hjust = 1, size = 10))+
theme(legend.key = element_blank())
En todos los casos, los coeficientes de las variables dependientes tienen un p-valor ajustado inferior a 0.05 excepto la variable rooms del tipo de propiedad PH.
Al gráficar los coeficientes se observa que hay una variación importante en cuanto a las categorías de barrio baja y media. Las casas tienen un coeficiente menor en ambos seguida por el tipo PH (especialmente en categoría de barrio baja).
El coeficiente de rooms es relativamente bajo para sus unidades y experimenta cambios de signo en los modelos.
Al ver la inestabilidad del coeficiente room y su no significancia en un modelo de tipo de propiedad PH, se puede concluir que esta variable no aporta información relevante dadas las otras variables. Esto probablemente ocurre por su alta correlación con las demás.