住宅価格を予測する〜Kaggle House Priceチュートリアルに挑む(その1)

住宅価格を予測する〜Kaggle House Priceチュートリアルに挑む(その1)

日増しに寒くなってきました。
街ゆく人々は厚手のコートにマフラーと本気で防寒し始めているわけですが、著者はダイエットのためにあえて薄着で過ごしております。

さて、Kaggleの回帰問題のチュートリアルである、住宅価格の予測(House Prices: Advanced Regression Techniques)に挑戦しました。

Kaggleには2つチュートリアルがあって、回帰問題はHouse Price、クラス分類問題はタイタニック号の乗客の生存予測(Titanic: Machine Learning from Disaster)になります。


ちなみにTitanic tutorialは当ブログでも既に数回とりあげています。

このチュートリアルの目的はいたって簡単で、与えられた79もの変数(敷地面積とか天井の高さとか)をもとに住宅価格を予測するだけです。

今回は程々にデータを前処理し、なんとなく線形回帰モデルを構築してKaggleに予測結果を提出するまでを説明します。
ちなみにスコアは0.13110(4,748人中1,807位)で初めて挑んだにしてはなかなか良い成績でした^^

以下、Pythonのver3.7で実行しています。

ライブラリの準備

今回使用するライブラリをインポートします。
input:

前処理

データの取り込み

KaggleのHouse Priceのページからデータをダウンロードし、読み込みます。
学習データとテストデータをまとめて前処理するために、フラグをつけた上でマージしています。
input:

output:

説明変数として関係がない、Id、SalePrice、WhatIsDataを除いて79もの変数があります。
扱う変数がかなり多く、一つずつ確認するのはかなり時間的にも精神的にも厳しいものです。
なので、以降では詳細な変数の説明はせず、最低限予測モデル構築に必要な処理をするにとどめます。

欠損値の補完

まず学習データとテストデータの欠損の有無を調べます。
input:

output:

input:

output:

また、欠損している変数が数値型なのかカテゴリカル変数なのかを把握するために、データ型も確認しておきます。
input:

output:

学習データ、テストデータともにかなり欠損しています。
こういうときはパパッと欠損が多いカラムは削除してしまいたくなります。
ですが、その前に変数について詳しく説明しているドキュメントがKaggleにあげられているので、まずはそれを見てみましょう。
Kaggleからデータをダウンロードすると、「data_description.txt」というファイルも含まれていることに気がつきます。このファイルには、変数にどんなデータが格納されているのかが詳しく説明されています。
すると、大多数の欠損は情報がないことを意味するのではなく、欠損そのものが情報であることがわかります。
たとえば、最も欠損が多い、PoolQC(プールのクオリティ)をみてみましょう。
この変数の欠損はプールが住宅に存在しないことを意味しており、データの欠損そのものが情報となっています。
そのほかの変数(カテゴリカル変数)についても、欠損はその施設や設備が存在しないことを意味しているだけなのです。
また、数値型の変数についても、欠損は占有面積がゼロであることを意味しているだけであって、情報がないわけではありません。
したがって、カテゴリカル変数、数値型変数の欠損には以下の補完を行います。

  • カテゴリカル変数の欠損:欠損を示す文字列’NA’を補完
  • 数値型変数の欠損:0.0を補完

input:

マージデータの欠損を確認し、全て補完されていることを確認します。
input:

output:

全ての欠損値が補完されていることを確認できました。

カテゴリカル変数をダミー化

機械学習の定石通り、カテゴリカル変数をダミー化します。
本来はEDAでカテゴリカル変数についてもSalePriceとの関係性を探るべきですが、今回は飛ばします。
input:

目的変数の分布変換

学習データのSalePrice(住宅価格)の分布を確認します。
欠損補完の箇所で、プールがない住宅がほとんどであることがわかりました。
これは裏を返せばプールがあるような豪邸がいくつか存在するということであり、住宅価格がかなり歪な分布になっているのでは?と想定されます。
input:


予想どおり、かなり右側に分布の裾野が広がっています。
対数変換をすることで正規分布に近づけます。
input:


SalePrice(住宅価格)の分布が正規分布ライクになりました。
学習データの教師データにはこの対数変換後のSalePriceを用いることにします。

予測モデルの構築

今回は変数量がかなり多いため、係数に強力なペナルティをかけたいのでLasso回帰を使って予測モデルを構築します。
まず、学習データとテストデータにマージデータを分割します。
input:

基本的には数値変数に対しては標準化を施したうえでLasso回帰モデルを学習させます。
pipelineを使ってお手軽に前処理を施し、最適なLassoパラメータを探していきます。
input:

output:

Lassoのパラメータα=0.01のときに汎化性能が0.18になることがわかりました。
ちなみに汎化性能は予測結果および教師データに自然対数をかけたものに対し、RMSE(root mean square error)を使って算出しています。
今回はこの予測モデルを使ってKaggleに提出します。

モデルの検証

学習したモデルが実際に教師データにどれくらい近似できているのかを検証してみます。
横軸が教師データ、縦軸が予測結果としてデータを散布します。
input:

output:

左が学習データ、右がテストデータになります。
学習データに対してはそこそこフィットしてますが、テストデータにはフィットしていないようです。
外れ値、過学習、特徴量エンジニアリング不足などなど課題は山積ですが、いったん先へ進みます。

予測結果の提出

最後に学習データ全体を使って予測モデルを再構築して予測結果を出力します。
ここで予測結果のSalePrice(住宅価格)は対数をとった値なので、最終的にはexponentialをかけてあげる必要があります。
input:

提出できました!