今回は過去に実施されたSignateのアップル引越し需要予測に挑戦しました。
実際に投稿してみた結果、ランキング100位を切れました!
今回はそのノウハウを共有したいと思います。
※コードの公開は一応期限まではしません。方針だけ
アップル引越し需要予測について
コンペ概要
一言で説明すると、引越し件数の予測。詳しくは、コンペ詳細へ。
データ概要
用意されているファイルは以下の3つ
- 学習用データ
- 評価用データ
- 応募用サンプルファイル
そして気になる学習用データの中身は、
◆学習用データ(train.csv):2100行、2010年7月1日~2016年3月31日
データ項目 | 意味 | 変数種類 |
datetime | 日時(YYYY-MM-DD) | 文字列 |
y | 引越し数(これを予測したい) | 数値 |
client | 法人が絡む特殊な引越し日フラグ | 数値 |
close | 休業日 | 数値 |
price_am | 午前の料金区分(-1は欠損、0~5) | 数値 |
price_pm | 午後の料金区分(-1は欠損、0~5) | 数値 |
意外と使える変数が少ない!?
上記の2010年から2016年の6年分の時系列データを用いて評価用データにある1年分(2016年4月1日~2017年3月31日)の引越し数(y)を予測します。
モデル作成方針
攻め方
まずは特徴量エンジニアリングからモデリングまでの手法を簡単に説明します。
大きな流れは以下の通りです。
モデリングについては時系列モデリングと時系列を無視した木系モデリングを行い、後段でアンサンブルを行います。
データ加工・変換
以下を試しました。どうってことはないです。むしろ少なくてすみません。
- datetimeを文字列からタイムスタンプに変換
- どのカラムにも欠損はなかったので欠損処理はなし
- データの選定
⇒2012年東日本大震災があった年なので、引越しデータとして不安定なところを削除…
⇒したところ精度が下がったのでデータの選定はせず
特徴量追加
さて、ここからが特徴量エンジニアリングです。
- datetimeを分割して月、日付の項目をカラムとして追加
- 休日フラグの付与(土日、祝日)
- 曜日番号の付与(月:0、火:1、水:2、木:3、金:4、土:5、日:6)
- 六曜番号付与(先勝、友引、先負、仏滅、大安、赤口)
※六曜番号はただ単に周期的に付与されているわけでないことに提出後気が付いた 泣 - 料金区分に1足して午前、午後を掛け算。(price_am+1)*(price_pm+1)を追加
- 去年の同週同曜日を追加【2021/6/21追加】
以上です。引越しに影響しそうな習慣や行事を追加したいのですが、思いつかず…
木系モデリング
上記で作った特徴量をうまく使って、時系列を無視した形でモデリングを行います。
Light GBM Regressorを使います。モデリングの流れはちょっと複雑ですが以下の手順です。
複雑なのは評価の仕方ですね。Light GBM(LGBM)のパラメータはデフォルトのままです。
◆評価の仕方
- KFoldを使ってデータを何分割するかを決める(今回は5分割)
- 訓練データをランダムで訓練用(全体の4/5)、評価用(全体の1/5)に分割する
- 2.で分けた訓練用データを使ってモデリング、評価用データを使って評価
- LGBMはイテレーションを繰り返し学習し、最適なパラメータを使って実際のテストデータ(今回のターゲット)を予測実施
- 2~4は5回繰り返し行われるのでそれぞれ結果を保存し、最終的に平均を取る
KFoldは指定した回数分データを分ランダムで割してくれる優れものです。モデルの汎化性能を高める(=まだ見ぬテストデータに対しても精度が落ちないようにする)ために用います。
時系列モデリング
次に、時系列データとしての特徴を学習させるためにProphetを用いてモデリングします。
Prophetを用いるためには、データセットをdatetimeとyのみにします。
つまり時系列モデリングではその他の特徴量が使えないのです。
Prophetはやることがなく何も考えずにモデルをトレーニングさせ、予測します。
本当にやることがない。むしろ何をすれば良いのかわからない…
なので、せっかく用意されている特徴量が使えないのは非常にもったいないのでLight GBMを使って結果の平均を取ります。
アンサンブル
最後に大詰めです。アンサンブルを行います。
いろいろ試した結果、以下が最も精度良かったです。
- LGBM予測値 + (Prophetモデルの予測値平均値 – LGBMの予測値平均)
LGBMの予測結果だけではなんとなくトレンドが乗っていない気がしたのでProphetの平均との差分を足し合わせてみました。これが絶妙にスコアアップに繋がった。
※イメージ画像(緑の線が最終予測結果)
他に試したこと
- LGBM予測値単体
- Prophet予測値単体
- LGBMとProphetの平均(LGBMの予測値 + Prophetの予測値) / 2
まとめ
- 100位を切れたということで、まぁそれなりにデータサインエスできた?
- 時系列分析らしい特徴量を入れたい。移動平均とかトレンドとか
- 全国の平均気温とか、天気情報を入れたら精度上がるかな?
- しかし、もっと精度の上がるアンサンブルのやり方があったはず
- 時系列モデリングって理論とか使い方が鬼ムズだったけどProphetがめっちゃ楽。さすがFacebook
コメント