Kaggle ASHRAEコンペ 上位解法まとめ・振り返り

f:id:sukekiyo_DS:20191230201954p:plain

 kaggle その2 Advent Calendar 2019の19日目の記事です。
 (空いていたのでお邪魔させて頂きます。)

 Kaggleで開催された ASHRAE - Great Energy Predictor III についてまとめます。いろいろと荒れたコンペではありましたが、時系列データの取り扱いに関する勉強としてまとめておきます。

 なお、私の結果は約3500チーム中290位(銅圏内)→2053位と大シェイクダウンでした。クソ雑魚ソリューションではありますが自身の振り返りのために最後に記載します。ご意見やマサカリ等頂けると嬉しいです。

コンペの概要

  • ASHRAE(アメリカ暖房冷凍空調学会)がホストであり、2016年に使用した電力(電気,冷水,蒸気,お湯)と気候のデータから、2017年~2018年に使用する電力を予測する問題
  • Timestampは1時間毎。約1500の建物に対して、それぞれ予測する
  • 建物にはそれぞれsite_id(全16サイト)がついており、気象データはsite_id毎に与えられる
  • 評価指標はRoot Mean Squared Logarithmic Error
  • 施策の効果の検証に使うのがコンペの目的らしい。 (施策を行わなかった場合を機械学習で推測し、比較対象に用いる)
  • 欠損や外れ値が多く、かなりノイジーなデータセット。同じサイト(=同じ気候)でもbuilding_idによって挙動が異なるように見える
    f:id:sukekiyo_DS:20191230201222p:plain
    https://www.kaggle.com/nroman/eda-for-ashrae より

データリーク

  • コンペの途中で、全16のsite_idのうち、5つのsiteにあるbuilding_idの電力のデータがweb上に存在することが判明

    • 運営は「リークがあった5サイトはprivateには含めない」と発表したものの、データセットの変更等は行いませんでした

    • このリークに失望し、コンペから撤退する人も多かったようです

  • しかし、有志によりリークがまとめられたため、既知のデータセットとしてコンペを進めることが可能だった

    • そのため、本質的ではないパズルやスクレイピング技術を競うコンペとはなりませんでした

    • リークをまとめあげたIsamu Yamashitaさんがずっと金圏内にいたため、もう他のリークはないと考えて進めることができました(しかも結果的にYamashitaさんが優勝!本当にすごい。)

 個人的には2016年のデータのみでは手掛かりが少なすぎたので、ヒントが与えられてむしろやりやすくなったのでは?と思っていました。
 (とはいえ、運営にはリークしたデータを正式にまとめたり、コンペの途中でLBからリークの結果を取り除いたりといった対応はして欲しかったですが。。。あとコンペ終了後もprivateLBがなかなか公開されなかったのもキツかったです。)

有用だった公開カーネル

上位 Solution

年末年始のためか、まだあまり多くのソリューションは公開されていません…。
この章は随時更新していく予定です。

Public 1st place solution (private 497th)

https://www.kaggle.com/c/ashrae-energy-prediction/discussion/122796

まずはshake downしてしまいましたが、publicLBで1位だった方のソリューション

  • Feature Engineering and Feature Selection
    • 18特徴量のみ。いろいろと試したが効かなかった
    • dew_temperatureについて、feature importanceが高かったが取り除いた方がCVが良くなった。(air temperatureが重要でdew_temperatureは悪影響を与えているのでは?)
    • siteidand_meterといったCategorical Multiplicationが少しだけ効いた
  • Validation Strategy
    • 1~6月・7~12月をtrain, validに分割(half-and-half kernel と同等)
  • outlier removal (最重要ポイント)
    • 時系列にプロットしてデータをよく観察して、100以上のルールを作って外れ値を除去。
    • Examples of effective rules: “Meter 0 and long 0 segment”/”Meter 2 and start before April and long 0 segment”/”0 segments in many building at the same time”/”day average is too small in January comparing with December”.
  • Single Model
    • LightGBMのみ。Catboostやtime-series basedなモデルも試したが、良くなかった
  • Ensemble
    • 32個のLightGBM (4random seed)
      • 2 -> [1-6] train model or [7-12] train model (important)
        4 -> 4 random seed average (effective)
        2 -> Remove all suspicious outlier or remove only obvious outlier (slightly effective)
        2 -> Modify site0 electric units or not (almost no effects)
    • 各モデルの重みづけが重要であった
      • 基本的に、1-6月modelよりも7-12月modelのほうが重みを大きくする。(7~12月の方がtestデータに近い時期のデータだから)
      • 7~12月のtestデータを予測するときは、7-12月modelの重みを大きくする
      • trainデータの7~12月で外れ値が多い場合は、1-6月modelの重みを大きくする
  • Post Process
    • サブミットする前に時系列プロットし、後処理を検討
    • piecewise linear function(区分線形関数)を用いて最小値を修正?(ここあまりわかりませんでした…)
  • Leak
    • サブミット前にリークデータを置換
    • 学習データには使わない (アンサンブルの重みづけの最適化には使っている?)

2nd place solution

https://www.kaggle.com/c/ashrae-energy-prediction/discussion/123481

img

  • Preprocessing
    • 1449 buildingをすべてマニュアルで確認して外れ値除去
  • Feature Engineering
    • データセットが重かったことやロバストなバリデーション戦略の難しさから、ほとんどFeature engineeringを行わなかった。(約50特徴量)
    • その代わりにモデルをたくさん作り、アンサンブルさせることに力を注いだ
  • Modeling
    • XGB, LightGBM, Catboost, FFNN(Feed forward Neural Network)を使用。(FFNNは一部のみ)
    • 各site+meter毎、各build+meter毎、各building_type+meter毎等を試した結果、各site毎に学習させるのが良いと判断。
    • 4-fold CV と 5fold CVの組み合わせ?でチューニング(よく分からなかった)
  • Post Processing
  • Ensemble
    • meter = 0: 30% XGB-bagging + 50% LGBM-bagging + 15% CB-bagging + 5% FFNN
      meters 1, 2, 3: 30% XGB-bagging + 50% LGBM-bagging + 20% CB-bagging
    • CVスコア, LV, Leakスコアのそれぞれを見て重みを判断
  • Leak
    • サブミット時の置換のみ

9th place solution

https://www.kaggle.com/c/ashrae-energy-prediction/discussion/123525

  • CVスコアとHold outとLBスコアの相関が取れるようにすることに力を注いだ
  • LightGBM (x7), CatBoost (x4), Neural Network (x4), LiteMORT (x1)のアンサンブル
  • 特徴量はシンプルなもののみ。(最高でも15個。平均で12個)
  • Cleansingや気象データの補間は重要だった

My solution (297th → 2053th)

 ここからは私のクソ雑魚ソリューションです。
 本格的に取り組み始めたのはコンペの締め切りの約3週間前からでした。この頃にはリークはほぼ公開されて落ち着いており、センサデータの取り扱いには興味があったのでshake覚悟で参加することにしました。

基本戦略

  • ASHRAE- KFold LightGBM - without leak (1.08)カーネルを修正していく形でスタート

  • サブミット時にはすべてのリークデータ(site_id=0,1,2,4,15)を置換して提出

    • リークしたサイトはprivateには使わないと公式に発表されていたので、それならば固定した方がリークしていないサイトの評価がしやすいと考えていた

    • site_id=4は使わない方がLBが高くなる?という説もあったが、全部使っていた

  • リークしたサイトのデータ(2017~2018)は学習データに加えた

  • また、リークしたサイトはtrainのみに用い、validにはリークしていないサイトのみを用いた。(リークしていないサイトに最適化させたかった)

  • 特徴量は基本的なもののみ。lag featureやcount encoding, target encoding等も試したが、私の手元ではCVが改善しなかったので使わなかった

CVの切り方

  • 基本的にはKernelやDiscussionで議論されていた通り、2foldを検討
  • リークしたデータをプロットすると、1年を通したトレンドがありそう

f:id:sukekiyo_DS:20191230201353p:plain

そこで、Train・Validに使うデータをずらして学習させた(下図のイメージ)

f:id:sukekiyo_DS:20191230201505p:plain:w500

 (「時系列は未来の情報を使うべきでない」と基本的に言われていますが、月(=季節)の情報の方が重要と考えていました。あまりよくなかったかもしれない。)

  • CVの切り方とスコアは以下の通り f:id:sukekiyo_DS:20191230201540p:plain

  • この6モデルをCVスコアの重み付き平均でアンサンブルしたところ、CV: 0.8763, LB: 0.988

  • 上から3モデルでのアンサンブルではCV: 0.8673, LB: 0.980 という結果に

    • 切り方によってCVスコアが大きく異なるのは、2つのfoldで季節性が似ているか似ていないかが影響していたと思われる。(下図左のように2つのfoldで特徴が異なると精度が低く、 特徴が近いと精度が高くなるはず) f:id:sukekiyo_DS:20191230201609p:plain
  • この後、seed average(x10)してベスト公開カーネルと平均をとり、LB: 0.965(銅圏内)に到達。このモデルを最終提出していればprivateでも銅メダルを獲得していました。 画像

敗因:pseudo labeling

少し前に「回帰問題でもpseudo labelingが効く」とTwitterで話題になっており(たしかatma cupの時だったと思います)、気になって本コンペでも実装しました。

  • pseudo labelingとは、1度予測した結果をtestデータの「疑似的なラベル」とし、trainと一緒に学習させる方法。koshian先生のQiita記事が詳しい。よく「Data Augmentation」の一種として使われると誤解されがちですが、どちらかというと「正則化」の一種らしい
  • 実際には疑似ラベルの丸暗記を防ぐために、
    • 2017のpseudo label + train(2-fold) → 2018のtestを推論
    • 2018のpseudo label + train(2-fold) → 2017のtestを推論
      というように学習・推論させた
  • スコアは以下 f:id:sukekiyo_DS:20191230201703p:plain

  • これをベストカーネルとアンサンブルしたところ、LB: 0.964と0.001改善。CVもLBも良くなったことから、「pseudo labeling最高やん!」と思っていました。

  • (今思えばCV良くなりすぎ?その割にはLB変わってなさすぎ?と疑うべきだったのか…)

最終サブ選択

  • ベストカーネルはLeak部分の精度が高くなるように重みづけしてアンサンブルする方法を用いており、個人的にはリークのサイトにoverfitする可能性高いのでは?と考えていました
  • よって、2つ目のサブミットはpseudo labelingを用いてベストカーネルとアンサンブルを取らないもの(LB: 0.979)を選択

結果

  • めちゃめちゃshake downしました。普通にちょっと泣きそうになるよね。
  • ただ、自分の今のレベルをある程度知ることができたので、参加したことに後悔はありません
  • 上位陣はやはりデータをよく観察しているなと思いました。なにかすごい欠損処理をしているんだろうなと思っていましたが、手作業で削除しているチームも多かったのが意外でした
  • 銀圏内にタッチするにはアンサンブル前提でより様々なモデルを作る必要があると思いました

最後に

ここで直近行われたセンサデータを用いたコンペを見てみましょう。

いやいや、難しすぎじゃないですか。。。
しかし強い人は強いんですよね。これらの複数で上位に入っている方もいますし、結局実力なんでしょうか…。