Pythonと機械学習で家賃予測Webアプリを作ってみた!【Flask・Selenium・scikit-learn】
はじめに
私はすでに機械学習とWebスクレイピングの学習を一通り終えて、それらの技術を使いスクレイピングで情報を取得し機械学習で結果を予測するWebアプリを開発したので備忘録としてこのアプリの説明を残します。
このアプリは、不動産情報サイトSUUMOから物件データを自動で収集し、機械学習モデルを構築して、ユーザーが指定した条件の家賃を予測します。
本記事では、このアプリケーションの概要から、使っている技術、コードのポイントまでを解説します。Webスクレイピングや機械学習、Flaskを使ったWebアプリ開発に興味がある方の参考になれば幸いです。
こんな方におすすめ
- Pythonで実践的なWebアプリを作ってみたい方
- Webスクレイピングと機械学習を連携させる方法に興味がある方
- Flaskを使った開発の流れを知りたい方
GitHubリポジトリ
アプリケーションの概要
このアプリは、以下の特徴を持っています。
- 自動データ収集: SUUMOから指定された地域の物件情報をWebスクレイピングで自動的に収集します。
- 機械学習モデルの自動構築: 収集したデータを用いて、家賃を予測するためのニューラルネットワークモデルを自動で学習・保存します。
- シンプルなWebインターフェース: Flaskを利用しており、ブラウザ上で誰でも簡単かつ直感的に操作できます。
- モデルの再利用: 一度学習させたモデルはファイルとして保存され、次回からは学習済みのモデルを再利用して高速に予測ができます。
アプリの動作イメージ
-
その地域の学習済みモデルがない場合は、自動でデータ収集と学習が始まります。(数分かかります)
-
「最寄り駅までの時間」「築年数」「専有面積」「間取り」を入力して予測ボタンをクリックします。
使用技術
このアプリケーションは、主に以下のPythonライブラリで構成されています。
-
Webフレームワーク:
-
Flask
: Webアプリケーションの骨格となる部分です。ルーティングやHTMLテンプレートの表示を担当します。
-
-
データ収集(スクレイピング):
-
selenium
: ブラウザを自動操作して動的なウェブサイトから情報を取得します。 -
webdriver-manager
: ChromeDriverを自動でインストール・管理します。
-
-
データ処理:
-
pandas
: 収集したデータを表形式で扱うために使用します。 -
numpy
: 数値計算を高速に行います。
-
-
機械学習:
-
scikit-learn
: 機械学習モデルの構築、学習、評価に使用します。今回はニューラルネットワークモデル(MLPRegressor
)を利用しました。 -
joblib
: 学習済みのモデルをファイルに保存・読み込みするために使用します。
-
ディレクトリ構造
このアプリケーションは、以下のようなディレクトリ構造になっています
コードのポイント解説
1. データ収集とモデル学習 (scraper.py
)
このスクリプトがスクレイピングとモデルの構築を行います。scrape_and_train
関数が主な処理を担います。
処理の流れ
-
Seleniumの起動:
headless
モードでChromeブラウザを起動し、SUUMOにアクセスします。 -
データ収集:
- 検索フォームに指定された地域名を入力し物件を検索します。
-
find_elements
で物件情報を取得し、PandasのDataFrameに変換します。 - 「次へ」ボタンをクリックして、複数ページからデータを収集します。
-
データ前処理:
- 収集したデータ(賃料、専有面積、築年数など)を扱いやすいように整形します。例えば、「万円」や「m2」などの単位を取り除き、数値データに変換します。
scraper.py
# scraper.pyより抜粋 df['賃料'] = df['賃料'].str.replace('万円', '').astype(float) df['専有面積'] = df['専有面積'].str.replace('m2', '').astype(float) df['築年数'] = df['築年数'].str.replace('新', '0').str.replace('築', '').str.replace('年', '').astype(int) df['徒歩'] = df['徒歩'].str.extract(r'(\d+)').astype(int)
- 「間取り」のようなカテゴリ変数は、
pd.get_dummies
を使ってモデルが学習できる形式(0か1のフラグ)に変換します。
- 収集したデータ(賃料、専有面積、築年数など)を扱いやすいように整形します。例えば、「万円」や「m2」などの単位を取り除き、数値データに変換します。
-
モデルの学習と保存:
- scikit-learnの
MLPRegressor
(多層パーセプトロン回帰)を使ってモデルを学習させます。scraper.py# scraper.pyより抜粋 model = MLPRegressor(solver="adam", random_state=0, max_iter=5000, hidden_layer_sizes=(100, 50)) model.fit(x_train, y_train)
- 学習済みのモデル、学習に使用したカラム情報、間取りのリストを
joblib
とjson
を使ってmodels/
ディレクトリに保存します。
- scikit-learnの
2. Webアプリケーション (app.py
)
Flaskを使って、HTMLテンプレートの表示、scraper.py
の呼び出しを制御します。
-
@app.route('/train', methods=['POST'])
(モデル準備)- ユーザーが入力した地域名を受け取ります。
- その地域の学習済みモデル (
_model.pkl
) が存在するかチェックします。 -
存在しない場合:
scraper.py
のscrape_and_train
関数を呼び出して、データ収集とモデル学習を実行します。 - 存在する場合: 保存されているモデルと関連情報を読み込みます。
- 最後に、予測情報を入力するための
index.html
を表示します。
-
@app.route('/predict', methods=['POST'])
(予測実行)- ユーザーが入力した「築年数」や「専有面積」などの情報を受け取ります。
-
joblib.load
で学習済みモデルを読み込みます。 - 入力された情報からモデルが予測できる形式のDataFrameを作成します。
-
model.predict()
で家賃を予測し、結果をresult.html
に渡して表示します。
app.py# app.pyより抜粋 @app.route('/predict', methods=['POST']) def predict_page(): # (省略) フォームからデータを取得 # モデルとカラム情報を読み込み model = joblib.load(f'models/{safe_region_name}_model.pkl') with open(f'models/{safe_region_name}_columns.json', 'r', encoding='utf-8') as f: columns = json.load(f) # 予測用のデータフレームを作成 pred_df = pd.DataFrame(columns=columns) pred_df.loc[0, :] = 0 pred_df['専有面積'] = menseki pred_df['築年数'] = year pred_df['徒歩'] = minute selected_madori_col = f"madori_{selected_madori}" if selected_madori_col in pred_df.columns: pred_df[selected_madori_col] = 1 # 予測を実行 prediction = model.predict(pred_df) fee = round(prediction[0], 2) return render_template('result.html', fee=fee, region_name=region_name)
実行方法
このアプリケーションを自分のPCで動かしてみたい方は、以下の手順で実行できます。
-
リポジトリのクローン(ダウンロード):
git clone [https://github.com/GAT252/renting_prediction](https://github.com/GAT252/renting_prediction) cd renting_prediction
-
依存ライブラリのインストール:
pip install -r requirements.txt
-
アプリケーションの起動:
python app.py
-
ブラウザでアクセス:
Webブラウザでhttp://127.0.0.1:5000
にアクセスします。
まとめと今後の課題
今回は、Pythonを使ってSUUMOからデータを収集し、家賃を予測するWebアプリケーションを作成しました。Flask、Selenium、scikit-learnを組み合わせることで、データ収集からモデルの学習、予測までを自動化する仕組みを実現できました。
今後の課題としては、以下のような改善が考えられます。
-
クラウドへのデプロイ: HerokuやAWSなどにデプロイして、誰でもアクセスできるようにする。
-
特徴量の追加: 物件の設備(オートロック、バス・トイレ別など)や、建物の構造(鉄筋コンクリートなど)といった、より多くの特徴量をモデルに追加して予測精度を向上させる。
-
スクレイピングの効率化 :築年数と駅から徒歩何分という情報はサイトの構造上、ほかの情報と同時に取得できなかったので一つ、一つピンポイントでパスを指定するしかないからスクレイピングに時間がかかっていた。パスをピンポイントで指定して物件情報を取得するのではなくクラス名などで他の情報と同時に取得できればスクレイピングの時間が短くなり待機時間が短くなる。
学び・得られた成果
- Webスクレイピングから機械学習モデル構築、Webアプリ開発までの一連の知識・スキル習得: seleniumによるスクレイピング、scikit-learnを使ったモデル構築、Flaskによるアプリケーション開発という一連の流れを経験できました。
- 問題解決力やデバッグ能力の向上: スクレイピング時のエラーハンドリングや、ライブラリ間の連携で発生する問題への対処を通じて、実践的な開発スキルが向上しました。
最後まで読んでいただきありがとうございました!この記事が、皆さんのアプリ開発のヒントになれば嬉しいです。