Se cargan las librerías que se utilizarán a lo largo del trabajo.
library(tidyverse)
library(OneR)
library(broom)
library(modelr)
Se carga un dataset de propiedades.
properties <- read_rds('ar_properties.rds')
Éste cuenta con 8 variables:
Exceptuando la variable id que contiene valores únicos con el fin de identificar las propiedades, se crea un modelo de Regresión Lineal Múltiple para predecir el precio de cada propiedad a partir de las covariables restantes.
modelo <- lm(price ~ l3 + rooms + bathrooms + surface_total + surface_covered + property_type,
data=properties)
summary(modelo)
Call:
lm(formula = price ~ l3 + rooms + bathrooms + surface_total +
surface_covered + property_type, data = properties)
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 ***
l3Agronomía 623.53 8846.14 0.070 0.943807
l3Almagro -4520.04 4295.24 -1.052 0.292650
l3Balvanera -24788.27 4551.65 -5.446 5.18e-08 ***
l3Barracas -10128.24 5351.06 -1.893 0.058397 .
l3Barrio Norte 49921.81 4417.82 11.300 < 2e-16 ***
l3Belgrano 69648.12 4283.55 16.259 < 2e-16 ***
l3Boca -47540.60 7076.20 -6.718 1.86e-11 ***
l3Boedo -19034.38 5219.54 -3.647 0.000266 ***
l3Caballito 6220.15 4301.29 1.446 0.148153
l3Catalinas -76321.95 33563.74 -2.274 0.022974 *
l3Centro / Microcentro -29046.49 6781.80 -4.283 1.85e-05 ***
l3Chacarita 11903.39 5299.02 2.246 0.024687 *
l3Coghlan 40820.55 5462.90 7.472 8.02e-14 ***
l3Colegiales 34073.02 4816.54 7.074 1.52e-12 ***
l3Congreso -32314.97 5494.75 -5.881 4.10e-09 ***
l3Constitución -47292.98 6321.63 -7.481 7.50e-14 ***
l3Flores -22510.27 4536.15 -4.962 6.99e-07 ***
l3Floresta -28315.65 5069.38 -5.586 2.34e-08 ***
l3Las Cañitas 90455.90 5883.38 15.375 < 2e-16 ***
l3Liniers -20080.34 5366.27 -3.742 0.000183 ***
l3Mataderos -33863.43 5424.79 -6.242 4.35e-10 ***
l3Monserrat -32431.49 5228.46 -6.203 5.59e-10 ***
l3Monte Castro -8770.72 5949.63 -1.474 0.140445
l3Nuñez 56958.42 4559.69 12.492 < 2e-16 ***
l3Once -30757.83 5456.51 -5.637 1.74e-08 ***
l3Palermo 66169.58 4221.50 15.674 < 2e-16 ***
l3Parque Avellaneda -34398.95 7598.09 -4.527 5.99e-06 ***
l3Parque Centenario -12288.30 5016.45 -2.450 0.014305 *
l3Parque Chacabuco -22537.83 5314.36 -4.241 2.23e-05 ***
l3Parque Chas 5195.26 7542.97 0.689 0.490981
l3Parque Patricios -36808.02 5973.29 -6.162 7.24e-10 ***
l3Paternal -13314.50 5189.69 -2.566 0.010304 *
l3Pompeya -79977.17 8035.74 -9.953 < 2e-16 ***
l3Puerto Madero 259015.83 5095.12 50.836 < 2e-16 ***
l3Recoleta 64088.22 4360.34 14.698 < 2e-16 ***
l3Retiro 26067.40 5281.27 4.936 8.01e-07 ***
l3Saavedra 19492.00 4914.18 3.966 7.31e-05 ***
l3San Cristobal -23739.75 4955.13 -4.791 1.67e-06 ***
l3San Nicolás -26247.55 5168.96 -5.078 3.83e-07 ***
l3San Telmo -5653.85 4877.12 -1.159 0.246356
l3Tribunales -34608.17 8924.63 -3.878 0.000106 ***
l3Velez Sarsfield -25943.69 8303.75 -3.124 0.001783 **
l3Versalles -22232.13 6758.40 -3.290 0.001004 **
l3Villa Crespo 1595.26 4317.54 0.369 0.711770
l3Villa del Parque -3290.17 4866.59 -0.676 0.498997
l3Villa Devoto 13301.39 4807.08 2.767 0.005659 **
l3Villa General Mitre -19170.08 6802.25 -2.818 0.004831 **
l3Villa Lugano -83039.18 6533.35 -12.710 < 2e-16 ***
l3Villa Luro -7579.11 5404.78 -1.402 0.160833
l3Villa Ortuzar 18667.61 6829.18 2.734 0.006269 **
l3Villa Pueyrredón 10516.80 5349.56 1.966 0.049314 *
l3Villa Real -8823.37 8745.56 -1.009 0.313030
l3Villa Riachuelo -32775.66 17171.10 -1.909 0.056298 .
l3Villa Santa Rita -5767.71 6383.86 -0.903 0.366274
l3Villa Soldati -136489.91 18944.29 -7.205 5.90e-13 ***
l3Villa Urquiza 30648.43 4418.91 6.936 4.09e-12 ***
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 ***
---
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
Según este modelo, -109406.61 es la ordenada al origen. Esto significa que, si encontrásemos una propiedad en la que todas las variables tuviesen un valor igual a 0, el modelo predeciría que dicha propiedad tendría un precio de -109406.61. Esto claramente no tiene sentido. No solo porque no tendríamos una propiedad con precio negativo sino porque, además, difícilemtne tendríamos una propiedad cuya superficie total fuese 0.
El resto de los coeficientes indica cómo varía, según la predicción de nuestro modelo, dicho precio inicial al aumentar en una unidad cada variable en cuestión y dejando el resto de las variables con un valor constante.
En el caso de las variables l3 y property_type, nos encontramos ante variables dummies, variales categóricas que indican que la propiedad tiene cierta cualidad o no. l3 se refiere al barrio donde se ubica la propiedad y property_type, al tipo de propiedad en que consiste (PH o departamento).
Dado que una propiedad no puede encontrarse en más de un lugar ni ser de más de un tipo, solo uno de los coeficientes para la variable l3 y uno para la variable property_type tendrá influencia en la predicción que realice nuestro modelo para cada propiedad. Por ejemplo, en el caso de un departamento de Caballito, nuestro modeo utilizará el coeficiente 6220.15 para la variable l3 y el coefciente 92653.32 para property_type. El resto de los coeficientes relacionados a l3 y a property_type no se utilizarán dado que la variable reflejará un valor igual a 0 en dichos casos, dejándolos anulados.
Es pertinente resaltar que, en los casos de variables dummies, nos encontraremos con k-1 coeficientes, donde k es la cantidad de clases que puede tomar la variable considerada. Esto se debe a que, de otra forma, el modelo estaría sobreparametrizado y las variables presentarían dependencia lineal, lo que impediría que el sistma de ecuaciones generado tuviese una única solución.
En particular, se observa que los barrios de Puerto Madero, Las Cañitas, Belgrano, Palermos, Recoleta, Núñez, Barrio Norte, Coghlan, Colegiales, Villa Urquiza, Retiro, Saavedra, Villa Ortúzar, Villa Devoto, Chacarita, Pueyrredń, Caballito, Parque Chas, Villa Crespo y Agronomía influirán positivamente en el precio estimado por el modelo puesto que sus coeficientes son positivos. El resto de los barrios, en cambio, presenta un coeficiente negativo por lo que el valor estimado presentará un decremento si la propiedad se encuentra ubicada en uno de ellos.
Las variables rooms, bathrooms, surface_total y surface_covered, por otro lado, son numéricas, y pueden tomar cualquier valor. La multiplicación de sus valores por sus respectivos coeficientes también tendrá un impacto en la predicción de nuestro modelo, ya sea generando un aumento en el precio estimado, en el caso de los baños, la superficie total y la superficie cubierta, o ya sea provocando una disminución, en el caso de los dormitorios.
Resulta interesante destacar que, a excepeción de los barrios de Agronomía, Almagro, Barracas, Caballito, Monte Castro, Parque Chas, San Telmo, Villa Crespo, Villa del Parque, Villa Luro, Villa Real y Santa Rita, los valores de la variable dummy l3 presentan un p-valor menor a 0.05, lo que significa que la variable es útil para explicar y cuando en el modelo se encuentran presentes las demás variables, pero no en otro caso. Lo mismo sucede con la variable dummy property_type.
Los coeficientes calculados para Agronomía y Villa Crespo, por su parte, muestran un valor mayor a 0.7, indicando que en estos casos la variable resulta significativa incluso en ausencia de las demás variables.
Respecto de la evaluación del modelo, podemos ver que éste presenta un R² de 0.77, lo que indica que nuestro modelo es capaz de explicar el 77% de la variabilidad de la variable depediente Y a partir de las variables independientes proporcionadas.
A continuación, se proponen dos nuevos casos y se utiliza el modelo ajustado para predecir sus precios.
El primer caso consiste en un departamento de 120 metros cuadrados cubiertos, ubicado en el barrio de Abasto, con 3 dormitorios y 2 baños. El segundo se trata de un PH en Balvanera, con 80 metros cuadrados cubiertos, 20 metros cuadrados no cubiertos, 2 dormitorios y 3 baños.
Se genera un nuevo dataset con estos casos y se utiliza la función predict para predecir sus precios.
nuevos_casos <- data.frame(
l3 = c('Abasto', 'Balvanera'),
rooms = c(3, 2),
bathrooms = c(2, 3),
surface_total = c(120, 100),
surface_covered = c(120, 80),
property_type = c('Departamento', 'PH')
)
nuevos_casos %>%
mutate(predict = predict(modelo, newdata = .)) %>%
select(l3, predict, everything())
El modelo predice que la propiedad en el barrio de Abasto vale 324596.4, mientras que la del barrio de Balvanera cuesta 215267.6, por lo que resulta preferible tener la primera para vender.
Se crea un nuevo modelo sin la variable l3.
modelo_sin_l3 <- lm(price ~ rooms + bathrooms + surface_total + surface_covered + property_type,
data=properties)
summary(modelo_sin_l3)
Call:
lm(formula = price ~ rooms + bathrooms + surface_total + surface_covered +
property_type, data = properties)
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
Se observa que la mediana de los residuos de este modelo se encuentra más alejada del 0 que en el modelo anterior (-3307), lo que nos indica que su distribución presenta mayor asimetría. Lo deseable sería que este valor se encontrase próximo al 0 para poder verificar una distribución normal de los residuos, i.e. de la diferencia entre los valors Ŷ predichos y los valores de Y observados.
Por otro lado, si bien los coeficientes estimados han variado su valor, no han cambiado su signo, por lo que su incidencia en la estimación de precios se mantiene: aquellas variables que incrementaban el valor de los precios continuan haciéndolo y lo mismo ocurre con las que disminuían este valor.
El segundo modelo generado posee una menor capacidad explicativa de la variable Y. Su R² nos indica que las variables independientes solo pueden explicar el 68% de la variable dependiente. Este decremento resulta esperable en tanto este modelo utiliza menos variables.
Los modelos de Regresión Lineal aumentan su R² conforme aumentan la cantidad de variables empleadas en la predicción, sin importar si éstas están o no correlacionadas con la variable a predecir.
Sin embargo, si observamos el R² ajustado, vemos que también aquí el primer modelo supera al segundo (77% contra 68%). Esto resulta relevante puesto que el R² ajustado indica la capacidad de explicación de un modelo considerando las variables independientes que sí se encuentran relacionadas con la dependiente. Esta medida disminuye al añadir variables no relacionadas y aumneta solo si las agregadas son efecitvamente explicativas. Debido a esto, el R² ajustado posibilita la comparación de modelos con distinta cantidad de variables.
Así, el modelo que mejor explica la variable precios es el modelo que incluye la variable l3, dado que su R² ajustado es mayor que el último modelo realizado.
Con el propósito de crear una nueva variable barrios de tipo categórica que distinga entre barrios con precio alto, medio y bajo, se grafica un scatter plot de precios que nos permita visualizar si existen puntos críticos capaces de funcionar como puntos de corte entre las categorías definidas.
plot(sort(properties$price, decreasing = FALSE),
main = 'Precios ordenados en forma creciente',
ylab = 'Precios',
xlab = 'Índice',
col = 'cyan4')
Dado que no se observa la presencia de tales puntos, se opta por generar 3 bins de manera automática utilizando el método de “clusters” de la función bin del paquete OneR. Para ello, primero se agrupan los precios por barrios y se calcula su media, este será el input que tomará la función.
precios <- properties %>%
select(l3, price) %>%
group_by(l3) %>%
summarise(media_precio = mean(price)) %>%
arrange(media_precio)
precios
precios$clusters <- bin(precios$media_precio,
nbins=3,
labels=c("bajo", "medio", "alto"),
method="clusters")
precios
Dado que deseamos tener clases balanceadas, revisamos cuántos barrios han quedado agrupados en cada clase.
precios %>%
count(clusters)
Vemos que no se han obtenido clases balanceadas. La categoría bajo cuenta con muchos más barrios que las otras dos. Y la categría alto agrupa un único barrio.
Volvemos a generar los bins pero ahora utilizamos el método de content, que arma bins con igual cantidad de elementos.
precios$bins <- bin(precios$media_precio,
nbins=3,
labels=c("bajo", "medio", "alto"),
method="content")
precios
Chequeamos para confirmar:
precios %>%
count(bins)
Agregamos la nueva información al data frame de datos que ya teníamos. Para ello, utilizamos la función left_join. Además, cambiamos el nombre de la nueva variable bins por barrios.
properties_barrios <- left_join(properties, precios[,c('l3', 'bins')], by='l3')
names(properties_barrios)[names(properties_barrios) == 'bins'] <- 'barrios'
properties_barrios
Se ajusta un nuevo modelo. Esta vez, se utiliza la variable barrios creada en el apartado anterior en lugar de la variable l3.
model_con_barrios <- lm(price ~ rooms + bathrooms + surface_total + surface_covered +
property_type + barrios, data=properties_barrios)
summary(model_con_barrios)
Call:
lm(formula = price ~ rooms + bathrooms + surface_total + surface_covered +
property_type + barrios, data = properties_barrios)
Residuals:
Min 1Q Median 3Q Max
-457728 -36989 -5510 25167 701372
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -155886.83 2662.38 -58.55 <2e-16 ***
rooms -8868.58 481.81 -18.41 <2e-16 ***
bathrooms 36265.52 702.19 51.65 <2e-16 ***
surface_total 804.49 25.49 31.57 <2e-16 ***
surface_covered 1727.13 30.98 55.76 <2e-16 ***
property_typeDepartamento 113911.17 2333.81 48.81 <2e-16 ***
property_typePH 59415.69 2474.16 24.02 <2e-16 ***
barriosmedio 20501.46 1154.63 17.76 <2e-16 ***
barriosalto 76571.89 1070.82 71.51 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 73130 on 45895 degrees of freedom
Multiple R-squared: 0.73, Adjusted R-squared: 0.7299
F-statistic: 1.551e+04 on 8 and 45895 DF, p-value: < 2.2e-16
Es posible notar que la mediana de los residuos de este modelo presenta signo negativo, al igual que el modelo que incluía a la variable l3. Esto nos indica que al menos la mitad de los valores Ŷ predichos por ambos modelos son valores que se encuentran por encima de los valores Y observados. No obstante, la mediana de los residuos de este segundo modelo se encuentra más cerca del 0 que la mediana del modelo con l3, lo que podría indicar que, en rangos generales, los valores Ŷ predichos en este caso y los valores Y reales se encuentran a menor distancia.
En cuanto a los coeficientes calculados, podemo observar que, si bien sus valores han cambiado, no lo ha hecho así su signo. Lo que nos implica que aquellas variables que influían positivamente en la variable a predecir lo siguen haciendo y lo mismo ocurre con la variable rooms, cuya incidencia era negativa.
Por último, notamos que la variabilidad explicada por este modelo es del 73% (valor de R²). Sin embargo, como ya se advirtió previamente, no debemos fiarnos de esta medida para establecer una comparación con el modelo de l3, sino que debemos utilizar su valor ajustado. Dado que el R² ajustado de este modelo resulta menor que el del modelo de l3 (73% contra 77%), podemos afirmar que es este último el que mejor explica la variabilidad de los datos.
De todos modos, cabe hacer la reflexión de qué modelo resulta más útil a la hora de estimar el precio de una propiedad. Si bien el modelo de l3 explica mejor a la variable Y, la cantidad de valores posibles que puede adoptar la variable l3 y sus correspondientes coeficientes (igualmente variados) no permite establecer un patrón claro que dé cuenta de cómo influye esta variable en la predicción. El modelo ajustado con la variable barrios, en cambio, si bien posee un menor poder explicativo, sí nos da una idea de esta relación: en todos los casos en los que la propiedad se encuentre ubicada en un barrio de precio “bajo”, el valor predicho de la misma no se verá incrementado; si, en cambio, el inmueble se encuentra en un barrio de precio “medio”, su valor aumentará 20501,46, y se incrementará en 76571,89 en los casos en los que se ubique en un barrio de precio “alto”.
Dado que las variable surface_covered y surface_total están correlacionadas, se propone crear una nueva variable llamada surface_patio que refleje la diferencia entre ambas superficies. De este modo:
surface_patio = surface_total - surface_patio
Sin embargo, podría ocurrir que se encontrasen casos de inconsistencia donde la superficie total de una vivienda fuese menor a su superficie cubierta. De encontrarse tales casos, se propone eliminarlos, puesto que se trataría de registros mal ingresados.
Entonces, como primer paso, se chequea la existencia de casos de inconsistencia.
nrow(properties_barrios[properties_barrios$surface_covered > properties_barrios$surface_total,])
[1] 0
No se observan casos en los que la superficie total sea menor que la cubierta. Se procede a generar la nueva variable previamente definida.
properties_barriosYpatio <- properties_barrios %>%
mutate(surface_patio = surface_total-surface_covered)
properties_barriosYpatio
Se entrena un nuevo modelo utilizando ahora la variable barrios en lugar de l3 y la variable surface_patio en lugar de surface_total.
modelo_barriosYpatio <- lm(price ~ barrios + rooms + bathrooms + surface_covered + surface_patio+ property_type, data=properties_barriosYpatio)
summary(modelo_barriosYpatio)
Call:
lm(formula = price ~ barrios + rooms + bathrooms + surface_covered +
surface_patio + property_type, data = properties_barriosYpatio)
Residuals:
Min 1Q Median 3Q Max
-457728 -36989 -5510 25167 701372
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -155886.83 2662.38 -58.55 <2e-16 ***
barriosmedio 20501.46 1154.63 17.76 <2e-16 ***
barriosalto 76571.89 1070.82 71.51 <2e-16 ***
rooms -8868.58 481.81 -18.41 <2e-16 ***
bathrooms 36265.52 702.19 51.65 <2e-16 ***
surface_covered 2531.62 16.35 154.81 <2e-16 ***
surface_patio 804.49 25.49 31.57 <2e-16 ***
property_typeDepartamento 113911.17 2333.81 48.81 <2e-16 ***
property_typePH 59415.69 2474.16 24.02 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 73130 on 45895 degrees of freedom
Multiple R-squared: 0.73, Adjusted R-squared: 0.7299
F-statistic: 1.551e+04 on 8 and 45895 DF, p-value: < 2.2e-16
Vemos que la variable surface_patio posee el mismo coeficiente que la variable surface_total del modelo anterior. Esto se debe a que la capacidad explicativa de la variable surface_total ahora está representada por surface_patio. Se comprueba que aquellos casos en los que la superficie total y la supericie cubierta eran iguales nada aportaban al modelo, pues estos caso ahora presentan valor 0 y el coeficiente asignado se ha mantenido.
Por otro lado, la variable surface_covered presenta un coeficiente mayor: ha ganado poder explicativo en el aumento de precios como consecuencia de haber quitado del modelo la variable correlacionada surface_total.
A continuación, analizaremos los residuos del modelo generado con las variables barrios y surface_patio.
En primer lugar, generamos un data frame que contiene, además de las variables independientes y la variale dependiente, los residuos del modelo ajustado.
resid_barriosYpatio <- properties_barriosYpatio %>%
add_residuals(modelo_barriosYpatio)
resid_barriosYpatio
Calculamos la media de estos residuos.
mean(resid_barriosYpatio$resid)
[1] 5.589609e-09
Confirmamos que la media es un valor muy cercano a 0. Esto era esperable dado que justamente es uno de los supuestos que asumidos a la hora de generar el modelo y ajustar la recta por mínimos cuadrados.
A continuación, se realizan distintos gráficos de los reisudos que nos permitirán analizarlos mejor.
plot(modelo_barriosYpatio)
En el primer gráfico, podemos observar los residuos versus los valores predichos por el modelo. Esta visualización nos muestra que, conforme aumentan los valores predichos, también lo hace la varianza de sus residuos, por lo cual el supuesto de homogeneidad de la varianza no se satisface. Esto indica que los residuos presentan cierta estructura que no se explica por el modelo lineal ajustado.
El segundo gráfico muestra que los residuos estandarizados no se ajustan a la distribución normal. Sería deseable que esto ocurriese, puesto que, de ese modo, los test e intervalos de confianza construídos serían más apropiados.
Finalmente, el último gráfico, permite observar los residuos en relación a su leverage, es decir, en relación a su grado de influencia en el modelo. Dado que el leverage de cada observación puede tomar valores entre 0 y 1 y aquí todos los varlores se encuentran por debajo de 0.05, podríamos afirmar que ninguna observación aislada está forzando a la recta a desviarse del curso establecido por un conjunto de observaciones mayor.
Se implementa un modelo de elasticidad constante definido del siguiente modo:
\[ log(price) = \beta_0 + \beta_1log(rooms) + \beta_2log(bathrooms) + \beta_3log(surface\_covered) + \beta_4property\_type + \beta_5barrio + \beta_6surface\_patio \]
model_log = lm(log(price) ~ log(rooms) + log(bathrooms) + log(surface_covered) + property_type +
barrios + surface_patio, data=properties_barriosYpatio)
summary(model_log)
Call:
lm(formula = log(price) ~ log(rooms) + log(bathrooms) + log(surface_covered) +
property_type + barrios + surface_patio, data = properties_barriosYpatio)
Residuals:
Min 1Q Median 3Q Max
-1.35966 -0.15330 -0.00635 0.14266 1.39173
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 8.154e+00 1.943e-02 419.76 <2e-16 ***
log(rooms) -4.850e-02 3.948e-03 -12.28 <2e-16 ***
log(bathrooms) 1.809e-01 3.986e-03 45.39 <2e-16 ***
log(surface_covered) 8.229e-01 4.638e-03 177.41 <2e-16 ***
property_typeDepartamento 2.897e-01 7.494e-03 38.66 <2e-16 ***
property_typePH 9.848e-02 7.979e-03 12.34 <2e-16 ***
barriosmedio 1.402e-01 3.761e-03 37.27 <2e-16 ***
barriosalto 3.851e-01 3.487e-03 110.43 <2e-16 ***
surface_patio 3.478e-03 8.322e-05 41.79 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.2382 on 45895 degrees of freedom
Multiple R-squared: 0.8045, Adjusted R-squared: 0.8045
F-statistic: 2.361e+04 on 8 and 45895 DF, p-value: < 2.2e-16
En comparación con el anterior, vemos que este modelo posee mayor capacidad explicativa. No solo su R² es mayor, sino que también lo es su R² ajustado, medida que nos permite realizar esta comparación. Mientras que el modelo anterior presentaba un R² ajustado de 73%, este es capaz de explicar el 80% de la variable dependiente.
Además, la mediana de sus residuos se aproxima en gran medida al 0, lo que nos indica que los residuos presentan una distribución normal, una característica deseable desde los supuestos del modelo de regresipon lineal.
Ahora bien, en cuanto a los parámetros, cabe hacer una aclaración: éstos no deben recibir la misma interpretación que en los modelos previos.
El hecho de aplicar el logaritmo a nuestra variable independiente nos permite plasmar el efecto porcentual constante que las variables explicativas tienen sobre aquella. De este modo, la variable porperty_type, por ejemplo, incrementa el precio un 0.2897% al tomar el valor Departamento.
A su vez, el que a algunas variables numéricas, como rooms, bathrooms y surface_covered también se les aplique el logaritmo posibilita considerar su propio incremento en términos porcentuales. Así, en el caso de la variable surface_covered, por ejemplo, su coeficiente no indica cuánto aumenta el precio cuando la superficie cubierta se incrementa en una unidad y el resto de las variables se mantienen constantes, sino que estima cuánto aumenta el precio cuando la superficie cubierta se incrementa en un 1%. Dado que, como ya dijimos, el efecto de las variables también debe ser entendido en términos porcentuales, al aumentar el 1% la superficie cubierta, el valor de la propiedad se incrementará un 0.8229%. De este coeficiciente se dice que refleja la elasticidad estimada del precio en relación a la superficie cubierta.
Esa modificación en en la fórmula nos permite ajustar un modelo más adecuado para la realidad, puesto que es de esperar que el aumento en el precio de una propiedad no sea uniforme respecto de la superficie cubierta, no esperamos que por cada metro² añadido la propiedad aumente la misma cantidad de dinero. Por el contrario, parecería sensato esperar que los inumuebles muy pequeños, al aumentar su superficie cubierta, tuviesen un incremento de precio menor en relación a aquellas propiedades muy grandes. El logaritmo de la variable a explicar nos permite realizar una estimación semjante.
En este apartado se agrupa el data frame por tipo de propiedad y se genera una nueva tabla con dos columnas: en la primera se indica el tipo de propiedad y en la segunda se anida el data frame correspondiente.
propTypes <- properties_barriosYpatio %>%
group_by(property_type) %>%
nest()
propTypes
Para cada tipo de propiedad, se genera un modelo igual al ajustado previamente, con las variables barrios y surface_patio, y se lo almacena en la columna model.
patio_model <- function(df) {
lm(price ~ barrios + rooms + bathrooms + surface_covered + surface_patio, data=df)
}
propTypes <- propTypes %>%
mutate(model = map(data, patio_model))
propTypes
Con el fin de comparar los distintos modelos, se utiliza la función get_coefficients aquí definida y las funciones glance y augment, del paquete broom. La primera muestra los coeficientes estimados de cada modelo, la segunda permite visuaizar información relativa al R², R² ajustado y el desvío estándar de los residuos (sigma), y la última nos brinda información más detallada de estos últimos, lo que nos permitirá observar su distribución.
summary(propTypes$model[[1]]) # datos del modelo Casa
Call:
lm(formula = price ~ barrios + rooms + bathrooms + surface_covered +
surface_patio, data = df)
Residuals:
Min 1Q Median 3Q Max
-278103 -53057 -8025 39974 487168
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -14242.11 10435.97 -1.365 0.173
barriosmedio 31290.27 7538.44 4.151 3.55e-05 ***
barriosalto 110453.26 7676.85 14.388 < 2e-16 ***
rooms 6253.83 2593.36 2.411 0.016 *
bathrooms 30892.73 3833.97 8.058 1.90e-15 ***
surface_covered 1125.88 66.76 16.866 < 2e-16 ***
surface_patio 399.00 101.68 3.924 9.21e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 91120 on 1174 degrees of freedom
Multiple R-squared: 0.5488, Adjusted R-squared: 0.5465
F-statistic: 238 on 6 and 1174 DF, p-value: < 2.2e-16
summary(propTypes$model[[2]]) # datos del modelo Departamento
Call:
lm(formula = price ~ barrios + rooms + bathrooms + surface_covered +
surface_patio, data = df)
Residuals:
Min 1Q Median 3Q Max
-525687 -34454 -4891 23288 694078
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -48235.90 1322.53 -36.47 <2e-16 ***
barriosmedio 20486.58 1228.48 16.68 <2e-16 ***
barriosalto 73331.74 1126.39 65.10 <2e-16 ***
rooms -14318.29 514.19 -27.85 <2e-16 ***
bathrooms 31750.11 752.89 42.17 <2e-16 ***
surface_covered 2945.13 18.23 161.55 <2e-16 ***
surface_patio 975.45 31.60 30.87 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 70830 on 40348 degrees of freedom
Multiple R-squared: 0.7586, Adjusted R-squared: 0.7585
F-statistic: 2.113e+04 on 6 and 40348 DF, p-value: < 2.2e-16
summary(propTypes$model[[3]]) # datos del modelo PH
Call:
lm(formula = price ~ barrios + rooms + bathrooms + surface_covered +
surface_patio, data = df)
Residuals:
Min 1Q Median 3Q Max
-266658 -32757 -1815 29250 323310
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3924.79 3308.05 -1.186 0.236
barriosmedio 24976.69 2422.32 10.311 <2e-16 ***
barriosalto 74869.51 2406.89 31.106 <2e-16 ***
rooms 908.18 1114.47 0.815 0.415
bathrooms 25088.75 1588.80 15.791 <2e-16 ***
surface_covered 1362.05 32.93 41.359 <2e-16 ***
surface_patio 423.80 36.49 11.615 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 56060 on 4361 degrees of freedom
Multiple R-squared: 0.6581, Adjusted R-squared: 0.6576
F-statistic: 1399 on 6 and 4361 DF, p-value: < 2.2e-16
Como una primera gran diferencia entre los tres modelos generados (y también con respecto a los anteriores), vemos que la variable rooms solo tiene una influencia negativa sobre el precio en el modelo de Departamentos. En los demás casos ha pasado a ser positiva, lo que indica que el precio aumentará conforme lo haga la cantidad de habitaciones de la propiedad.
Por otro lado, si observamos los R² de cada uno de los modelos, vemos que el que mejor se ajusta también es el modelo de Departamentos, cuyas variables independientes llevan a explicar casi el 76% de la variabilidad de Y. En segudo lugar se ubica el modelo de PH con casi el 66% y último, el de Casa con aproximadamente e 55%.
Esto es consistente con los valores de desvíos estándares observados, en los que el modelo de Casa presenta el mayor desvío y el de PHs, el menor. Adicionalmente, la tabla a continuación confirma que, de los tres modelos, es este último el que presenta una distribución más cercana a la normal.
Hecho por Macarena Fernandez Urquiza
m.fernandezurquiza@gmail.com