SUUMOにある家賃がバカ高い賃貸がなんでバカ高いのか調べる。後編

こちらの記事をご覧いただきありがとうございます。
この記事は後編です。前編がまだの方はぜひ前編からご覧ください。
（後編だけ読んでいただいてもOKです。話が分からないことはないと思います。）

https://qiita.com/tomyu/items/cd90f3bb8dafc7c23835

SUUMOの賃貸情報をスクレイピングし、機械学習モデルで家賃を予測することを試みましたが、家賃がバカ高い物件の予測がうまく行きませんでした。
前編ではバカ高物件の詳細ページを見て高額になる理由を探して仮説を立てました。
今回の後編では、詳細ページのスクレイピングをして得た情報を使い、前編での仮説を検証します。


# 前編の振り返り

前編では、以下の情報が家賃に影響しそうだと仮説を立てました。

* 設備の中身や充実
* 構造
* 駐車場
* 不動産会社

これらの変数がどれだけ家賃に影響しているのか、機械学習モデルを使って調べます。
※不動産会社の情報を拾い忘れました。申し訳ない…。


# 新しく拾ってきた情報

詳細ページをスクレイピングしたおかげでかなり情報量が増えました。
今までは1物件につき22種類の情報でしたが、情報を拾いなおして __31種類+オプション+契約条件__ まで増えました。
オプションや駐車場、その他拾えそうなものは拾ってきました。
※オプションや契約条件は1物件にいろいろな種類がついていたりいなかったりするので別枠にしています。

総物件数は __約19万件__ 、1件につき __31種類+オプション+契約条件__ の情報を持っています。

※スクレイピングでデータを拾いなおしたため、サンプルは前編と後編で異なります。
前編と後編で結果に差が出たとして、それはサンプルに差があるから、という可能性を残すことになります。
（そんなに大きな差にはならないような気がしますが…）


# 事前に行ったこと

機械学習モデルとか、精度向上のための調整とか、そんな話をします。
そんなに大事でもないので飛ばしていただいてもOKです。

### 使用したモデル

前編に引き続き __LightGBM__ を使用しました。

### 対数変換

高額物件でも予測しやすいように対数変換しました。
この時点でのr2スコアは __約0.878__ でした。

※r2スコアって何？と思う方向けに、r2スコアが0.88だったらテストで88点とれているってことです。その認識でだいたいあってます。~~詳しい人に怒られそうですが。~~

### train_test比率

データ数trainとtestの比率は __7:3__ に分けると精度が良くなりました。
この時点でのr2スコアは __約0.956__ でした。既によさげなスコアが出ています。

### パラメータ調整

`n_estimators`だけ十分になるように設定しました。
n_estimators以外も調整を試みましたがあまり精度に影響がなかったので気にしないことにしました。
 ~~めちゃめちゃ時間かかって大して変わらなかったので萎えたとも言えます~~


# 詳細情報とともに家賃を予測してみる。

LightGBMくんと学習データの調整をして、家賃予測に臨みました。


#### 解釈の注意

この先を読むうえで気を付けていただきたいのが、モデルでの重要度が高い＝変数と家賃に因果関係がある　ということではありません。
例えば、「オートロック機能がついている物件かどうか」という情報をモデルが重要視していたとして、「オートロックがある」から「家賃が高くなる」、となるとは限らないってことですね。
あくまでそういう傾向があるよ、くらいの解釈にとどめておくと良いと思います。

### 予測精度

31種類すべての変数を利用した場合、r2スコアは __約0.959__ となりました。
学校のテストで96点取れたら凄いですよね（厳密には違うけど）。

下のグラフは家賃の真値または予測値が100万以上の物件のヒストグラムです。
200万以上と予測した物件の数が、実際に家賃が200万以上の物件の数と同じくらいになっているように見えます。

<img width= alt='be_able_to_predict_high_rent.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/b7546186-0303-6cd2-fb08-26e29c57c5e7.png'>

LightGBMくんも200万以上の物件がわかるようになりました。300万付近の予測が出なかったのは少し残念ですが、なかなか良さげな気がします。

### 変数重要度

LightGBMくんが予測するのに各変数がどのくらい役に立っていたのか、変数重要度をグラフに表示します。

<img width=500 alt='details_feature_importances.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/ce1ad315-3691-938b-6493-15b40ae3972f.png'>


情報を増やす前と増やした後でそんなに変わっていないですね。

やはり __面積__ __間取り__ がかなり重要なようです。
物件の広さが一番家賃に直結するみたいですね。

次点で __市区町村(〇〇区)__ と __駅__ が有力です。
物件の立地も大きな影響力があるようです。

そこから __築年数__ __階数__ と続いていきます。
前回の結果とおおよそ同じです。

新しく追加された情報では、__構造__ が多少役に立っているようです。 __オプションの数__ もちょっと役に立っています。
駐車場情報、契約条件の数、その他の情報はほぼほぼ役に立っていません。


これを見る限り、前編の仮説の検証結果は
* 設備の充実　→　関係なくはない（ほとんどない）
* 構造　→　多少関係ある
* 駐車場　→　関係ない

ということが言えそうです。

設備の充実がほとんど関係なさそうなのは意外な結果でしたが、それらしい理由が見つかりました。
実はSUUMOの「特徴・設備」の欄には最大でも60個しか記載されていないことが判明しました。
以下は「特徴・設備」に載っていたオプションの数のヒストグラムです。

<img width= alt='hist_num_option.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/34e2727e-23c5-dfdb-7607-c85744b21942.png'>

60の値が異常に高く、また60より大きい値がありません。
このことから、「特徴・設備」には最大でも60種類しか載せられないことが予想できます。

不動産会社からすれば、「特徴・設備」の欄がスカスカだと魅力のない物件とみられるのでなるべくたくさん書きたいはずです。
大した事ない物件でも、何とかかけそうな特徴を探して載せておくのではないでしょうか。
対して魅力あふれる高額物件でも、特徴は60種類までしか書けないことになります。
つまり、中身の差はあれど、数でみれば普通の物件も高額物件も大した差は出ないと言えそうです。



### 変数選別

予測にあまり役に立っていない変数を減らしました。
一つ変数を減らして学習と予測をしなおし、精度がほとんど変わらなかった変数を減らしました。

その結果、変数は __12種類__ まで減りました。この時のr2スコアは __約0.962__ で、減らす前から若干上がりました。
（誤差レベルな気がしなくもないですが）

そして、残った変数とその重要度が以下となりました。

<img width=500 alt='elite_feature_importances.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/414fa427-ef2e-fe49-78c7-d86d783a2879.png'>

先ほどあった変数重要度とほとんど変わっていないですね。その方が自然だと感じられますが。
このくらいの情報があれば、結構高い精度で家賃が予測できるらしいです。

前編の時は __間取り__ 変数が落とされていましたが、今回は生き残っていますね。それと、__階数__ が落とされて __階__ が生き残りました。

前編では似たような情報を持っている変数が落とされているのではないか、と書きましたが、実は __間取り__ と __面積__ の情報は似て非なるものということなのかもしれません。
私としてはその方が体感正しいと感じられます。クソ広いだけのワンルームと1LDKなら後者の方が住みたいと感じます。

それはそれで前編はなぜ間取りの情報を落としたのか、疑問が残りますね。
パラメータ調整を渋ったせいですかね。それが理由ならわかりやすくていいのですが。
若しくは、スクレイピングした時期が違うのでサンプルの差が影響しているのかもしれません。



# 家賃との関係性が高いオプションを調べる

先ほどの検証では、物件のオプションの数の情報は使用しましたが、「何のオプションが入っているか」の情報は利用していませんでした。
物件一つ一つに、特定のオプションがあるorないの情報を付けて、LightGBMくんに与えてみます。

### このオプションありますか？変数を作る。

例えば、オプションの一つに「エアコン」があります。
詳細ページの特徴・設備の情報欄に「エアコン」と書いてあれば「1」、書いていなければ「0」として、「isエアコン」変数を作りました。
こんな感じであらゆるオプションに対してあるない変数を作りました。

※boolだからisつけたんですが、冷静に考えて YesNoの質問=is っておかしいですね。DoYouHave〇〇とかのほうが正確な気がします。

<img width=400 alt='この変数ありますか？テーブル.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/1c5a8607-3446-db6c-f9cc-0a9cc181e9ed.png'>


### 変数を1つ入れてみる

先ほどの厳選された12種類の変数+1つのオプション情報をモデルに与えて予測しました。
いっぺんに全部入れないのはさすがに情報量が多すぎるからです。モデルが結果を出すまでにクッソ時間がかかってしまうのでやりません（やれません）。
あと情報量が多すぎるとかえって精度に悪影響が出るとかそんな話もあります。

まずはよくあるオプション上位20種の結果です。
上からよくある順に並べています。

<img witdh= alt='option_r2_importance_top20.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/1aa0a49e-ffab-375e-e41d-19a8d21f1a49.png'>

オプションを追加する前のr2スコアは __約0.9615__ でした。
(さっきは約0.962と書きましたが、細かい違いを確認したいので4桁に変えました)
左のグラフを見ると、r2スコアが向上したのは「シューズボックス」と「クロゼット」の2つです。他は下がりました。

importance（右のグラフ）は、「洗面所独立」「オートロック」「浴室乾燥機」「システムキッチン」「バストイレ別」あたりが比較的大きいです。

r2スコアとimportanceが連動していないのは何とも不思議な感じがします。
（家賃の予測に役立つ変数なのにスコアが下がるのは奇妙じゃないですか？）
これもおそらく、追加したオプションが他の変数で十分説明できている情報だからむしろ邪魔になっている可能性が高いです。

#### 重要度の高いオプションを見る

importanceが最も高いオプションを見てみます。
下はimportanceの高い順に並べたものです。

<img width= alt='option_r2_importance_importancetop20.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/2dd67b7c-d39b-9dfc-9526-e47d036062bb.png'>

なんとなーく、あるとないで家賃相場が変わりそうなオプションが上位に並びます。
「オートロック」「システムキッチン」「エレベーター」はいかにも家賃が高そうな気がします。
「バストイレ別」は格安物件とそうでない物件を分けられるのではないでしょうか。

「宅配ボックス」が一番上にあるのが何とも不思議感に思ったのですが、おそらくは宅配ボックスって新築に多いんじゃないでしょうか。
Amazon利用者が増えて置き配の文化も浸透して、宅配ボックスの需要が増えたのがごく最近ってことじゃないですか？
実質新築かどうかを見分ける変数になっている可能性があります。知らんけど。

して、あるとないで家賃に差があるかどうか確認します。
「宅配ボックス」のあるないで箱ひげ図を作成したものが下です。
※外れ値を表示すると凄く見づらくなるので非表示にしています。

<img width= alt='boxplot_takuhaibokkusu.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/4c7a136d-a487-8713-65a4-33c0c054349d.png'>

結構なズレがありますね。
平均値を比較すると、
* ある：約12.27万
* ない：約 8.86万

でした。そこそこの差があります。
他のimportanceが高いオプションも細かい差こそあれどだいたい同じような傾向がありました。

importanceを見れば、家賃との関係性が感じられそうです。


#### r2スコアが高いオプションを見る

r2スコアが最も高かった変数を見てみます。
r2スコアが高い順に並べました。

<img width= alt='option_r2_importance_r2scoretop20.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/e35ff1b5-9e76-cb30-6985-4f8285a07ad3.png'>

importanceがスカスカですね笑
ですがモデルの予測に役立った皆さんです。

「始発駅」「シャッター」「2面採光」など、家賃に関係あんの？と思ってしまったオプションが並んでいます。
「敷金・礼金不要」は、おそらく高額物件にはついていないですよね。富裕層にそんなオプションあっても大した魅力にならないでしょうから。という意味で、高額物件とそうでない物件を分けている可能性があります。

これも家賃相場の違いを確認しました。
<img width= alt='boxplot_sihatueki_sym.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/9c3abd59-e4a7-29a9-0566-dae83fd7550f.png'>

若干の違いはあれど、大した差ではないような気がします。
これも外れ値を非表示にしていますが、実は外れ値を表示すると明確に違いが出ます。

<img width= alt='boxplot_sihatueki.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/2e94cc47-919a-dc6e-7395-e1829a99dd67.png'>

私が始めてみた時に「おぉ…」と声がもれました笑。
（謎の400万越えを除いて）家賃100万以上を超える物件は始発駅周辺に存在しないことがわかります。
よって、始発駅周辺という情報があれば超高額物件ではないと宣言することができるわけですね。
（わざわざ始発駅って情報を書いてないだけって可能性もあります）


先に少し書いた「敷金・礼金不要」は高額物件につかないだろうというのも、同じように確認してやはり超高額物件にはついていませんでした。
同様に、r2スコアが向上したものは高額層についていないという傾向が見られました。

このような結果になったのは、相場を大きく分けられるほどの情報ではないものの、他の変数とは少し違った情報が得られるので、スコア向上につながっていると考えられます。
特にLightGBMは決定木を利用しているモデルなので、都合の良い情報だけ利用できる点で相性が良いように思いますね。


### おまけ：オプション情報だけで予測してみる

これについてはただの好奇心での実験です。
オプション情報だけでも家賃予測できんじゃね？と思ってしまったので試します。

先ほどのオプションあるないテーブルのうち、ほとんど物件についていないオプションを削って300個のオプション情報を説明変数にして、家賃を予測しました。

結果、r2スコアは __約0.71__ でした。さすがにめっちゃ精度良くね？とはならんか。
以下は変数重要度のグラフです。

<img width=500 alt='elite_feature_importances (1).png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774344/db22d311-cef8-9e54-fe14-a4edbeabebea.png'>


「3口以上コンロ」が一番影響力高いのか…。
意外過ぎるやつが出てきたのでビビりました。
しかして他の変数は、先ほどの個別に重要度を確かめた時に出てきた顔ぶれも多いですね。

皆さんが今後賃貸を借りることがあれば、ぜひコンロの数に注目してみてください。


# まとめ

結局のところ、家賃に関係の深い情報は検索結果表示のページでほぼほぼ読み取れそうですね。
確かに家賃が上がる傾向のあるオプションはいくらかありましたが、わざわざ確認するまでもなく家賃相場がだいたいわかるようです。
どのオプションが有効かってのは少し戻ってグラフ見てください。重要度が高いオプションは結構相場の違いもあります。

で、家賃がバカ高い理由は何なのかってことですが、ザックリ「クソ広い」「立地良し」「新しめ」「建物がデカい」くらいの傾向が分かりました。いや周知の事実やん。
これだけいろいろ調べたうえでそういう結果になったので、その辺の人が言うより僕が主張したほうが説得力あるんじゃないですか？たぶん。

## おまけ：パラメータ調整の話

前編でパラメータ調整を渋りましたが、記事を書いた後に前編で使っていたデータでモデルを動かし、パラメータ調整しました。
`num_leaves`の影響力が結構大きく、r2スコアは約0.90まで向上しました。0.9くらいまで行けるんですね。

モデルのパラメータ調整は大事ですね。
仮に調整しても大して変わらんのだとしても、調整しても変わらないことを確かめるのは大事だと思います。

# 終わり。

賃貸についていろいろ調べまわったので、賃貸に詳しくなれたような気がします。
今度引っ越すときに「おっ、この物件宅配ボックスあるやん家賃高そう」とか言ってそうです。

それ以上に、気になることの調べ方とかそういう方向性で良い経験になったと感じます。
自分で気になったことを自分の手で調査できるのはなかなか面白いです。

変数の詳しい解釈を得るための勉強を進めているので、その手法も使っていろいろ調査してみようと思います。
「PFI」とか「PD」とか「ICE」とか「SHAP」とかその辺です。少々専門性が高いと思うので記事にしてみてもらえるかどうかは怪しいと思いますが。

クラスタリング手法で物件の傾向分けとかもしてみたいですね。
カテゴリ変数が多いのでその辺をどうするか見えていないところなんですけども…。

あと、オプションあるない変数の扱いがクッソめんどくさかったです。だいぶスパース（0ばっかりとかそういうやつ）な情報でメモリ食いまくるって言うね。何回かNotebookくんにメモリ足りねぇって怒られました。あとでスパース情報の扱い方も勉強したほうがいいですね。



# 他のSUUMO記事

まとめ記事書いたのでぜひご覧ください。

https://qiita.com/tomyu/items/aa565490f48612e00535