20 models ensemble diagnostics result

この記事は、[Numerai Advent Calendar 2021](https://adventar.org/calendars/6226) の16日目の記事です。

# はじめに

https://twitter.com/murenoha/status/1470527452221173760

このツイート内容と一部、重複します。
ツイート内容に加えてTB200の結果、新旧neutralize関数による結果も記載します。

# 変更履歴

* 2022-01-23
  * モデルのURLを追加
* 2022-05-10
  * 画像サイズを変更
  * 2022-04-03にアナウンスのあった新Diagnosticsの結果を追加
    * https://rocketchat.numer.ai/channel/announcements?msg=562DyyiAdoNKyWDmC
  * その他、文言や画像表示を微調整
* 2022-09-04
  * R332以降は、これらのモデルの予測提出は停止するので、最終提出のR331を追記

# データセットの20分割

https://forum.numer.ai/t/super-massive-data-release-deep-dive/4053/16

のフォーラム記事でmdoさんが言及されている分割方法です。

ターゲットのオーバラップを避けるために、Eraを以下のようにパージングして全体を4つグループの分けます。

```
Eraグループ1: 0001, 0005, 0009, ...
Eraグループ2: 0002, 0006, 0010, ...
Eraグループ3: 0003, 0007, 0011, ...
Eraグループ4: 0004, 0008, 0012, ...
```

さらに、特徴量1050個を210個の区切りで、全体を5つのグループに分けます。

```
特徴量グループ1: 1 ~ 210
特徴量グループ2: 211 ~ 420
特徴量グループ3: 421 ~ 630
特徴量グループ4: 631 ~ 840
特徴量グループ5: 841 ~ 1050
```

このようにして、4 * 5 = 20 で、データセットが20分割になります。

# アンサンブル結果

- ターゲット: target_nomi_20
- 学習アルゴリズム: LGBMRegressor
- パラメータ ([example](https://github.com/numerai/example-scripts/blob/master/example_model.py)と同じ)
  - n_estimators: 2000
  - learning_rate: 0.01
  - max_depth: 5
  - num_leaves: 2 ** 5
  - colsample_bytree: 0.1

## ノーマル

今回、20個の各データセットで学習して、予測値の平均を求めてアンサンブルしてみました。

* Diagnostics

|All|TB200|
|---|---|
|<img width="400" alt="20_ensemble_all.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/66d979d8-0d81-323d-c6fa-7bbf3ce20fc0.png">|<img width="400" alt="20_ensemble_tb200.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/76e8eb2d-48d7-31fd-a575-2dd9f40d8565.png">|

* 新Diagnostics

|All|TB200|
|---|---|
|<img width="400" alt="20_ensemble_all_newdiag.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/550e19f1-0f5f-113a-79be-5af7a9257bef.png">|<img width="400" alt="20_ensemble_tb200_newdiag.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/b8666e24-c7be-d534-7050-b295943fca23.png">|

* モデル（R297からR331まで提出）
https://numer.ai/murenoha8


## フルFN（新neutralize関数）

新データセットのutils.pyのneutralize関数を使用。proportion=1.0

* Diagnostics

|All|TB200|
|---|---|
|<img width="400" alt="20_ensemble_fn_all.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/f98554d7-fc55-2765-a0b9-04638ca690f7.png">|<img width="400" alt="20_ensemble_fn_tb200.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/1e5953ea-ceda-acb1-6761-4a1e76b0b74f.png">|

この結果だけをみるとマイナスが少なくて安定してそうですが、最近のlive eraでどうだったのか気になります。
今後、提出して観察してみます。
フルFNのCorrは、ノーマルのFNCの0.0175になると思いましたが、 0.0194 で一致しませんでした。

* 新Diagnostics

|All|TB200|
|---|---|
|<img width="400" alt="20_ensemble_fn_all_newdiag.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/3158765d-1f9b-9b11-526e-a04f19233a45.png">|<img width="400" alt="20_ensemble_fn_tb200_newdiag.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/ab1a4baa-be35-a4d8-0c50-926ccd047f31.png">|

* モデル（R298からR331まで提出）
https://numer.ai/murenoha9


## フルFN（旧neutralize関数）

旧データセットのneutralize関数を使用。proportion=1.0

|All|TB200|
|---|---|
|<img width="400" alt="20_ensemble_fn_all_old.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/d3bef353-c081-8952-f066-bb070c4df28a.png">|<img width="400" alt="20_ensemble_fn_tb200_old.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/ef36f8f0-d9bd-0b42-2116-40395b5b5974.png">|

Corrが、ノーマルのFNCの0.0175と一致しました。
新診断は、旧データセットのneutralize関数が使用されているようです。

* モデル（R298から提出）
https://numer.ai/murenoha8
このモデルのFNCが該当

# exampleモデルの結果

データセット分割との比較として、
新データセットに含まれている example_validation_predictions.csv です。

## ノーマル

|All|TB200|
|---|---|
|<img width="400" alt="example_val.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/913eb6b8-d7f7-50de-6822-1e9dc6cc7adf.png">|<img width="400" alt="example_val_tb200.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/8b6294d5-827a-cb9c-a058-77de7aec5282.png">|

## フルFN (新neutralize関数)

|All|TB200|
|---|---|
|<img width="400" alt="example_val_fn_new.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/a8b1cf55-4a01-f5ee-31f8-8d97860cdba8.png">|<img width="400" alt="example_val_fn_new_tb200.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/54a3d0b2-0d18-7218-c877-2ea2c159dafb.png">|

## フルFN (旧neutralize関数)

|All|TB200|
|---|---|
|<img width="400" alt="example_val_fn_old.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/c93d524f-7438-2b87-a892-2b2144834a61.png">|<img width="400" alt="example_val_fn_old_tb200.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628739/fe6500d1-cd9b-3e6d-6a10-687888f49152.png">|

# 雑多なメモ

- 20個のモデルの最適な組み合わせを探す
- nomi以外の他の20dayターゲットで学習してアンサンブルする
- 60dayターゲットで学習してアンサンブルする
- riskiest featuresによる中和を導入する
- 新旧neutralize関数の違いを調査する

# おわりに

ハイスペックマシンではなくても、データ分割してアンサンブルかつフルFNで高Sharpeを期待できそうです。

上記メモを試して進展ありましたら、共有したいと思います。

(特徴量が5つに分かれているのは、平日の5日間？)