銀行員 RとPythonに出会う

Rネタを中心に、いろいろと更新していきます

~不動産とファイナンス・賃貸物件入居者編(1)~「機械学習を使って東京23区のお買い得賃貸物件を探してみた」を千葉県でやってみる

今回は前々回の記事で触れた通り、以下のエントリを参考に千葉県のお買い得賃貸物件を分析して探してみます。

shokosakaさんのブログですが、大変勉強になりました。

このブログをなぞる形で進めてみます。

www.analyze-world.com

 

その前に、ブログを始めてわかったのですが、高校時代にサッカー部で共に汗を流したK君がこんな面白い記事を書いていたので合わせて紹介しておきます。

K君は僕と違い物理方面の科学者(FaceBookによるとナノサイエンス?)なわけですが、経済・ファイナンス界隈の人が一度は経験するラグランジュ未定乗数法を直感的なプロットで説明してくれています。彼はいつの間にかフランスの大学で研究をやっていてフランスからレスポンスしてくれました。

また、matplotlibでCDジャケットを作ってしまうという暴挙も見せています。

koideforest.hatenadiary.com

koideforest.hatenadiary.com

 

 

さて、本題に入ります。

 

 

賃貸物件情報の取得条件

まず初めに、例にならってsuumoから賃貸物件情報を取得してきます。

もちろん千葉県を対象にするのですが、さすがに全エリアを対象にするわけにはいきませんので、以下の市に絞ってデータを取得してきています。(東京に近いところから選択)

市川市 ・浦安市 ・柏市 ・鎌ヶ谷市 ・白井市 ・千葉市

流山市 ・習志野市 ・船橋市 ・松戸市 ・八千代市

また、ある程度前提を絞りたいので、さらに単身者向け物件に限定します。

検索条件として、間取りを「ワンルーム、1K、1DK、1LDK」でフィルターしています。その他の条件は特に付与していません。

 

 賃貸物件情報の取得

僕は前処理からRで完結したいと思ったのでrvestを使ってスクレイピングしてこようと思ったのですが、何やら途中うまくいかなくなったので結局pythonで処理しました。

今回はBeautifulSoup4を使ってスクレイピングしています。

 

 結果、欠損やら何やらざっと処理した結果、最終的に28,445件の物件情報になりました。

データ取得面での前処理はざざっと終わらせましたが、正直欠損をドロップする時点で気がかりなこともありました。

いろいろ追求したいところですが、試行ですので先に進みます。

 

基礎統計

ここからが分析のスタートです。

実務では、先のデータ取得、データのクレンジング、基礎統計で外観を把握、問題あれば再度データのクレンジング・・・と途方もないループがあって一番時間がかかるところではあります。

まず、市別にSUMMO掲載物件数を見ていきます。

f:id:d_s:20180826231338p:plain

最大は千葉市で約9400件、最低は白井市で125件です。

shokosakaさんの記事のまんまですが、言わずもがな人口の多い都市順に並んでいそうです。

では、物件数と人口でプロットして確かめます。

(人口は2015年)

f:id:d_s:20180826233324p:plain

おお、綺麗な回帰直線が引けました。

やはり都市人口と物件掲載数は強い相関があることがわかりますね。

習志野市だけ信頼区間から飛び出ていますが、物件の供給過剰なのでしょうか?

昨今、相続対策と消費税増税を謳ったアパート建築が流行ったので、築年数を分析すれば見えてくるのかもしれません。

 

さて、入居者としては一番の関心事である家賃を見ていきます。

家賃の中央値が高い順に並べます。

f:id:d_s:20180827000041p:plain

これは納得ですね。どうやら都心に近い順に並んでいそうです。

流山が3番目に来たのは 意外でしたが、つくばTX沿線の開発で新しい物件が多いのかもしれません。

以前、流山おおたかの森SCのTOHOシネマズによく映画を見に行きましたが、住環境としては文句のつけようのないような場所だと感じていました。

逆に、流山市の家賃の最低価格は相当安いので旧市街・新市街で相当な差があるのでしょう。

また、市川、千葉、松戸についてはどうやら変なデータが紛れ込んでいそうです。

単身向け物件にしては相当な値段の物件が見られますが、間取りの設定ミスか値段の設定ミスでしょう。

モデルを作成する際には注意しなければなりません。

 

次に、外れ値を除外して同様に見てみます。

f:id:d_s:20180827000107p:plain

先ほどよりだいぶ見やすくなりました。

白井市については、そもそも物件数が125件程度なのでなんとも言えませんが、流山市はレンジが広いですね。

そして今更気づきましたが、不覚にも柏市を入れるのを忘れていました。。。

(知らない方のために言いますと、柏市柏レイソルのホームタウンで千葉県内でも人気のある都市です)

 

やっとここまできましたが、だいぶ遅い時間になってしまいました。

その他、基礎分析を一気に行ってしまいます。

Bar Chart(by Frequency)

f:id:d_s:20180827001308p:plain

グラフが小さくと申し訳ありませんが、要約すると

・間取り

1K→1LDK→ワンルーム?→1DK→その他

・最寄り駅

JR総武線(圧倒的)→東京メトロ東西線→JR常磐線京成本線新京成線→JR京葉線→その他

・最寄り駅徒歩(分)

10分→5分→7分→8分→3分→その他

(その他、築年数等の分析を行いたいところですが今日はここまでということで。)

念のため変数とその欠損割合を確認して今日は終わりにしたいと思います。

f:id:d_s:20180827005950p:plain

次回はいよいよモデルを作成して割安物件を探していきます。

 

※コード追記(こちらのブログのほぼまんまです)

機械学習を使って東京23区のお買い得賃貸物件を探してみた - データで見る世界

 

library(ggplot2)
library(tidyverse)
library(caret)
library(randomForest)
library(ggrepel)
library(psych)
library(makedummies)
library(DT)


options(scipen=100)

# データセットの読み込み
df <- read.csv("C:\\Users\\daichi_saito\\Documents\\realestate\\dataset_chibapre2.csv",
               fileEncoding = "cp932", sep = ",")
colnames(df) <- c('names', 'city', 'adress', 'age', 'layout','height',
                  'floor', 'area', 'monthly_cost', 'other_cost', 'rout1',
                  'station1', 'distance1', 'rout2', 'station2', 'distance2',
                  'rout3', 'station3', 'distance3')
df <- cbind(df,makedummies(df, basal_level = FALSE, col = "layout"))
df$distance1 <- as.integer(str_replace(df$distance1,'分',''))
df <- na.omit(df)
df$city <- as.character(df$city)
df$city <- factor(df$city, levels=unique(df$city))
df$layout <- as.character(df$layout)
df$layout <- factor(df$layout, levels=unique(df$layout))

# 物件数が多い順位に並び替え
df1 <- df %>%
  select(city) %>%
  group_by(city) %>%
  tally() %>%
  arrange((n))
df1$city <- with(df1,reorder(city, n))

# 千葉県市別物件数のプロット
ggplot(df1,aes(city,n,fill = city)) +
  geom_bar(stat="identity", alpha=0.8)+
  ggtitle("千葉県市別物件数")+xlab("")+ylab("物件数")+ 
  theme(axis.text.x = element_text(angle = 180, hjust =1))+
  theme_bw(base_family = "HiraKakuProN-W3") +
  coord_flip() +
  ylim(0,25000) + scale_y_continuous(labels = scales::comma)

# 人口データを追加して物件数/人口のプロット
df1$pop <- c(62,109,164,193,174,168,483,482,623,972)
ggplot(df1,aes(pop,n)) +
  geom_point()+
  ggtitle("物件数/人口のプロット")+xlab("人口(千人)")+ylab("物件数")+ geom_smooth(method = "lm") +
  geom_text_repel(label = df1$city, family = "HiraKakuProN-W3", size = 3) +
  theme_bw(base_family = "HiraKakuProN-W3") +
  ylim(0,25000) + scale_y_continuous(labels = scales::comma) +  scale_x_continuous(labels = scales::comma)
cor(df1$n, df1$pop)

# 市別家賃BoxPlot
cost_median <- with(df, reorder(city, monthly_cost, median))
par(las=1, cex.axis=0.7, family = "HiraKakuProN-W3")
boxplot(monthly_cost ~ cost_median, data = df,
        xlab = "賃料+共益費", ylab = "",
        main = "市別家賃", varwidth = TRUE, horizontal=TRUE)

par(las=1, cex.axis=0.7, family = "HiraKakuProN-W3")
boxplot(monthly_cost ~ cost_median, data = df,
        xlab = "賃料+管理費", ylab = "",
        main = "市別家賃(〜15万円)", varwidth = TRUE, horizontal=TRUE, ylim = c(0,150000), outline=FALSE)