SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

翔泳社の本(AD)

Pythonの機械学習ライブラリ(pandas)を使って、回帰アルゴリズムで不動産価格を予測しよう

  • X ポスト
  • このエントリーをはてなブックマークに追加

 Pythonでの機械学習を学ぶ入門書『実務で役立つPython機械学習入門』(翔泳社)が発売中です。本書では実際にありうるビジネス課題を想定し、機械学習によるデータ分析を用いて解決する手順を解説しています。今回は本書から、回帰アルゴリズムを利用して不動産価格を予測する方法を紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

 本記事は『実務で役立つPython機械学習入門 課題解決のためのデータ分析の基礎』(池田雄太郎、田尻俊宗、新保雄大)の「2-2 回帰アルゴリズム:不動産価格を予測しよう」から抜粋したものです。掲載にあたって編集しています。

 また、記事内ではPythonとpandasを利用します。

回帰アルゴリズム:不動産価格を予測しよう

 あなたは、とある不動産会社に勤務しています。あなたの会社は数百の不動産を保有し、賃貸物件を顧客に貸し出しています。ある日、あなたの上司から、「物件の賃貸価格決定を自動化したい」と要望を受けました。さぁ、どうするか考えましょう。

フェーズA ビジネス課題分析

 今回のリクエストは「物件の賃貸価格決定を自動化したい」ですが、このリクエストにどういった背景があるかを考えたり、質問したりすることが重要です。上司や関係するメンバーへのヒアリングを行った結果、次のような背景があることがわかりました。

 現在、あなたの会社では、物件の賃貸価格を業界経験が豊富なメンバーが地域の相場などを調査した後、決定しています。このプロセスは安定しているのですが、新しい物件が加速度的に増えていること、賃貸価格を決定できるメンバーが限られていることから、作業が追いつかなくなっています。そこで、あなたの上司から「最近よく聞くAIで自動化ができるのではないか」というリクエストが来たとのことです。

 背景は整理できました。解決したい課題は「物件の賃貸価格決定プロセスの効率化」とも言い換えられそうです。

予測したい値は何か? どんなアクションに使えるか?

 「不動産の賃貸価格決定の自動化」を機械学習の世界に適用できるように考えてみます。今回のケースでは、機械学習の文脈では「物件の賃貸価格予測」と捉えられそうです。このとき「予測したい値」は「物件の賃貸価格」になりそうです。

 また、「この値を用いたアクション」を考えてみると、恐らく「業界経験が豊富なメンバー」がこの結果を見て最終確認をし、実際の家賃に反映されることになりそうです。そういったアクションを考えると、「純粋な予測結果」だけでなく、「どういった特徴量からこの結果が算出されたか」「どのくらいの精度か」も同時に示した方がよさそうです。

特徴量として何が使えるか

 あなたは会社のデータベース一覧を調べ、次の情報を使えることがわかりました。

  • いままでに管理していた物件情報とその賃貸価格

 今回はこのデータを用いて機械学習プロジェクトを進めましょう。

フェーズB データ分析、機械学習

 フェーズBでは次のような作業を行います。

  • データ収集
  • データ観察
  • 特徴量エンジニアリング
  • アルゴリズムの選定・評価方法の選定
  • 機械学習モデルの学習
  • 機械学習モデルを使った予測
  • 機械学習モデルの評価

データ収集

 まず、プロジェクトを始めるためにデータを収集していきましょう。

 フェーズAで使えることがわかった「いままでに管理していた物件情報とその賃貸価格」は会社のデータベースに保存されていることがわかりました。今回は手元にそのデータをダウンロードするという前提で進めましょう。

データ観察

 前のステップでダウンロードしたデータを観察していきましょう。このステップの目的は、いくつかありますが、一言でいえば、実際にどんなデータなのかを確認することです。

 pandasを使ってデータを読み込んでみましょう。全体のコードは書籍のリポジトリに公開していますので、そちらをご参照ください。

import pandas as pd
df = pd.read_csv("realestate_train.csv")
df.head()
データ観察

 各カラムは以下の内容を表しています。

  • rent_price:賃貸価格
  • house_area:広さ (m2)
  • year_from_built:築年数
  • distance:駅からの距離 (m)
  • built_date:建築日
  • balcony_area:ベランダの広さ (m2)
  • house_structure:建物の構造
  • floor:階数
  • total_floor:建物の階数

 予測したい値には、rent_price:賃貸価格を使います。

特徴量エンジニアリング

 ここで、特徴量エンジニアリングについて説明をしますが、その前に「特徴量とはそもそも何か?」について解説します。

特徴量とは

 特徴量とは、モデルがデータを学習や予測に利用する際に利用するデータのことです。次の図を使って説明します。

特徴量

 今回のケースでは予測したい値は物件の賃貸価格です。予測したい値に対して正解データを準備する必要があります。ここでは過去の物件の賃貸価格のデータが正解データになります。

 特徴量は物件の賃貸価格の予測に必要な情報、ここでは、例えば物件の広さや駅までの距離になります。機械学習モデルはこういった情報を基に予測したい値、ここでは物件の賃貸価格を予測します。人間に置き換えるとわかりやすいかもしれません。

 皆さんがある物件を見せられて「この物件の賃貸価格はいくらぐらいだと思う?」と聞かれた場面を想定してみてください。恐らく多くの人が「広さがこのくらいで、駅からの距離がこのくらいで、最寄り駅が◯◯だから……」というように考えるかと思います。

 機械学習モデルもかなり大雑把に書いてしまえば、同じようなプロセスで予測を行っています。機械学習モデルにとっては特徴量は「予測のために使われる唯一の情報」です。

 特徴量は機械学習モデルの精度を向上させる上で、非常に重要です。特徴量はいま書いたとおり「予測のために使われる唯一の情報」なので、よい特徴量を選択することで、モデルの予測精度が大きく向上する可能性があります。逆に、不適切な特徴量を用いると、いかに機械学習モデルに使われるアルゴリズムがよかったとしても精度の向上は見込めません。

特徴量エンジニアリングとは

 それでは特徴量エンジニアリングとは何でしょうか? 特徴量エンジニアリングとは、特徴量を生成することをいいます。いま例に出したのが物件の広さや駅までの距離だったので「生成する必要はあるのか?」と思われた方もいるかもしれません。特徴量には「元データをそのまま使う特徴量」と「元データを加工して生成する特徴量」の2種類が存在します。

 「元データをそのまま使う特徴量」はいま説明した物件の広さや駅からの距離です。一方「元データを加工して生成する特徴量」としては、「物件の過去1年間の賃貸価格の変動」や「建物構造」があります。「物件の過去1年間の賃貸価格の変動」は元データになく、元データをベースに加工して特徴量を生成する必要があります。建物構造は元データに存在しているのですが、「RC」「鉄骨」のようなカテゴリデータになっているため、機械学習モデルに入力できません。カテゴリデータは専用の加工方法があります。Section5-3で詳しく説明しています。

 ここでは、まずは機械学習プロジェクトの全体にフォーカスして理解してほしいので、「元データをそのまま使う特徴量」のみ使います。具体的には次の2つを使います。

  • house_area:広さ (m2)
  • distance:駅からの距離 (m)

アルゴリズムの選定・評価指標の選定

 今回は、実数値の予測をします。このようなケースでは回帰アルゴリズムを使うと覚えておきましょう。ほかの実数値予測の例は、店舗の売上予測、需要予測など多岐にわたります。機械学習プロジェクトに際しては、まずこの回帰アルゴリズムが適用できるか考えてみましょう。

 回帰アルゴリズムを適用するために、scikit-learnというライブラリを使います。本書では機械学習モデルの学習、予測に基本的にscikit-learnというライブラリを使います。scikit-learnは、Pythonの代表的な機械学習ライブラリの1つです。機械学習モデルを構築しようと思ったら、まずscikit-learnにないか確認してみてください。

 scikit-learnに興味があれば、一つひとつのアルゴリズムをscikit-learnのドキュメントで読 んでみてください。

 さて、scikit-learnを使って回帰アルゴリズムを実装してみましょう。しかし、回帰アルゴリズムと一口にいってもその種類は多岐にわたります。scikit-learnの教師あり学習のページを眺めて、さまざまなものがあることを確認してみてください。

 では、いまどのアルゴリズムを使えばよいか、という話をします。1つの正解はなく、ここで断言することは正直難しいのですが、個人的には最初はRidge Regressionを使うことをおすすめしています。理由はアルゴリズムや結果の解釈がしやすく、結果も安定することが多いからです。今回もRidge Regressionを使いたいと思います。

機械学習モデルの学習

 それではいよいよ学習に移りましょう。データはデータ観察ステップで読み込んだものを使います。

 まずは全体のコードを載せます。

# 1. Ridge Regressionモデルクラスの読み込み
from sklearn.linear_model import Ridge

# 2. 特徴量と正解データの設定

# 予測したい列(正解データ)
target_col = rent_price
# 使いたい特徴量
feature_cols = ['house_area', 'distance']
# dfはデータ観察で読み込んであります。
# モデルの学習を行うために「X: 特徴量」「y: 正解データ」に分割します
y = df[target_col]
X = df[feature_cols]

# 3. モデルの学習

# モデルの初期化
model = Ridge()
# モデルの学習
model.fit(X, y)

 ステップごとに解説します。

1. モデルクラスの読み込み

 最初にモデルクラスであるRidgeをscikit-learnからimportしています。ここでほかのアルゴリズムを使いたい場合は別のクラスを読み込みます。

# Ridge Regressionモデルの読み込み
from sklearn.linear_model import Ridge

2. 特徴量と正解データの設定

 機械学習アルゴリズムに学習させるときは基本的に、特徴量と正解データを別々に読み込ませる必要があります。正解データは家賃、特徴量はhouse_area:広さ (m2)とdistance:駅からの距離 (m)の2つを使います。一般的に、変数名は正解データや予測したい列をy、特徴量をXで表すことが多いです。

# 予測したい列(正解データ)
target_col = rent_price
# 使いたい特徴量
feature_cols =['house_area', 'distance']
# dfはデータ観察で読み込んであります。
y = df[target_col]
X = df[feature_cols]

3. モデルの学習

 さて、これで準備はできました。モデルの学習をします。コードを紹介します。

# モデルの初期化
model = Ridge()
# モデルの学習
model.fit(X, y)

 なんとこれだけで完了です。いま使っているscikit-learnを始めとして、一般的によく使われる機械学習ライブラリはこのようにうまく抽象化されており、簡単に学習を行うことができます。

 Ridgeクラスではパラメータを設定でき、上記の例では指定なしでデフォルト値が使われますが、次のようにパラメータを設定できます。

# パラメータ付きのモデルの初期化
model = Ridge(alpha=1.4)

 このパラメータをハイパーパラメータと呼びます。ハイパーパラメータは「どのように学習を行うか」を指定するために使います。なぜハイパーパラメータと呼ぶかというと、機械学習アルゴリズム内部で学習されるものはパラメータと呼ばれるのですが、このパラメータと区別するためです。「どのように学習を行うか」を指定するためのパラメータをハイパーパラメータと呼んでいます。

機械学習モデルの評価

 さて、学習したモデルの評価を行いましょう。評価をする、というのは簡単にいうと「このモデルで予測した結果がどのくらい当たっているのか計測する」ということです。評価をする一般的な方法は「学習したデータに対して予測を行い、正解と比較する」方法です。

 さて、学習したデータに対して予測を行ってみましょう。次のコードで予測を行うことができます。

# 学習したモデルを用いて予測を行う。
df["pred_rent_price"] = model.predict(X)
# 予測値と正解の値のみに絞って比較する。
df[["rent_price", "pred_rent_price"]].head()
コードで予測

 このpred_rent_priceカラムの数字が予測結果です。今回では予測された賃貸価格ということになります。10万円前後の物件が10万円前後で予測されていたり、20万円前後の物件が20万円前後で予測されていたりと大雑把には当たっていそうです。しかし、細かく見ていくと、例えば1行目を見ると本当の値が81000.0に対して予測結果が 93257.478559と約 12000円のずれが生じていることがわかります。

 このように1行1行見ていくのも1つの方法ですが、途方もなく時間がかかってしまうので、一般的にはさまざまな評価指標を用いて計算します。

 scikit-learnのmodel evaluationページを見ると一般的な評価指標の一覧を見ることができます。

 今回は評価指標としてMAE(Mean Absolute Error, 平均絶対値誤差)を用います。MAEとは、正解値と予測値の差の絶対値で平均を取ったものです。例えば、前述したように1行目では約12000円の差がありましたが、これを1行1行計算していき、その平均を取るような方法です。

 次のコードで計算できます。

from sklearn.metrics import mean_absolute_error
print(mean_absolute_error(df["rent_price"], df["pred_rent_price"]))
# => 17763.514918603825

評価指標は計算できましたが…

 MAEが17763なので、平均して正解値と予測値で17763円のずれがあることがわかりました。「この値はよいのか、悪いのか」と思われた方もいらっしゃるでしょう。申し訳ないのですが、この値に対する絶対的な「よい、悪い」という基準はありません。最終的には「この予測結果がどう使われるか」によって変わります。

 今回のケースを振り返ると「新しい物件の賃貸の価格決定を行いたい」というものでした。物件の賃貸価格を考えると、17763円のずれというのは大きな差に思えます。ここで選択肢が2つ考えられます。「1. 精度を許容範囲まで高める」「2. 人間のサポートを前提としてプロセスを構築する」という2つです。

 「2. 人間のサポートを前提としてプロセスを構築する」がどういうことかというと、例えば機械学習モデルの予測値はあくまで参考値として用い、そこから人間が微調整するという方法です。実際のプロジェクトでは「1. 精度を許容範囲まで高める」を時間や労力をかけて行うより、2を選んでしまった方が現実的なことも多々あります。

 少し話が脱線しましたが、精度の良し悪しを判定するにはどういった使い方をされるかによって異なります。フェーズA:ビジネス課題分析での結果を踏まえて検討するようにしてください。

未知のデータに対する精度:汎化性能

 今回は学習データに対して予測を行い、予測値と正解値を比較しました。実はこれはシンプルな方法ですが、正確な方法ではありません。というのも、学習データというのは機械学習モデルがすでに知っているデータなので、精度が高くなってしまうのです。これは「漢字ドリルで学習をして、同じ問題をもう1回解いている」状態に近いです。より高性能なモデルを構築するには「漢字ドリルで学習をして、全く別の問題を解く」という方法を採る必要があります。この未知のデータに対する精度がよいことを汎化性能といい、汎化性能を測定する手法をクロスバリデーションといいます。

機械学習モデルを使った予測

 あなたは機械学習モデルの評価を行い、ビジネス上の目的が達成できる精度を得られました。それでは実際に家賃がまだついていないデータに対して予測を行ってみましょう。リポジトリにデータを用意しているので、次のコードでデータを読み込んでください。

df_pred = pd.read_csv("realestate_pred.csv")
df_pred.head()
家賃がまだついていないデータに対して予測

 表のようにrent_priceがないデータになっています。

 さて、先ほど学習したモデルを使って予測を行ってみましょう。注意点としてはscikit-learnなどメジャーな機械学習ライブラリでは、学習済みのモデルには常に同じ順番で同じ特徴量を渡す必要があります。

 例えば、feature_colsは次のような順番でカラム名が入っています。先ほど学習したときもこの順番で入力しました。そのため、予測の際も同じ特徴量を同じ順番で渡す必要があります。ここは間違えやすいのでご注意ください。

feature_cols = ['house_area', 'distance']
# 注意: feature_cols = ['distance', 'house_area'] では間違った結果になる
# 使った特徴量だけに限定
X_pred = df_pred[feature_cols]
# 予測を行う
X_pred["pred_rent_price"] = model.predict(X_pred)
# 先頭を表示
df_pred.head()
予測の際も同じ特徴量を同じ順番で渡す

 はい、先ほど見たデータにpred_rent_priceカラムが追加されていることがわかります。この値がモデルで予測された値です。

 これで、機械学習アルゴリズムを使った予測を行うことができました。意外とあっさりと進んだのではないでしょうか。近年ではscikit-learnを始めとしてユーザーフレンドリーなライブラリが多く存在しているので、複雑なロジックの実装をする必要なく、機械学習を利用できます。

実務で役立つPython機械学習入門 課題解決のためのデータ分析の基礎

Amazon  SEshop  その他

 
実務で役立つPython機械学習入門
課題解決のためのデータ分析の基礎

著者:
発売日:2023年11月16日(木)
定価:3,300円(本体3,000円+税10%)

本書について

本書はPythonを利用して、実際の課題を機械学習で解決する手法を解説する書籍です。手を動かしながら、データ分析やアルゴリズムについて学ぶことができます。本書では「1.課題分析」「2.データ分析」「3.予測」の3ステップで課題解決を行っていきます。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
翔泳社の本連載記事一覧

もっと読む

この記事の著者

渡部 拓也(ワタナベ タクヤ)

 翔泳社マーケティング課。MarkeZine、CodeZine、EnterpriseZine、Biz/Zine、ほかにて翔泳社の本の紹介記事や著者インタビュー、たまにそれ以外も執筆しています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18632 2023/11/23 07:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング