Untuk menjual sesuatu yang tidak perlu, Anda harus terlebih dahulu membeli sesuatu yang tidak perlu, tetapi kami tidak punya uang.
- Tiga dari Prostokvashino
pengantar
Kebetulan saya tinggal di apartemen saya (atau kondominium lokal) di Montreal. Dan sekali, sekitar setahun yang lalu, saya dikunjungi oleh pemikiran bahwa akan menyenangkan untuk pindah ke rumah Anda sendiri. Saya sudah memiliki pengalaman dalam membeli dan menjual perumahan, dan, pada prinsipnya, akan mungkin untuk mendekati masalah ini secara sederhana, seperti yang dilakukan sebagian besar penduduk lokal: menyewa seorang agen real estat dan membiarkannya menangani semua masalah, tetapi akan membosankan dan tidak menarik.
Karena itu, saya memutuskan untuk mendekati masalah ini secara ilmiah. Ada tugas: Anda perlu mencari tahu berapa banyak yang saya miliki, dan di mana saya mampu. Nah, pertanyaan yang lewat - untuk memahami di mana angin bertiup. Dan menjelajahi perhitungan geo-spasial dalam R .
Pada prinsipnya, segera jelas bahwa saya tidak akan menarik hanya rumah keluarga terpisah (lokal) jika saya ingin tinggal di daerah beradab dan terkena pemanasan global dengan naik sepeda setiap hari. Opsi lokal umum lainnya adalah membeli dupleks atau tripleks, mis. rumah di mana ada dua atau tiga apartemen: Anda tinggal di satu,sisanya Anda kembangbiakkan kelincisisanya diserahkan kepada penyewa. Kemudian kuantitas lain yang tidak dikenal muncul - pendapatan sewa.
Oleh karena itu, saya ingin membuat peta kota dengan harga perumahan untuk dijual, harga sewa, dan juga dapat melacak bagaimana semua ini berubah dari waktu ke waktu.
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"))

, :

( ):
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$]
, , :

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

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

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.

, — - .

, . , ( ) .
“ ” 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 ):

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

, 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 )
:

:

, , , - — , ( XX ), ..
, 523k$, [ 570k$ — 620k$]
, . , . sf :
, (), , :
aggregate(filter(kijiji_geo_p,bedrooms==2)%>%dplyr::select(price), mtl_p, median, join = st_contains)

, . . .
, :
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)

— .
, .

, .

, ( /( * ).
.

( / ).

, , ( ).

, R mengevaluasi apa, kapan dan di mana membeli atau menjual. Tetapi hidup adalah hal yang lebih rumit, dalam aplikasi nyata tidak ada cukup pengetahuan tentang harga jual nyata (di daerah kami ini hanya tersedia untuk agen penjual terdaftar). Jadi Anda tidak boleh berharap bahwa ramalan yang diperoleh akan bertepatan dengan kenyataan sebesar 100%. Secara umum, siapa pun yang tidak bersembunyi bukanlah kesalahan saya.
Sumber
Semua data dan kode sumber ada di repositori . Beli gajah kami!
Bonus untuk mereka yang telah membaca sampai akhir
Peta interaktif dengan hasilnya: http://www.ilmarin.info/re_mtl/