Pythonによる不動産情報のデータ取得&分析(3)【賃貸物件/分析編】
さて、いよいよ分析にチャレンジします。
目的は、家賃の適正水準を探ることです。今後、マンション売却物件の分析も行いたいと思っていますので、賃貸価格と売買価格の比較を行い、割安割高の検証を行うことも念頭に置いています(出来るかどうかはやってみないと分かりませんが)。
前回、賃貸物件データの前処理を行いましたので、そのデータを用いて、pyhonにて重回帰分析を行いたいと思います。が、統計分析についても、全くのシロウトですので、書籍やブログ等を参考にしながら行います。
まずは、前回保存したデータをDataframeとして取り込みます。また、逐次グラフ化して確認しながら作業を行っていきますので、Jupyter Notebookを利用します。
なお、70㎡の面積に引き直した家賃を「標準家賃」として、家賃単価(円/㎡)×70で計算した結果を列として追加しておきます。
賃貸データの概要の把握
データ系列の情報を見ておきましょう。
15万件の賃貸データがありますね。まず、家賃の分布と家賃単価の分布を見てみましょう。それぞれの要約統計量describe
とヒストグラムhist()
を表示します。
家賃の平均は10万円ほど、家賃単価の平均は3350円ですね。家賃は物件の広さによって異なりますので、今後の分析は、不動産業者が物件比較の際に良く利用する家賃単価を中心に行っていきたいと思います。
市区別の物件数
世田谷区の物件数が突出して多いですね。各区の人口と比較してみます。
各市区町村の平成30年3月現在の人口が以下に掲載されていますので、Excelにコピペして、csvファイル化します(市町村のデータも取り込まれます)。
そのcsvファイルをdf_pop
として取り込んだ上で、grouped
に統合concat()
します。その際に、統合方法としてjoin='inner'
を指定します。その後、必要のない面積の列等を除外して、グラフ化します。
人口が多いと物件も多いという傾向が出てますね。大田区だけ、人口の割には物件数が少ないですが。スクレイピングの際にデータ取得が完全でなかったのが影響しているのかもしれません。
もともと目的が、家賃の適正水準を探ることなので、データ数が十分にあれば良いとします。
市区別の家賃・家賃単価
市区別の家賃・家賃単価の平均を見ると、当たり前かと思いますが、明らかに傾向がありますよね。
ついでに家賃単価の箱ひげ図を描いてみましょう。グラフを平均によって並べ替えするのには、seabornライブラリが便利です。傾向がよく分かって面白いですね。世田谷区が案外低いですね。
築年数別の家賃単価
築年数別に家賃単価を散布図にしてみます。
上下に異常値がありそうですので、中身を見てみましょう。
面積が2㎡のものがあったり、逆に660㎡のものがあったり、どうも入力ミスと思われるデータが散見されます。そうでないものもありますが、単価が14000円以上、500円以下のものはこの際、除外して分析していくことにします。
そのうえで、築年数毎の平均値をグラフ化すると、以下のようになります。
60年以降の平均値が大きくバラついていますので、築年数毎の物件数を見てみましょう。2000件以下だけ表示させます。
データ数の少ない築年数56年以降を分析から除外してしまいましょう。 さらに、市区別・築年数別の家賃単価(平均)をデータフレーム化したものを作成し、グラフ化します。
区別に家賃単価の水準感が異なり、更に築年数が増加すれば、単価が下がっていく傾向がよく分かりますね。
最寄駅からの時間による家賃単価
最寄駅からの時間によって単価がどう変化するのかを確認しておきます。 最寄駅から物件までの移動手段として「徒歩」の場合にてグラフ化します。
これも異常値がありそうです。データ数を見てみましょう。
明らかに、750分は間違いですね。75分もどうでしょうか。切りの良いところで40分超のデータは除外しましょう。さらに、これも市区別にグラフ化しておきます。
これも異常値ですので、確認して必要があれば除外しておきましょう。
重回帰分析を行ってみる
さて、いよいよ重回帰分析です。有名なライブラリscikit-learnをimportして、分析を行います。異常値を除外したdf_modから、重回帰分析の説明変数、目的変数とするもののみ取り出して、データフレーム化しておきます。面積と部屋数、物件階と建物の高さは、各々やや相関が高いので、ここでは面積、物件階を残すことにします。この当たりは専門家でないので、適当です。すみません。
# scikit-learnライブラリをimportします import sklearn from sklearn.linear_model import LinearRegression as LR # 線形回帰モデルのインスタンス化 model = LR() # 説明変数Xに家賃単価(目的変数)と除外するとした「部屋数」「階数」以外を挿入 X = df_for_analysis_base.drop(['家賃単価', '部屋数','階数'], axis=1) # 数値以外の説明変数(「市区」「手段」)をダミー化 X = pd.get_dummies(X) # 目的変数に家賃単価を代入する y = df_for_analysis_base['家賃単価']
説明変数Xはこんな感じ。
予測モデルの作成は、以下の1行を実行するだけです。
# 予測モデルの作成
model.fit(X, y)
結果として、回帰係数model.coef_
、切片model.intercept_
、決定係数score()
をそれぞれ表示させます。
決定係数は61%となりました。まぁこんなもんなんでしょうか。 説明変数と係数の関係をもう少し分かりやすく表示させてみましょう。
coeff_df = pd.DataFrame(X.columns) coeff_df.columns = ['説明変数'] coeff_df['係数推定'] = model.coef_
coeff_dfを表示させると以下の通りとなりました。
従って、(場所)世田谷区(築年数)20年(駅からの距離)徒歩10分(面積)70㎡ (物件階)2階の賃貸物件の家賃単価は、4164 .43 -3.84 +276.05 - 15.0470 - 26.3320 - 22.2110 + 50.852 = 2736円/㎡となります。
賃貸物件の面積が70㎡ですので、約191,500 円が家賃推定額となります。
(場所)江東区(築年数)15年(駅からの距離)徒歩5分(面積)80㎡ (物件階)10階の賃貸物件ですと、4164.43 -161.86 + 276.05 -15.0480 - 26.3315 - 22.41 * 5 + 50.85 * 10 = 3076円/㎡が家賃単価となります。
賃貸物件の面積が80㎡ですので、約246,000円が家賃推定額となります。
いかがでしょうか。なんとなくイメージあってますか。
検証してみる
データを学習用データ(Train)と検証用データ(Test)に分けて、残差プロットなるものを作成し、検証してみることも行うようです。
y=0の回りに、残差がランダムにばらけているように見えれば、モデルは良かったと言えるようですが、上のグラフの場合はどうなんでしょう。ランダムにはばらけていないように見えるので、モデルを修正していく必要があるかもしれません。
今回は、方角のデータ等、家賃単価に影響がありそうなデータを取り込んでいません。また、統計や機械学習は、まだ、勉強を始めたばかりですので、今後、機会があれば、モデルの修正にチャレンジしていきたいと思います。
長くなりましたので、本日はこれにて失礼します。次回以降は、売却物件について分析していきたいと思います。