【コンペ振り返り】第1回金融データ活用チャレンジ

SIGNATEで2023年1月から3月まで開催されていた金融データ活用チャレンジの振り返ります。

リアルタイム開催のコンペの参加はこれが初めてだったので、初心者ですがご容赦ください

コンペ中にも記事を書いたので、僕の苦難や挑戦を知りたい方はこちらも併せてどうぞ。

https://qiita.com/mohki7/items/ea9961484d562a62b9a6

# 自己紹介
慶應義塾大学理工学部管理工学科4年生。大学では統計やAI、数理最適化、金融工学、IE、プロジェクトマネジメント、経済などを幅広く理系的な視点から学んでいる。まあ、データサイエンスとは距離が比較的近い学部だと思う。

Twitterはこちら→[@A7_data](http://twitter.com/A7_data "my twitter")
<dl>
  <dt>2022年1月</dt>
  <dd>統計の勉強を本格的に開始</dd>
  <dt>2022年4月6日　</dt>
  <dd>統計検定2級合格（優秀成績賞)</dd>
<dt>2022年6月</dt>
  <dd><a href="https://codegym.jp/academy">CODEGYM ACADEMY</a>参加。<a href="https://cs50.jp/">CS50</a>などの講義を通し、Flaskでアプリを個人開発</dd>
<dt>2022年6月14日</dt>
  <dd>データサイエンティスト検定リテラシーレベル合格</dd>
<dt>2022年8月24日</dt>
  <dd>統計検定準1級不合格</dd>
<dt>2022年9月14日</dt>
  <dd>統計検定準1級合格（最優秀成績賞)</dd>
<dt>2022年9月30日</dt>
  <dd>簿記3級合格</dd>
<dt>それ以降</dt>
  <dd>機械学習を中心に勉強中。理論を勉強しながらSIGNATEやKaggleをちょこちょこ。深層学習にも手を出してる</dd>
<dt>2022年12月</dt>
  <dd>SIGNATE Intermediateに昇格</dd>
  <dd>Kaggle Contributerに昇格</dd>
<dt>2022年12月</dt>
  <dd><a href='https://twitter.com/DSL_Tw'>データ分析特化型学生団体DSL　
@Data_Science_League</a>に加入。日々勉強中。</dd>
<dt>2023年1月</dt>
  <dd>SIGNATE 第一回金融データ活用チャレンジ参加中</dd>

</dl>

SIGNATEは現在(2023/2/19)Intermediateで、メダル獲得を目標に奮闘中

# コンペの概要
コンペページはこちら

https://signate.jp/competitions/841

## コンペの内容
【目標】
ある住宅ローン契約者が、3ヶ月後に連続して延滞するかどうかを予測する

【データ】
・金融機関での実務データに近い人工的データ
・顧客の属性情報や銀行の口座の情報などの金融データから予測
・__訓練データが2年分ほどあり、テストデータは訓練データの翌月__
・各ユーザーごと、月毎に上記データが与えられており、途中で延滞フラグが1になった人はそれ以降データは存在しない
    →したがって、テストデータはテストデータの月まで延滞しなかった人だけが残っており、その中でその月に延滞する人を予測する

【評価指標】
・AUC

【その他特徴】
・Databricks環境内で全てのプログラムを実行する必要があり、外部データの利用、内部データの持ち出しは禁止
・不均衡データ
・チュートリアルファイルがとても優秀で、チュートリアルをこなすだけでスコア0.89ほどを出せる

言葉で説明するのむず。笑
詳しくはコンペページをご覧ください笑

## コンペの投稿者数など
参加者は1600人越え、投稿は12000件越えだった。

SIGNATEで1000人を超える参加者はかなり多い（過去2番目）らしいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179677/64824093-73bb-05fa-bf7d-32014c2717d2.png)

# 自分の結果
一言で言えば、全然良くなかった。初めてのコンペ参加だったとはいえ、もっとやれたはずだと思ってます。。。

## 最終スコア・結果
最終スコア：0.9426342
最終順位：198位
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179677/aa2937d0-e46a-17b9-a355-14fb940e6c79.png)

これよりも最終的に高くなったスコアもありましたが、提出しなかったので提出した中ではこれが最高点です。
期間中はずっと0.94の壁を越えられず苦しんでいたので、最終スコアで越えられたのは少し嬉しかった。。？

## 自分の大まかな作戦
時系列のテーブルデータであり、チュートリアルもLightGBMを使っていたので、LightGBMのゴリ押しで行こうと思っていました。

そして基本的には「__有効な特徴量の生成__ → __アンサンブル__ → __パラメータチューニング__」を予定していました。
### 前処理/データ整形
今回のデータは特徴量の数が46個あり、そのうち欠損値を含むものは10個ほどで、さらにその特徴量も、「なぜ欠損になっているのか」がわかりやすいものだったし、データは全て数値だったので、表記揺らぎもなく、前処理やデータ整形は楽な印象でした。

でももしかしたら、前処理の必要性を低く見せておいて、実はゴリゴリに必要なものだったのかもしれない・・・

不均衡データの処理は、データにあった延滞する人としない人の比率が1:3.6とかだったので、その比率を守るようにtarget_flag=1とtarget_flag=0をピックアップして学習してました。

そのままで学習するよりスコアは良かったので、ひとまず良かったですが、正しいかはわからなかったです。。

### 特徴量生成に重きを置いた
我らがKaggle本に、「アンサンブルやハイパーパラメータチューニングよりも有効な特徴量を見つけた方がスコアを上げるコスパはいい」と書いてあった（気がする）ので、基本的に特徴量生成を進める方針にした。


https://amzn.to/3ZWberw
<a href="https://www.amazon.co.jp/Kaggle%E3%81%A7%E5%8B%9D%E3%81%A4%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E6%8A%80%E8%A1%93-%E9%96%80%E8%84%87-%E5%A4%A7%E8%BC%94/dp/4297108437?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=16EWA3V16PCTI&keywords=kaggle&qid=1678373530&sprefix=kaggle%2Caps%2C188&sr=8-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExS0xYUlpRSVZDVVM1JmVuY3J5cHRlZElkPUEwNDIyODAwWVRaWDVITVhXUlhFJmVuY3J5cHRlZEFkSWQ9QTJQNVRFOFYyMDVZRzcmd2lkZ2V0TmFtZT1zcF9hdGYmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl&linkCode=li3&tag=joshikiblog-22&linkId=c6988ab3b1dacd64e49e1d4a89e202e7&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4297108437&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=joshikiblog-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=joshikiblog-22&language=ja_JP&l=li3&o=9&a=4297108437" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

ただ、住宅ローンについての知識はほぼないし、そもそも人生経験も少ないので、ドメイン知識がなくネットの情報から頑張るしかなかったのはつらかった。。

類似したケースに関する論文も読んだし、住宅ローンについてのサイトはおそらく50は見たけど、多分全然足りなかったですね。

実際に作成した特徴量としては、
・前月との差
・3ヶ月移動平均
・完済年齢
・ローンを借り始めた年齢
・今まで何回返したか
・期間中の預金額の平均や最大値、最小値、最大値と最小値の乖離度
・完済年齢が65歳を超えるかどうか

などなどでした。定年後は収入が減るので延滞しやすいのではないか、ローン延滞の大きな原因は離婚などの突然のアクシデントが原因のことが多いらしいので、審査から時間が経っているほど延滞しやすいのではないか、など仮説をいくつも考えて特徴量生成をしましたが、決定的なものは見つけられませんでした。。。

### LightGBMでゴリ押し
コンペ期間中に、他の参加者の方のブログを見ることができたが、このたかいとさんのブログをとても参考にしてモデル構築を行いました。

https://takaito0423.hatenablog.com/entry/2023/02/03/212539

自分よりできる人たちがどういった考え方で取り組んでいるのか、コードはどのように書いているのか、本当に知りたかった部分だったのでとてもありがたかったです🙏

結局、あるシード値に固定し、5FoldのLightGBMだったので、5つのLightGBMをアンサンブルする形になりました。


# 振り返り
## 他の人の解法
Slackチャンネルで、他の方々が解法をシェアされていたので、全て読まさせてもらいました。

### 特徴量生成
・口座開設日や住宅ローン貸出日をtarget_encodingしたもの
・移動平均（rolling関数を用いて）
・メタ特徴量（予測値を使った特徴量生成）
・デフォルトが発生しない口座開設日や住宅ローン貸出日が存在するので、該当する人を全工程で除外する
・擬似的な完済年齢
・入金系の合計額過去１２ヶ月の変動係数
などを皆さん作られていたみたいです。

ただ、**自分との決定的な違いは、特徴量の数**でした。
皆さん3桁は軽く作っていて、300や400といった声が多かったです。
そっか、、、LightGBMってそんなに特徴量作るんだ・・・というのが正直な感想でした。

### 特徴量選択
特徴量の選択方法として、フィルタ法というのを使った方がいました。これは初耳だったので、あとで勉強します。

https://itmo-fs.readthedocs.io/en/latest/generated/ITMO_FS.filters.multivariate.MRMR.html

また、シンプルに特徴量重要度から上位の500個を選んだ人もいて、これはわかりやすかったです。ただ、時系列データということもあり、ドメインシフト（学習データとテストデータの分布が一致しない現象）を考慮しテストデータに近い直近2021/7以降のデータのみで特徴量重要度を出していたのは「なるほど！」となりました。。。

### モデル
皆さんLightGBMを使用されていました。やはり、テーブルデータなので勾配ブースティング一択だったのでしょう。NN系とのアンサンブルをしている人は見かけられなかったので、これは試してみたいと思いました。

パラメータを{"extra_trees":"true"}としたら結構スコアが上がったという人がいましたが、自分はこのパラメータを知らなかったので、まだまだ勉強不足・・
良さそうなサイトを見つけたのでどうぞ

https://note.com/j26/n/n64d9c37167a6

### 交差検証
今回は不均衡な時系列データだったので、StratifiedGroupKFoldを使った人がちらほら。(stratified='target_flag', group='yyyymm')

自分もやろうとしてたのに、Databricksのscikit-learnのバージョンが古くて使えなかったので諦めてた。。
普通にバージョンアップしている人がいて、自分は調べたのにやり方がわからなかったので力不足・・・
自分で実装すればよかったのに、シンプルに実装力不足・・・

修行が必要ですね、これは


### 参考になりそうなサイト
特徴量生成の際に参考になりそうな記事がシェアされていたので、ここでもシェアしておきます。

https://zenn.dev/colum2131/articles/fffac4654e7c7c

### 表彰式アーカイブ動画
表彰式のアーカイブ動画がつい先日YouTubeで公開されていました。
上位者の方々の解法なども短いですが紹介されているので、勉強になります。

https://www.youtube.com/watch?v=wguI0CTw_XU

## 反省点
初めてのちゃんとしたコンペへの参加だったので、反省点だらけでしたが、印象に残っているものを箇条書きにしてまとめておきます

:::note info
**特徴量をもっと生成しよう**
2桁しか生成できなかったのは足りなすぎ。移動平均とかもっともっとバリエーションを。
:::

:::note info
**実装力不足**
やりたいことをコードで表現できるように、もっとコードを書こう。特にStratifiedGroupKFoldとか、移動平均のrolling関数とか、全然使えてなかった。。。
:::

:::note info
**試行錯誤不足**
もっと色んなことを、たくさん試すべきだった。実装力不足が足を引っ張り、時間がなかった。もっとコードを書きながら勉強しよう
:::

初歩的なことばかりですが、上に行くには大切だと感じました。。。
python、もっともっと書きます。

# 最後に
今回はちゃんとしたコンペへの初めての参加で、わからないことだらけでしたが、得るものが多くて良かったと思います。
ただ、精度は全然出せなかったので、悔しい。。。
もっともっとKaggleで他の人のコードを読んだり、過去の人の解法を研究しよう、もっとコードを書きながら勉強しようと思いました。。

今後は目標であるKaggle　Masterの称号を目指して、頑張っていきます💪

ちなみに、今回の大会では「Databricks賞」という、ブログ記事に関する賞を、自分が所属する学生団体DSLのチームとして受賞することができました🎉
ありがとうございます

![348A9CD7-AC0E-4960-837C-D33010ACD8A8_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179677/03140996-46a7-7ac6-39be-98e06c5bd68d.jpeg)

その記事はこちら↓

https://qiita.com/mohki7/items/ea9961484d562a62b9a6

DSLのQiitaの方にも、チームとしての活動や詳しい解法などを書こうと思うので、ぜひ見てください😊