これは2023/3月に書いていたのですが、下書きのまま放置していたものです。
相当古い内容ではあるのですが、放置しっぱなしも(自分の精神的に)良くないなと思いましたので、備忘録として少しだけクリーンアップして投稿します。
なお、金融データ活用チャレンジも先日2回目が終了しました。そちらは参加登録だけして、活動できずに終わったのですが、次回があれば今度こそちゃんとやりたいと思っています。
参加していた以下のコンペが終了しましたので、最後のまとめを書いてみます。
今回は完全にコラムです。
まずは事務局の方、参加された皆様方、大変お疲れさまでした
初コンペということもあって右往左往している中、Slack上のやり取りは癒しでした。
ここからはコンペの結果や試みたことなどを、分析プロセスごとに書き残してみます。
結果
- 暫定評価:0.9860
- 最終評価:0.9878
ランクとしては45位でした。
初期目標が0.80以上だったので、それから考えれば思った以上に延ばせました。
ただ、最後1週間は0.99到達を目途に頑張っていたので、そこに至らなかったのは悔しいです。
やったこと詳細
基本プロセスは以下の内容から変わっていません。
いろいろ考えたのですが、結局学習は全てAutoMLでやりました。
以下、プロセスごとの詳細と反省点。
基本的な前処理と可視化
- #1記事を書いた時から特段の変化はありません
- ただ、今にして思えばもう少しEDAに時間かけてデータ理解を深めた方がよかったなと思っています。
特徴量エンジニアリング
- 最終的に作成した特徴量数は1600強(機械的な特徴量生成含む)
- もっとも暫定評価のよかったモデルは、そのうち650程度の特徴量を使用しました。
- 作成した特徴量を全部書くことはできませんが、
- ラグ特徴量(1か月前の値、2か月前の値、etc)
- 差分特徴量(当月値と1か月前の差分、etc)
- 変化率(当月値と1か月前の値の変化比、etc)
- 移動平均(過去Nか月期間の平均、etc)
のような機械的に生成できる特徴量や - 過去の滞納回数(全期間での対応有無、過去6か月以内の滞納有無、etc)
- 総入金金額・総出金金額
- 入金・出金の変動係数
のようなドメイン知識っぽい特徴量を入れていきました。
- 反省点は、中盤まで特徴量を追加するたびに毎回データの作り直しをしていたこと
- 特徴量が増える後半の際は、生成・保存処理だけで相当時間がかかっていた
- 結局、特徴量のカテゴリごとにテーブルを分けて管理するように変更。かなり時間をロスした
- Feature Storeを真面目に勉強して、それで管理するようにすればよかったなと反省
特徴量の選定と不均衡データの調整
特徴量選択
- 特徴量の選定は、SHAPの重要度を基に、影響度が小さいものをカットして、新たな特徴量を追加する方式で実施
- Wrapper MethodのStep backward方式ぽいやり方・・・かな?
- ただ、影響度が大きい特徴量を多く残しても必ずしもPublic LBが伸びるわけではなかったのもあって、今もどうしたらよかったのかわからず。。。
- 初学者の実力不足を実感。。。
- また、特徴量選択→AutoML→best modelのSHAP計算 というやり方をとっていたので試行時間が相当量発生
- これは素直にAutoML使わず、専用の処理を組めばよかったなと反省
- 結局、最後の方はカンと試行錯誤というアナログなやり方で特徴量選択を詰めていました。ここは大きな反省点。
- あと、チュートリアルに出ていたumapによる圧縮特徴量は後半手が回らず入れられませんでした。ここも反省点。
不均衡データの調整
- 結局、UndersamplingとOversamplingの組み合わせで不均衡調整
- 今回はラベルが負例のものが圧倒的多数。負例については、testデータのgid分だけに絞り、そこからgidごとに1~2件をランダムサンプリング。
- 負例はAdversarial Validationを使ってテストデータに近い分布のデータを選ぶこともしてみましたが、イマイチはまりませんでした
- やり方がよくなかったのだと思いますが、次回はもうちょっとやってみたい
- 正例はサンプリングした負例と同定度になるように単純にOversampling。
- 正例のOversamplingはSMOTE等も試したのですが、自分の場合スコアが伸びなかったので、結局一番シンプルな形に落ち着きました。
- 過学習のことを考えるとどうなんだろう?というのも気になったのですが、試行錯誤の結果やることに落ち着きました。
- 最終的には正例・負例共に5万件程度、計10万件程度のデータ量を学習データとしました。
- Undersampling部がランダム成分を含むため、乱数seedを変更して作り直しもしていました。
- 今回はラベルが負例のものが圧倒的多数。負例については、testデータのgid分だけに絞り、そこからgidごとに1~2件をランダムサンプリング。
- 反省点は、これも結局どういった調整の仕方がよかったのか、未だにわからないこと
- Topの方たちの内容見て勉強したいと思います
学習
- 提出する予測のモデルは、全てDatabricksのAutoMLを使用
- 途中、他のやり方も検討したのですが、結局初志貫徹しました
- 実務ではDatabircks AutoMLを使ってないこともあり、わからないことも多くあったので今回かなり勉強になりました
- 最終提出に使ったモデルはLightGBM
- 序盤からAutoMLにつかうフレームワークはXgboostとLightGBMに絞っていたのですが、終盤はLightGBM一本でした
- Xgboostもいいスコアを出す時があったのですが、LightGBMの方が後半安定してスコアを出していたため
- データ量制約が厳しい
- 今回のクラスタだと、特徴量650 x データ行10万件が今回AutoMLで回せるギリギリのデータ量。これ以上は自動でサンプリング
- そのため、特徴量を増やしづらく。。。
後処理-アンサンブル
- 順位でのブレンディング
- 単純平均やスタッキングも試しましたが、順位でのブレンディングが最もスコアを伸ばせました
- 最終提出したデータもブレンディングしたものです
今回きつかったこと
- クラスタ制約が一番きつかった
- クラスタが1基なので、AutoMLを回している間に他の事をするのがきつい
- 後半はずっとAutoMLを回しまくっていたので、時間の使い方に悩みました
- あと、クラスタ設定が変更できないので、sparkの環境設定とか諦めたところがありました。spark.task.cpusの設定とか
- メモリ制約も、特徴量が増大してきた後半は悩みの種でした
あと仕事が最後のほうにかなり忙しくなり、両立がマジできつかった
学びになったこと
- 全て
- とはいえ、次回参加するとしたら異なるアプローチで進めてみたいと考えています
まとめ
次はリベンジ!