Usamos Data Science con el propósito pacífico de comprar una casa.

Para vender algo innecesario, primero debe comprar algo innecesario, pero no tenemos dinero.
- Tres de Prostokvashino

Introducción


Dio la casualidad de que vivo en mi departamento (o condominio local) en Montreal. Y una vez, hace aproximadamente un año, me visitó la idea de que sería bueno mudarse a su propia casa. Ya tenía algo de experiencia en la compra y venta de viviendas, y, en principio, sería posible abordar este problema simplemente, como lo hacen la mayoría de los residentes locales: contratar a un agente de bienes raíces y dejar que se ocupe de todos los problemas, pero sería aburrido y poco interesante.


Por lo tanto, decidí abordar este asunto científicamente. Hay una tarea: debes averiguar cuánto vale lo que tengo y dónde puedo pagarlo. Bueno, una pregunta pasajera: entender dónde sopla el viento. Y explorar los cálculos geo-espacial en el R .


En principio, estaba claro de inmediato que no sacaría solo una casa familiar separada (localmente) si quisiera quedarme en un área civilizada y golpear el calentamiento global con un paseo diario en bicicleta. Otra opción local común es comprar dúplex o triplex, es decir. casas donde hay dos o tres apartamentos: vives en uno,en el resto crías conejosel resto se entrega a los residentes. Luego aparece otra cantidad desconocida: ingresos por alquiler.


Por lo tanto, quería hacer un mapa de la ciudad con los precios de la vivienda en venta, los precios de alquiler y también poder rastrear cómo todo esto cambia con el tiempo.


zillow, , , , , , : https://apciq.ca/en/real-estate-market/. , , .


, , , , , , : https://github.com/Froren/realtorca


— , , - requests beatifulsoap, .


— , , , , , ; , .


, openstreet map, .



— , , sqlite , , . , , , , ..


R, tidy-verse, Simple Features for R, — - Geocomputation with R, ggplot2 ( tidyverse), tmap.


, , (join?) .



, , dplyr , :


R , :


library(tidyverse)
library(sf)

property<-read_csv("....") %>% 
 st_as_sf(coords=c("lng","lat"), crs=4326) %>% 
 st_transform(crs=32188)

:


neighbourhood<-geojson_sf("quartierreferencehabitation.geojson") %>%
 st_transform(32188) %>% 
 filter(nom_qr %in% c("Saint-Louis", "Milton-Parc")) %>% 
 summarize() %>% 
 st_buffer(dist=0)

:


neighbors <- st_join(property, neighbourhood, left=F)

openstreetmap :


osm_neighbourhood<-read_osm(st_bbox(neighbourhood%>%st_transform(4326)), ext=1.5, type="esri")

tmap :


library(tmap)
library(tmaptools)

tm_shape(osm_neighbourhood) + tm_rgb(alpha=0.7)+
  tm_shape(neighbourhood) + tm_borders(col='red',alpha=0.8)  + 
  tm_shape(neighbors) + tm_symbols(shape=3,size=0.2,alpha=0.8) +
  tm_shape(ref_home) + tm_symbols(col='red',shape=4,size=0.5,alpha=0.8)+
  tm_compass(position=c("right", "bottom"))+
  tm_scale_bar(position=c("right", "bottom"))

imagen
, :


imagen


( ):


lm(price ~ parking:area_interior)

:


## Coefficients:
##                            Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                33776.10   22175.97   1.523    0.129    
## parkingFALSE:area_interior   444.28      23.54  18.876   <2e-16 ***
## parkingTRUE:area_interior    523.01      19.65  26.614   <2e-16 ***

.. 444$ 33, +523$.


, 443k$, [433k$ — 453k$]


, , :


imagen


.. , .. . , . , , , generalized linear model inverse Gaussian distribution , - , :


imagen


: 435k$, 95% [419k$ — 450k$] — , .


, , , — .
, , — .. , , ( X X ) .


, () , ( , ).


imagen


generalized linear model inverse Gaussian distribution :


glm(price_sqft ~ parking + bedrooms,family=inverse.gaussian(link="log")

:


## (Intercept)    parkingTRUE   bedrooms2   bedrooms3   bedrooms4 
## 503.1981961   1.1215828   0.9720589   0.9662187   0.8325715

.. , 503$, 12% , — 2.8%, 3 — 3.3%, 4 17%, .
430k$ [ 413k$ — 448k$]



. .
- , - , — - , ?
, loess.
imagen


, — - .
imagen


, . , ( ) .


“ ” Generalized additive model


, . R mgcv gam:


gam(price_sqft ~ parking + bedrooms + s(start_date, k=24), family=inverse.gaussian(link="log"))

, , inverse Gaussian distribution, , , 24 . gam — , k .


( 2 ):


imagen


, : 429k [413k-447k], . . , .



, , .
imagen


, 60 . , .



, , . , 1, - :


#     
selected_mls=17758383 
#    2
max_distance=2000  
#       
plex_pe<-prop_geo_p %>% filter(type!='Apartment', type!='House')
ref<-plex_pe%>%filter(mls==selected_mls) 

#     
search_roi <- st_buffer(ref, max_distance) 
#      ,    -  
result <- st_intersection(plex_pe %>% filter(mls!=selected_mls), search_roi) %>% 
filter(area_interior<10000, area_interior>100,area_land>0,price<1e7,price>100 ) 

:


imagen


:


imagen


, , , - — , ( XX ), ..
, 523k$, [ 570k$ — 620k$]



, . , . sf :


, (), , :


aggregate(filter(kijiji_geo_p,bedrooms==2)%>%dplyr::select(price), mtl_p, median, join = st_contains)

imagen


, . . .
, :


gam(price_sqft ~ type + bedrooms + parking + s(x,y,k=100), family=inverse.gaussian(link="log"))

, 100:


pred_rent_whole <- raster(extent(mtl_land),res=100)
crs(pred_rent_whole)<-crs(mtl_land)
my_predict<-function(...) predict(...,type="response")
pred_rent_whole<- raster::interpolate(pred_rent_whole, model_rent_geo_whole, fun=my_predict, xyOnly=T,const=data.frame(bedrooms=2))

#      
pred_rent_whole <- mask(pred_rent_whole, mtl_land)

tmap:


tm_shape(osm_mtl)+tm_rgb(alpha=0.6)+
  tm_shape(mtl_arr) + tm_borders(alpha=0.8, col='black')+
  tm_shape(pred_rent_whole)+tm_raster(style="cont",alpha=0.7, title='$')+  tm_shape(subway_stop_p%>%dplyr::select(stop_name))+tm_symbols(col='blue',alpha=0.2,size=0.03)+
  tm_shape(subway_p)+tm_lines(col='blue',alpha=0.2)+
  tm_compass(position=c("right", "bottom"))+
  tm_scale_bar(position=c("left", "bottom"))+
  tm_layout(scale=1.5)

imagen
— .


, .
imagen


, .
imagen


, ( /( * ).
.


imagen


( / ).
imagen


, , ( ).


imagen



, R evaluar qué, cuándo y dónde comprar o vender. Pero la vida es una cosa más complicada, en la aplicación real no hay suficiente conocimiento del precio de venta real (en nuestra área esto está disponible solo para agentes inmobiliarios registrados). Por lo tanto, no debe esperar que los pronósticos obtenidos coincidan con la realidad en un 100%. En general, quien no se escondió no es mi culpa.


Fuente


Todos los datos y el código fuente están en el repositorio . ¡Compra nuestros elefantes!


Bono para aquellos que han leído hasta el final


Mapa interactivo con los resultados: http://www.ilmarin.info/re_mtl/


All Articles