library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
v ggplot2 3.3.2 v purrr 0.3.4
v tibble 3.0.3 v dplyr 1.0.1
v tidyr 1.1.1 v stringr 1.4.0
v readr 1.3.1 v forcats 0.5.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag() masks stats::lag()
library(dplyr)
library(tidyr)
library(ggplot2)
library(purrr)
library(corrr)
library(GGally)
Registered S3 method overwritten by 'GGally':
method from
+.gg ggplot2
options(crayon.enabled = FALSE)
properties <- read.csv("ar_properties.csv")
glimpse(properties)
Rows: 388,891
Columns: 24
$ id <chr> "S0we3z3V2JpHUJreqQ2t/w==", "kMxcmAS8NvrynGBVbMOEaQ==", "Ce3ojF+ZTOkB8d+LI9dpxg==", "AUGpj3...
$ ad_type <chr> "Propiedad", "Propiedad", "Propiedad", "Propiedad", "Propiedad", "Propiedad", "Propiedad", ...
$ start_date <chr> "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-0...
$ end_date <chr> "2019-06-14", "2019-04-16", "9999-12-31", "9999-12-31", "2019-07-09", "2019-08-08", "2019-0...
$ created_on <chr> "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-04-14", "2019-0...
$ lat <dbl> -34.94331, -34.63181, NA, -34.65471, -34.65495, -32.93547, -34.65183, -34.91213, -34.60338,...
$ lon <dbl> -54.92966, -58.42060, NA, -58.79089, -58.78712, -60.68398, -58.65912, -54.84749, -58.43450,...
$ l1 <chr> "Uruguay", "Argentina", "Argentina", "Argentina", "Argentina", "Argentina", "Argentina", "U...
$ l2 <chr> "Maldonado", "Capital Federal", "Bs.As. G.B.A. Zona Norte", "Bs.As. G.B.A. Zona Oeste", "Bs...
$ l3 <chr> "Punta del Este", "Boedo", NA, "Moreno", "Moreno", "Rosario", "Ituzaingó", "José Ignacio"...
$ l4 <chr> NA, NA, NA, "Moreno", "Moreno", NA, "Ituzaingó", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
$ l5 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,...
$ l6 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,...
$ rooms <int> 2, NA, 2, 2, 2, 4, NA, 6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, 1, 1, 1, 1,...
$ bedrooms <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,...
$ bathrooms <int> 1, NA, 1, 2, 3, 1, 3, 3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, 1, 1, 1, 1, 1, 1, 1...
$ surface_total <int> 45, NA, 200, 460, 660, NA, 70, NA, 1300, 405, 352, 373, 360, 1325, 250, 80142, 101, NA, 54,...
$ surface_covered <int> 40, NA, NA, 100, 148, 89, 122, NA, NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 54, 180, 33, 33, ...
$ price <int> 13000, 0, NA, NA, NA, NA, NA, NA, 0, NA, 0, NA, NA, NA, NA, NA, 0, 0, 0, NA, 0, 0, 0, 0, 0,...
$ currency <chr> "UYU", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
$ price_period <chr> "Mensual", "Mensual", NA, "Mensual", "Mensual", "Mensual", "Mensual", "Mensual", "Mensual",...
$ title <chr> "Departamento - Roosevelt", "PH - Boedo", "Ituzaingo 1100 - $ 1 - Casa Alquiler", "Dr. Ver...
$ property_type <chr> "Departamento", "PH", "Casa", "Casa", "Casa", "Casa", "Casa", "Casa", "Lote", "Lote", "Lote...
$ operation_type <chr> "Alquiler", "Venta", "Alquiler", "Venta", "Venta", "Venta", "Venta", "Alquiler", "Venta", "...
summary(properties)
id ad_type start_date end_date created_on lat
Length:388891 Length:388891 Length:388891 Length:388891 Length:388891 Min. :-54.98
Class :character Class :character Class :character Class :character Class :character 1st Qu.:-34.67
Mode :character Mode :character Mode :character Mode :character Mode :character Median :-34.60
Mean :-34.48
3rd Qu.:-34.43
Max. : 44.67
NA's :50597
lon l1 l2 l3 l4 l5
Min. :-105.27 Length:388891 Length:388891 Length:388891 Length:388891 Length:388891
1st Qu.: -58.80 Class :character Class :character Class :character Class :character Class :character
Median : -58.48 Mode :character Mode :character Mode :character Mode :character Mode :character
Mean : -59.37
3rd Qu.: -58.40
Max. : -41.90
NA's :50597
l6 rooms bedrooms bathrooms surface_total surface_covered
Mode:logical Min. : 1.0 Min. : -2.00 Min. : 1.00 Min. : -3.0 Min. : -139
NA's:388891 1st Qu.: 2.0 1st Qu.: 1.00 1st Qu.: 1.00 1st Qu.: 50.0 1st Qu.: 43
Median : 3.0 Median : 2.00 Median : 1.00 Median : 91.0 Median : 70
Mean : 2.9 Mean : 2.16 Mean : 1.67 Mean : 458.3 Mean : 235
3rd Qu.: 4.0 3rd Qu.: 3.00 3rd Qu.: 2.00 3rd Qu.: 266.0 3rd Qu.: 142
Max. :40.0 Max. :390.00 Max. :20.00 Max. :200000.0 Max. :4000000
NA's :144668 NA's :230747 NA's :94136 NA's :74063 NA's :97854
price currency price_period title property_type operation_type
Min. :0.000e+00 Length:388891 Length:388891 Length:388891 Length:388891 Length:388891
1st Qu.:2.000e+04 Class :character Class :character Class :character Class :character Class :character
Median :9.400e+04 Mode :character Mode :character Mode :character Mode :character Mode :character
Mean :2.690e+05
3rd Qu.:2.250e+05
Max. :2.147e+09
NA's :21222
Datos <- properties %>%
filter(l1 == "Argentina" , l2 == "Capital Federal" , currency == "USD" , operation_type == "Venta" , property_type == "Departamento" | property_type == "Casa" | property_type == "PH") %>%
select(id, l3, rooms, bedrooms, bathrooms, surface_total, surface_covered, price, property_type)
glimpse(Datos)
Rows: 61,905
Columns: 9
$ id <chr> "oyj+f764ALCYodIqBvWAww==", "HdjpKrqdwYfH9YU1DKjltg==", "YwWE3rTb2+gmsBwjUHmAPQ==", "6AxnSW...
$ l3 <chr> "Barracas", "Boedo", "Palermo", "Belgrano", "Versalles", "Velez Sarsfield", "Nuñez", "Alma...
$ rooms <int> NA, 6, NA, 3, NA, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, NA, 1, NA,...
$ bedrooms <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,...
$ bathrooms <int> NA, 2, 2, 4, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, NA,...
$ surface_total <int> 300, 178, 240, 157, 140, 95, 44, 40, 49, 40, 40, 40, 49, 40, 23, 40, 40, 32, 40, 36, 90, 45...
$ surface_covered <int> 180, 240, 157, NA, 110, 69, 38, 37, 44, 37, 37, 37, 44, 37, 23, 37, 37, 30, 34, 33, 90, 35,...
$ price <int> 320000, 500000, 350000, 470000, 155000, 199900, 147000, 92294, 115000, 77000, 88900, 88798,...
$ property_type <chr> "PH", "Casa", "Casa", "Casa", "Casa", "Casa", "Departamento", "Departamento", "Departamento...
Datos %>%
map_df(function(x) length(unique(x))) %>% head
Cantidad de valores faltantes (NAs) para cada variable
Datos %>%
map_df(function(x) sum(is.na(x))) %>% head
b) Matriz de correlación para las variables numéricas
Datos %>% select(-c(id,l3,property_type)) %>%
correlate(use = "complete.obs", diagonal = 1) %>%
shave() %>%
fashion()
Correlation method: 'pearson'
Missing treated using: 'complete.obs'
Datos <- Datos %>% select(-c(bedrooms)) %>% drop_na()
glimpse(Datos)
Rows: 51,210
Columns: 8
$ id <chr> "HdjpKrqdwYfH9YU1DKjltg==", "AfdcsqUSelai1ofCAq2B0Q==", "ESzybdH7YU2uIU1/kHtRGw==", "r22Ofz...
$ l3 <chr> "Boedo", "Velez Sarsfield", "Nuñez", "Almagro", "Almagro", "Almagro", "Almagro", "Almagro"...
$ rooms <int> 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 4, 1, 2, 1, 1, 2...
$ bathrooms <int> 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1...
$ surface_total <int> 178, 95, 44, 40, 49, 40, 40, 40, 49, 40, 23, 40, 40, 32, 40, 36, 90, 45, 54, 40, 33, 40, 40...
$ surface_covered <int> 240, 69, 38, 37, 44, 37, 37, 37, 44, 37, 23, 37, 37, 30, 34, 33, 90, 35, 48, 40, 32, 34, 36...
$ price <int> 500000, 199900, 147000, 92294, 115000, 77000, 88900, 88798, 110975, 92943, 69000, 99000, 96...
$ property_type <chr> "Casa", "Casa", "Departamento", "Departamento", "Departamento", "Departamento", "Departamen...
summary(Datos$price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
6000 119000 170000 251577 270000 6000000
Histograma de la variable precio: podemos observar que la mayoría de las observaciones se encuentran entre los 100 mil y los 200 mil USD. Existen valores altos de esta variable que van hasta 6 millones de USD.
Datos %>% ggplot(aes(price)) + geom_histogram()
b) Estadísticas descriptivas para la variable precio: cuartiles, promedio, mínimo y máximo por cada tipo de propiedad. Se observa que las casas valen alrededor del doble de los departamentos y PHs y que los departamentos y PHs tienen precios relativamente parecidos en promedio.La menor mediana es la de los departamentos, la media en este caso se encuentra bastante alejada de la mediana, por lo que podemos deducir que los outliers superiores están afectando la media.
Datos %>%
group_by(property_type) %>%
summarise(quantile1 = quantile(price, probs = 0.25), median(price), quantile3 = quantile(price, probs = 0.75), mean(price), min(price), max(price))
`summarise()` ungrouping output (override with `.groups` argument)
c) Boxplot de la variable precio por tipo de propiedad: podemos observar numerosos outliers en los valores superiores del precio de las casas y departamentos, que son mayores que los de los PHs.
Datos %>% ggplot(aes(x = property_type, y = price, group = property_type, fill = property_type )) +
geom_boxplot()
d) Correlograma de las variables numéricas: se muestra la fuerza y el sentido de la correlación del conjunto de variables. Todas las correlaciones son positivas siendo la más fuerte la de surface_total contra surface_covered. En general las correlaciones son bajas, probablemente por la influencia de los outliers.
Datos %>% select(-c(id,l3,property_type)) %>%
ggcorr(palette = "RdBu", label = TRUE)
Datos %>%
group_by(surface_total) %>%
summarise(quantile1 = quantile(price, probs = 0.25), median(price), quantile3 = quantile(price, probs = 0.75), mean(price), min(price), max(price))
`summarise()` ungrouping output (override with `.groups` argument)
Como se puede observar en la salida de la estadística descriptiva de la variable precio por cada cantidad de metros cuadrados, existen valores muy bajos de superficie, por ejemplo 10 metros cuadrados. Se decide eliminar las observaciones con menos de 16 metros cuadrados porque probablemente pertenezcan a cocheras y algunos tienen precios son muy elevados, como por ejemplo 220 mil USD por una propiedad de 10 metros cuadrados.
También se elimina la observación de 126062 metros cuadrados porque es 10 veces mayor a los otros valores altos observados y el valor de esta propiedad es de la misma magnitud de las otras. Para ello se pone una cota superior de 17 mil metros cuadrados. No se eliminan los otros valores altos porque pueden provenir de terrenos muy grandes.
Estudiamos ahora la variable precio por metro cuadrado:
summary(Datos$price/Datos$surface_total)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.71 2155.17 2653.85 2802.62 3233.08 124682.93
Para descartar los valores que no suenan razonables de la variable precio por metro cuadrado, podemos poner una cota inferior de mil USD por metro cuadrado y una cota superior de 6 mil USD por metro cuadrado (que es el precio por metro cuadrado del barrio más caro de Capital Federal, que es Puerto Madero).
quantile(Datos$price/Datos$surface_total, probs=c(.0165, .982))
1.65% 98.2%
999.9778 6000.0000
Como se puede observar las cotas establecidas descartan el 1,65% de los datos por debajo y el 1,8% de los datos por arriba. De un total de 51210 observaciones, nos quedamos con 49339 observaciones.
Datos <- Datos %>%
filter(surface_total > 16 , surface_total < 17000 , price/surface_total > 1000 , price/surface_total < 6000)
glimpse(Datos)
Rows: 49,339
Columns: 8
$ id <chr> "HdjpKrqdwYfH9YU1DKjltg==", "AfdcsqUSelai1ofCAq2B0Q==", "ESzybdH7YU2uIU1/kHtRGw==", "r22Ofz...
$ l3 <chr> "Boedo", "Velez Sarsfield", "Nuñez", "Almagro", "Almagro", "Almagro", "Almagro", "Almagro"...
$ rooms <int> 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2...
$ bathrooms <int> 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1...
$ surface_total <int> 178, 95, 44, 40, 49, 40, 40, 40, 49, 40, 23, 40, 40, 32, 40, 36, 90, 45, 54, 40, 33, 40, 40...
$ surface_covered <int> 240, 69, 38, 37, 44, 37, 37, 37, 44, 37, 23, 37, 37, 30, 34, 33, 90, 35, 48, 40, 32, 34, 36...
$ price <int> 500000, 199900, 147000, 92294, 115000, 77000, 88900, 88798, 110975, 92943, 69000, 99000, 96...
$ property_type <chr> "Casa", "Casa", "Departamento", "Departamento", "Departamento", "Departamento", "Departamen...
summary(Datos$price)
Min. 1st Qu. Median Mean 3rd Qu. Max.
30000 118000 168000 230827 265000 5700000
Histograma de la variable precio: no existen cambios notables en el gráfico, sólo una leve baja en la cantidad de observaciones de los valores bajos.
Datos %>% ggplot(aes(price)) + geom_histogram()
b) Estadísticas descriptivas para la variable precio: cuartiles, promedio, mínimo y máximo por cada tipo de propiedad. En general se mantienen las relaciones observadas en el anterior análisis. Los mayores cambios se presentan en el promedio: en las casas el promedio aumenta aproximadamente en 10 mil USD, en los departamentos disminuye en 23 mil USD y en los PHs se mantiene aproximadamente igual.
Datos %>%
group_by(property_type) %>%
summarise(quantile1 = quantile(price, probs = 0.25), median(price), quantile3 = quantile(price, probs = 0.75), mean(price), min(price), max(price))
`summarise()` ungrouping output (override with `.groups` argument)
c) Boxplot de la variable precio por tipo de propiedad: no se observan cambios significativos, más que la disminución de la cantidad de valores altos en los precios de los departamentos.
Datos %>% ggplot(aes(x = property_type, y = price, group = property_type, fill = property_type )) +
geom_boxplot()
d) Correlograma de las variables numéricas: en este caso, los cambios son significativos. Aumenta la fuerza de la correlación del conjunto de variables en la mayoría de los casos. Sólo se mantiene la correlación entre rooms y bathrooms. Como eliminamos los outliers estableciendo un rango en la variable precio por metro cuadrado, se nota un aumento importante en la correlacion de precio y superfiecie total. También es importante el incremento en la correlación de surface_total con rooms y bathrooms.
Datos %>% select(-c(id,l3,property_type)) %>%
ggcorr(palette = "RdBu", label = TRUE)
ajuste1 <- lm(Datos$price~Datos$rooms)
summary(ajuste1)
Call:
lm(formula = Datos$price ~ Datos$rooms)
Residuals:
Min 1Q Median 3Q Max
-2436398 -79231 -19294 41224 4774212
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -33579.6 1738.5 -19.32 <2e-16 ***
Datos$rooms 95936.8 566.4 169.39 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 170000 on 49337 degrees of freedom
Multiple R-squared: 0.3677, Adjusted R-squared: 0.3677
F-statistic: 2.869e+04 on 1 and 49337 DF, p-value: < 2.2e-16
Modelo 2: Modelo lineal simple para explicar el precio en función de la superficie total (surface_total)
ajuste2 <- lm(Datos$price~Datos$surface_total)
summary(ajuste2)
Call:
lm(formula = Datos$price ~ Datos$surface_total)
Residuals:
Min 1Q Median 3Q Max
-1466055 -36653 -8431 25152 3302659
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 20323.796 884.675 22.97 <2e-16 ***
Datos$surface_total 2430.488 7.882 308.34 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 125000 on 49337 degrees of freedom
Multiple R-squared: 0.6584, Adjusted R-squared: 0.6584
F-statistic: 9.507e+04 on 1 and 49337 DF, p-value: < 2.2e-16
b) El coeficiente beta1 en el modelo 1 indica que por cada incremento en una unidad de la variable habitaciones (rooms), el precio sube USD 95936.8. En el modelo 2, beta1 indica que por cada incremento en una unidad de la variable superficie total (surface_total), el precio sube USD 2430.488.
En el modelo 1 la estimación de σ que resulta ser 170000, indicada por Residual standard error. Si comparamos la estimación de σ del modelo 1 con la obtenida en el modelo 2, vemos que el desvío estándar se redujo considerableme.
En los dos modelos podemos ver que la distribución de los residuos no parece ser muy simétrica. Eso significa que el modelo predice ciertos puntos que se alejan mucho de los puntos reales observados.
R^2 nos dice qué proporción de la variabilidad total en la variable Y puede ser explicada por la variable regresora, en consecuencia es una medida de la capacidad de predicción del modelo.
R^2 también puede verse como una medida de la fuerza de la asociación lineal entre X e Y. Mientras mayor sea R^2 menor es la SSRes y por lo tanto, más cercanos están los puntos a la recta.
Para los datos de la regresión del precio versus habitaciones, en la salida del modelo lineal 1 vemos que R^2 es 0.3677, por lo tanto la relación lineal es levemente fuerte. Esto significa que el 36,77 % de la variabilidad observada en los valores del precio queda explicada por la relación lineal entre el precio y las habitaciones.
En cambio en modelo lineal 2 de precio en función de la superficie total, vemos que R^2 = 0.6584. Este valor implica una relación lineal moderadamente fuerte entre el precio y la superficie total. En particular, el 65,84 % de la variabilidad observada en los valores del precio queda explicada por la relación lineal entre el precio y la superficie total. El restante 100 % − 65,84 % = 34,16 % de la variabilidad no queda explicada por esta relación.
c) Entre los dos modelos, es mejor utilizar el modelo 2 para predecir el precio ya que explica un porcentaje mayor de la variabilidad de los valores del precio. Esta regresión lineal puede ser observada en el siguiente gráfico.
ggplot(Datos, aes(x=surface_total,y=price))+
geom_point(aes(colour=property_type),alpha=0.3)+
geom_smooth(method = 'lm')