【FDUA】第一回 金融データ活用チャレンジをやり終えた

:::note warn
これは2023/3月に書いていたのですが、下書きのまま放置していたものです。
相当古い内容ではあるのですが、放置しっぱなしも（自分の精神的に）良くないなと思いましたので、備忘録として少しだけクリーンアップして投稿します。

なお、金融データ活用チャレンジも先日2回目が終了しました。そちらは参加登録だけして、活動できずに終わったのですが、次回があれば今度こそちゃんとやりたいと思っています。
:::

<br>

参加していた以下のコンペが終了しましたので、最後のまとめを書いてみます。
今回は完全にコラムです。

https://signate.jp/competitions/841

# まずは事務局の方、参加された皆様方、大変お疲れさまでした

初コンペということもあって右往左往している中、Slack上のやり取りは癒しでした。
ここからはコンペの結果や試みたことなどを、分析プロセスごとに書き残してみます。

# 結果

- 暫定評価：0.9860
- 最終評価：0.9878

ランクとしては45位でした。

初期目標が0.80以上だったので、それから考えれば思った以上に延ばせました。
ただ、最後1週間は0.99到達を目途に頑張っていたので、そこに至らなかったのは悔しいです。

# やったこと詳細

基本プロセスは以下の内容から変わっていません。
いろいろ考えたのですが、結局学習は全てAutoMLでやりました。

https://qiita.com/isanakamishiro2/items/477fa0df6c5b69c77a1b

以下、プロセスごとの詳細と反省点。

## 基本的な前処理と可視化

- #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を変更して作り直しもしていました。
- 反省点は、これも結局どういった調整の仕方がよかったのか、未だにわからないこと
    - Topの方たちの内容見て勉強したいと思います

## 学習

- 提出する予測のモデルは、全てDatabricksのAutoMLを使用
    - 途中、他のやり方も検討したのですが、結局初志貫徹しました
    - 実務ではDatabircks AutoMLを使ってないこともあり、わからないことも多くあったので今回かなり勉強になりました
- 最終提出に使ったモデルはLightGBM
    - 序盤からAutoMLにつかうフレームワークはXgboostとLightGBMに絞っていたのですが、終盤はLightGBM一本でした
    - Xgboostもいいスコアを出す時があったのですが、LightGBMの方が後半安定してスコアを出していたため
- データ量制約が厳しい
    - 今回のクラスタだと、特徴量650 x データ行10万件が今回AutoMLで回せるギリギリのデータ量。これ以上は自動でサンプリング
    - そのため、特徴量を増やしづらく。。。

## 後処理-アンサンブル

- 順位でのブレンディング
    - 単純平均やスタッキングも試しましたが、順位でのブレンディングが最もスコアを伸ばせました
    - 最終提出したデータもブレンディングしたものです

# 今回きつかったこと

- クラスタ制約が一番きつかった
    - クラスタが1基なので、AutoMLを回している間に他の事をするのがきつい
    - 後半はずっとAutoMLを回しまくっていたので、時間の使い方に悩みました
    - あと、クラスタ設定が変更できないので、sparkの環境設定とか諦めたところがありました。spark.task.cpusの設定とか
    - メモリ制約も、特徴量が増大してきた後半は悩みの種でした
- ~~あと仕事が最後のほうにかなり忙しくなり、両立がマジできつかった~~

# 学びになったこと

- 全て
- とはいえ、次回参加するとしたら異なるアプローチで進めてみたいと考えています

# まとめ

次はリベンジ！