Recruit Data Blog

  • はてなブックマーク

目次

はじめに

こんにちは、新卒2年目の高橋です。

今回は、2022年8月下旬に終了したkaggleの American Express - Default Prediction というコンペティションに参加して得られた知見を紹介します。扱うデータがテーブル形式のものだったこともあり、普段の業務に活かしやすい知見が多かった印象です。最後までご覧いただけますと幸いです。

コンペティションの紹介

馴染みのある方も多いと思うのですが、クレジットカードで有名なアメリカン・エキスプレスが主催したコンペティションになります。タスク内容は、クレジットカードを利用しているユーザーが将来的に債務不履行になってしまうかどうかを分類する(2値分類)というシンプルなもので、参加者がかなり多かったです。(4875チーム)

データについても簡単に紹介します。今回は、kaggleのノートブック上で推論を行う必要がないタイプのコンペティションでtestデータも公開されていました。特筆するべき点は、大きく分けて2つあります。

  • 1つ目は、顧客ごとに複数(最大で13レコード)のレコードを持つログ形式のデータで、顧客数もtrainデータでは46万程度、testデータでは倍の92万程度とかなり多かったため、train・testデータ合わせて50GB近い大規模データであったこと
  • 2つ目は、特徴量が支払いに関するもの・残高に関するものといったレベルで匿名化されていたこと

これらの性質は、データを扱う上でなかなか苦労することも多いと思いますが、その分公開ノートブックやディスカッションでメモリ使用量を抑えるための知見や特徴量のEDA・リバースエンジニアリングが沢山共有されていて勉強になることが多かったです。中にはデータ量を10分の1に抑える知見もあり、とても参考になりました。

得られた知見について

データ量の削減

先ほど述べたように、提供されたデータは全体で50GBと巨大なものだったのですが、データ量を削減する Tips やそれらを適用した データセット が比較的早い段階で共有されていました。データ量を削減するために、intやfloatの精度を情報を落とさない範囲で落とすというのはよくやられていると思うのですが、floatの特徴量が実はrandomなノイズが乗せられているだけでそれを取り除くと整数で表せるのでint化できるなどデータの分布をしっかり確認して取り組む重要性を学ぶことができました。( notebook

データ量の削減自体は、メモリ使用量を意識しない普段の実験などでついつい後回しにしがちなのですが、50GBのデータが最終的に5GBで扱えるようになったのを目の当たりにして、重要性を再認識したので、今後は意識的に取り組んでいきたいです。

Meta-features

こちらは、コンペティション終了後に上位解法を読んでいて、やるべきだったなと強く思った特徴量作成の方法です。Meta-featuresとは、主にログデータに対して、全てのレコードにtargetを付与し、それを学習させたモデルのOut Of Fold(データをいくつかに分割して学習・検証する際に学習データに含まれないレコードのこと。以下、OOFとします。)に対する予測値を使って特徴を作る手法です。存在自体は 2019 Data Science Bowlの2位解法 で知っていたのですが、理解が甘く自分の手札にできていませんでした。なので、以下では自分の理解を深める意味も込めて、どのように今回のコンペティションで使用するべきだったのかを整理してみました。

ステップ1:目的変数を作成する

それぞれのcustomer_IDのレコードに対して、同じtargetの値を付与することで目的変数を作成します。customer_IDがAの顧客のtargetが0であれば、customer_IDがAである全てのレコードに対して0を目的変数とします。

ステップ2:適切なデータ分割を行い、モデルを学習する

このステップでは、作成した目的変数を予測するモデルを学習します。ここで注意が必要なのは、学習データには同じcustomer_IDのレコードが多数存在しているという点です。モデルを学習する際には、学習データと検証データに分けると思うのですが、正しく評価を行うために分割の際には同じcustomer_IDのデータが学習・検証データにばらけないようにするべきです。これは GroupKFold と呼ばれるもので、今回のコンペティションではさらに学習・検証データでtargetの0,1の割合が同じになるように分割するのがベストだったと思います。実装に関しては、1位の方が コード を公開されているので、そちらを参考にしていただくのがおすすめです。

ステップ3:trainデータに対してはOOFで、testデータに対しては全てのモデルの予測値の平均でベースとなる値を作成する

このステップでは、学習したモデルを用いて予測値を作成します。例として、モデルの学習時に5foldの分割を行なっていた場合を考えると、5つの学習・検証データの組み合わせとモデルができていると思います。ここで、それぞれのモデルで学習に用いなかったデータ(OOFつまり、検証データ)に対して予測を行うとtrainデータ全体に対する予測値が得られます。testデータに対しては、どのモデルも学習に用いていないので、全てのモデルで予測を行い、その予測の平均値を用いるのが一般的だと思います。(1位の コード でもこの方法が採用されていました)

ステップ4:顧客単位で集約を行い、特徴量として用いる

最後に、作成した予測値に対して平均を取ったりして顧客単位で集約することで、今回のコンペティションの場合だと他の特徴量と同じように扱うことができます。集約する際には、他の特徴量でも用いられていたテクニックなのですが、履歴を全て用いて集約するだけでなく、最新のものを例えば3つだけ抽出して集約することでバリエーションを増やすというのも効果的だったようです。( こちらのコメントのコード が参考になります)

理解を深めるにあたって、こちらの ディスカッション がとても参考になりました。この手法の強みは存在する履歴を最大限活用できる部分にあると思うので、ログデータを使って最終的にどうなったかを予測するようなタスク全般に応用できそうだと思いました。

特徴量選択

コンペティション期間中に公開されたノートブックでは、提供された匿名特徴量のmean,max,min,lastなど様々な集約方法で特徴量エンジニアリングを行っていたため特徴量の数が多くなりがちでした。もちろん、マシンリソースに余裕があれば作成した特徴量全てで学習しても良いのですが、場合によっては過学習につながったり計算時間が長くなりがちだったりするので、不要な特徴量は削るということが重要になってきます。上位解法を一通り読んだ感じ、どの手法が絶対に優れているというのは言えなさそうだったのですが、いくつか紹介します。

Permutation importance

重要度を知りたい特徴量の値を意図的にシャッフルして使えない状態にした際に、どれくらいシャッフル前と比較して予測精度が下がるかという観点で評価する手法。正確な結果を得るためには、一回だけではなく複数回行う必要があるため、全ての特徴量に対して行おうとするとかなり時間かかってしまうという点がデメリットとして存在します。しかし、この点は 14位の解法 によると、RAPIDSの cuml.ForestInference を活用することで高速に行えるとのことなので、今度試してみたいと思いました。

Null importance

Permutation importanceでは特徴量の値をシャッフルしていましたが、Null importanceでは目的変数の値をシャッフルします。シャッフルするのは目的変数のみでいいので、複数回行う際に計算コストが低く済みます。目的変数をシャッフルした状態の重要度をシャッフル前の重要度と比較することで、その差分が小さければ目的変数の予測にあまり寄与しないノイズに近いものと判断する手法です。 11位の解法 では、シャッフル前の重要度がシャッフル後の重要度の平均以上である特徴量を残すことで4300個から1300個に減らすことができたと紹介されていました。

その他にも、 2位の解法 で色々試して最終的にいくつかの手法を組み合わせた結果がうまくいったということが書かれていたり、Adversarial validationを応用してtrainデータとtestデータ(今回はpublic,privateのデータが分離可能だったため主にprivate)で分布が異なる特徴量を除外するというアイデアが紹介されていました。Adversarial validationを用いた特徴量選択は こちらの記事 に詳しくまとめられています。

Transformerの活用

コンペティションの序盤からLGBMなどのGBDT系のモデルの精度が高いことが明らかになっていて、最終的な解法でもLGBMをboosting=‘dart’で学習したモデルがメインでした。Transformerは単体だとGBDT系ほど精度が出なかったのですが、LGBMのOOFを活用するなどして精度を高めてアンサンブルすることで、GBDT系のみのチームと差をつけることができていた印象です。ここでは印象的だった2つのアプローチを紹介します。

LGBMで使用している特徴量を再現するように事前学習

LGBMで使用していた集約系の特徴量などが強力だということがわかっていたので、元のログ形式の特徴量の系列をTransformerの入力として、LGBMで使っている特徴量に近い出力を得られるように事前学習を行うことで精度が向上したとのことです。事前学習の際には、trainデータにしか存在しない目的変数は使用しないので、testデータも用いることができ、testデータの傾向の学習も可能になっているようです。加えて、大量のデータを事前学習で使用することができるのでモデルのサイズを大きくすることが可能で、6層のTransformerを使用したとのことでした。

alt text
5位の解法から引用

詳細は こちら

LGBMの出力を用いた知識蒸留

こちらの解法では、LGBMの出力に近いものをTransformerで再現できるようにすること(知識蒸留)を目指していました。この解法でも、LGBMのOOFとtestデータに対する予測値を学習に用いることで、testデータの傾向の学習とモデルのサイズを大きくした(こちらは4層)学習に成功していました。以下の画像のように使用しているモデルは、LGBMとその出力を知識蒸留したTransformerのみなのですが、アンサンブルを行うことで元のLGBMのスコアを上回ることができているのが印象的でした。

alt text
14位の解法から引用

詳細は こちら

おわりに

今回は、kaggleのAmerican Express - Default Predictionというコンペティションに参加して得られた知見を紹介させていただきました。データがテーブル形式だったこともあり、参加人数も多く、沢山の有用な知見が共有されていたと思います。今回ご紹介できなかったことも沢山あるので、興味を持たれた方はぜひ他のディスカッションも読んでみてください。( 10位の解法 では自己回帰RNNを用いてログが少ない顧客のデータを生成していたりとユニークな解法もありました。)

最後までご覧いただきありがとうございました。

参考:

Kaggleで勝つデータ分析の技術
https://gihyo.jp/book/2019/978-4-297-10843-4

高橋寛武

Airペイ、Airレジなどを扱うSaaS領域でモデル作成やデータ分析を担当

高橋寛武

新卒2年目のkaggle master(自然言語処理のコンペティションが得意)