不動産価格のデータ分析
本記事はAidemyデータ分析コースの成果物提示の回となっております。
内容は「不動産価格の分析比較」となっております。
Pythonを使ってSUUMOから都内のマンション情報を取得し、いくつかの分析手法を試して結果比較を行なっていきます。
本記事の大きな流れとしては
1、SUUMOから不動産データを取得(ウェブスクレイピング)
2、取得データをデータクレンジング
3、3つの手法を使いデータ分析→結果
4、まとめ
とさせていただきます。
1、SUUMOから不動産データを取得(ウェブスクレイピング)
今回は、東京都21区内(データクレンジングの関係で港区・北区を除外)にある価格が1億円未満の区分マンションのデータを取得しデータ分析に利用していきます。
#ライブラリをインポート
from bs4 import BeautifulSoup
from time import sleep
import requests
import pandas as pd
#データ取得のためURL、対象項目を指定
url = "https://suumo.jp/jj/bukken/ichiran/JJ012FC001/?ar=030&bs=011&ta=13&sc=13101&sc=13102&sc=13104&sc=13105&sc=13113&sc=13106&sc=13107&sc=13108&sc=13118&sc=13121&sc=13122&sc=13123&sc=13109&sc=13110&sc=13111&sc=13112&sc=13114&sc=13115&sc=13120&sc=13116&sc=13119&cn=9999999&cnb=0&et=9999999&hb=0&ht=9999999&kb=1&kj=9&km=1&kt=10000&mb=0&mt=9999999&ni=9999999&pc=30&pj=1&po=0&tb=0&tj=0&tt=9999999"
data_list_s=[]
for i in range(1,20):
print("data_listの大きさ",len(data_list_s))
target_url = url.format(i)
print(target_url)
r = requests.get(target_url)
sleep(1)
soup = BeautifulSoup(r.text)
contents = soup.find_all("div",class_="dottable dottable--cassette")
for content in contents:
menseki = content.find_all("table")[0].find_all("dd")[0].text
madori = content.find_all("table")[0].find_all("dd")[1].text
elements = content.find_all("div",class_="dottable-line")
title = elements[0].text
price = elements[1].text
address = elements[2].text
age = elements[4].text
#データ項目名を作成
data_list = {
"title":title,
"price":price,
"address":address,
"age":age,
"menseki":menseki,
"madori":madori
}
data_list_s.append(data_list)
print(data_list)
df = pd.DataFrame(data_list_s)
df.to_csv("test.csv",index = None,encoding="utf-8-sig")
出力結果を見ると、下記の通り文字の羅列となってます。
そこで「df」で見てみると、データ化されます。
df
まずはデータの取得ができました。
2、取得データをクレンジング
上記の表示を見たときに、\nやtitleの物件名、priceの販売価格等データ内容に余計な文言や数値が入っており、分析にかけられる状態ではありません。
そこで下記のコードを用いてデータをきれいにしていく作業が必要です。
#取得データをデータクレンジング
# dfの各要素から改行コード \n を削除
remove_break = lambda x: x.replace('\n', '')
df = df.applymap(remove_break)
# title,price,menseki,madori,address,ageの項目について不要文言の削除を行い、データを整える
extract_title = lambda x: x.replace('物件名', '')
extract_price = lambda x: x.replace('販売価格', '').replace('万円', '')[:4]
extract_menseki = lambda x: x.replace('(壁芯)', '').replace('m2', '').replace('㎡', '').replace('(', '')[:5].replace('.', '')[:2]
extract_madori = lambda x: x[:4]
extract_address = lambda x: x.replace('所在地', '').replace('東京都', '').replace('-', '').split('沿線・駅')[0][:8].replace('0', '').replace('1', '').replace('2', '').replace('3', '').replace('4', '').replace('5', '').replace('6', '').replace('7', '').replace('8', '').replace('9', '')[:3]
extract_address2 = lambda x: x.replace('所在地', '').replace('徒歩', '').split('沿線・駅')[1][-3:].replace('」', '').replace('歩', '').replace('分', '').replace('1', '1').replace('2', '2').replace('3', '3').replace('4', '4').replace('5', '5').replace('6', '6').replace('7', '7').replace('8', '8').replace('9', '9')
extract_age = lambda x: x.replace('バルコニー', '').replace('築年月', '').replace('m2', '').replace('㎡', '').replace('-', '').replace('1月', '').replace('2月', '').replace('3月', '').replace('4月', '').replace('5月', '').replace('6月', '').replace('7月', '').replace('8月', '').replace('9月', '').replace('10月', '').replace('11月', '').replace('12月', '').replace('年1', '').replace('年', '')[-4:]
df.title = df.title.map(extract_title)
df.price = df.price.map(extract_price)
df.menseki = df.menseki.map(extract_menseki)
df.madori = df.madori.map(extract_madori)
df['address1'] = df.address.map(extract_address)
df['address2'] = df.address.map(extract_address2)
del df["address"]
df.age = df.age.map(extract_age)
df.to_csv("revised_df.csv",index = None,encoding="utf-8-sig")
df.head()
出力結果は下記の通りとなります。
これでデータの準備は完了しました。
3、3つの分析手法を使い、データ分析
Pythonによるデータ分析手法は数多くありますが、今回は
・線形回帰
・ラッソ回帰
・リッジ回帰
それぞれの手法の説明については下記リンク先よりご確認ください。
線形回帰:https://qiita.com/0NE_shoT_/items/08376b08783cd554b02e
ラッソ回帰:https://qiita.com/y_itoh/items/ac5aa8225e4c72573c12
リッジ回帰:https://qiita.com/g-k/items/d3124eb00cb166f5b575
これらで分析をした上で結果の比較を行ってまいります。
import os
import re
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
df_data = pd.read_csv('./revised_df.csv')
# 価格と相関の高い築年数(age)と面積(menseki)と最寄り駅徒歩分数(address2)を説明変数に使用
X = df_data[["age", "menseki","address2"]].values
y = df_data["price"].values
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.1 , random_state=42)
best_model = ""
pred_model = []
# 線形回帰
model = LinearRegression() # 線形回帰モデル
model.fit(train_X,train_y) # 学習
pred_y = model.predict(test_X) # 予測
mse= mean_squared_error(test_y, pred_y)# 評価
print("線形RMSE : %.2f" % (mse** 0.5))
min_mse = mse
best_model = "線形回帰"
pred_model = pred_model.append(model)
# ラッソ回帰
model = Lasso() # ラッソ回帰モデル
model.fit(train_X,train_y) # 学習
pred_y = model.predict(test_X) # 予測
mse= mean_squared_error(test_y, pred_y)# 評価
print("ラッソRMSE : %.2f" % (mse** 0.5))
if min_mse > mse:
min_mse = mse
best_model = "ラッソ回帰"
pred_model = model
# リッジ回帰
model = Ridge() # リッジ回帰モデル
model.fit(train_X, train_y) # 学習
pred_y = model.predict(test_X) # 予測
mse= mean_squared_error(test_y, pred_y)# 評価
print("リッジRMSE : %.2f" % (mse** 0.5))
if min_mse > mse:
min_mse = mse
best_model = "リッジ回帰"
pred_model = model
print("ベストモデル:{}".format(best_model))
出力結果としましては、
ベストモデルは「線形回帰」ということになりました。
また改めて他の分析手法も試して比較しようと思います。
4、まとめ
申し訳ないのですが、私自身勉強不足で他のブログ記事のように結果に対する詳細な分析やこの結果をどう活かすか等についてまで言及できません。
今後勉強を続け、このブログでお伝えしていけたらと思ってます。
また、本記事について時間が限られている中、Aidemyのチューターさん達にご指導頂き、作成することができました。
色々聞いてしまいすいません。ご対応感謝します。
データ分析コースを通じてPythonの文法・構造や分析流れ・手法を学ぶことができ、大変有意義であったと共に、学習の深さを感じることとなりました。ありがとうございました。
この記事が気に入ったらサポートをしてみませんか?