【小ネタ】`Birthday Seed`のすすめ



## はじめに

こんにちは！
Kaggleでは乱数を固定することが多いです。そのシード値の多くは、`0, 1, 42, 777, 1234`などに偏っています。本記事では、乱数のシード値が他のKagglerと被るとどのような事が起こるのか論じます。
**結論としては、乱数のシード値は被らない方が良いと考えられます。**
そこで、なるべく他のユーザーと被らない乱数シード値として、`Birthday Seed`（＝誕生日を乱数のシード値に使うというだけの話です、、！😂）を提案します。


## Kaggleにおける乱数の固定について

Kaggleでは多くの機械学習実験を行います。その際に、乱数のシード値が固定されていないと試行錯誤によって精度が向上したのか、乱数によってたまたま変化しただけなのかの切り分けが難しくなり、再現性が取れなくなります。そのため、乱数のシード値を固定することが望ましいです。

Kaggleで良く使われている乱数固定関数は例えば下記があります。ソースコードの冒頭に貼り付けるだけで、めぼしい乱数の固定が可能です。

**PyTorchユーザー向け**
```python
import os
import random
import numpy as np
import torch

SEED = 42

def seed_everything(seed):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.backends.cudnn.deterministic = True

seed_everything(seed=SEED)
```

**TensorFlowユーザー向け**
```python
import os
import random
import numpy as np
import tensorflow as tf

SEED = 42

def set_seed(seed):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
    tf.random.set_seed(seed)
    
set_seed(seed=SEED)
```

## 乱数のシード値が他のKagglerと被るとどうなるのか


乱数のシード値が他のKagglerと被ることの影響について、「[The Kaggle Book：データ分析競技 実践ガイド＆精鋭31人インタビュー](https://book.impress.co.jp/books/1122101060)」の7.2章「再現性を確保するためにランダム状態を設定する」には下記のように書かれています。

>さて、コンペティションの参加者全員が同じ乱数シードを使っているとしたら、次の二重の現象が生じることが考えられます。
・ この乱数シードはパブリックリーダーボードでうまくいきすぎる（過剰適合する）可能性がある。
・ 多くのKagglerが同じような結果を生成し、プライベートリーダーボードの順位に同じような影響を与える。
　乱数シードを変更すれば、過剰適合を回避できるだけではなく、抜け駆けをすることができます。つまり、他の参加者のさまざまな結果を参考にして、最終的に有利な位置につくことができます。

出典：[The Kaggle Book：データ分析競技 実践ガイド＆精鋭31人インタビュー](https://book.impress.co.jp/books/1122101060)

つまり、**他のKagglerと乱数のシード値が被らない方がちょっとだけ得**ということです！

## Birthday Seedのすすめ

それではタイトルを回収し、他のKagglerと被らなそうな乱数のシード値として、`Birthday Seed`（＝誕生日を乱数のシード値に使うというだけの話です、、！😂）を提案します。

**`Birthday Seed`の使用方法**
```python
SEED = 1015 # This is my birthday🎂
```


**`Birthday Seed`を使用するメリット**
- 他のKaggler（`0, 1, 42, 777, 1234`などの乱数シード値を使っている）と、まず乱数のシード値が被らない
    - 仮に他の誰かが`Birthday Seed`を使ったとしても、その人と被る確率は単純計算で`1/365`（閏年を除く）とかなり低いです。
        - それでも被ったら友達になればいいんじゃないでしょうか。
- 忘れない
    - オリジナルのシード値を使うとして、忘れてしまう可能性がありますが、誕生日であれば忘れる可能性が低いです。
- 誕生日を覚えてもらえる
    - 自分の誕生日をシードとして公開することで、他の参加者との親しみやすい交流のきっかけになるかもしれません。
    - 例えば、同じ誕生日のシードを使用している参加者同士で「誕生日が同じだ！」という話題でコミュニケーションが生まれる可能性があります。

**`Birthday Seed`を使用するデメリット**
- 他のKagglerに対して一人負けする可能性がある
    - 抜け駆けをできることもあれば、逆もしかりです。
- 誕生日がバレる
    - 恥ずかしがり屋の人には向いていないかもしれません。
- 誕生月が一桁（4月など）の場合は使えない
    - `SEED = 0415`などとするとエラーになります
        - [YYYYMMDD形式](https://e-words.jp/w/YYYYMMDD%E5%BD%A2%E5%BC%8F.html)で書けば大丈夫ですが、年齢がバレるという新たなデメリットが、、、

## おわりに

「[自転車置き場の議論](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%82%AD%E3%83%B3%E3%82%BD%E3%83%B3%E3%81%AE%E5%87%A1%E4%BF%97%E6%B3%95%E5%89%87)」失礼しました！
（ぶっちゃけ、乱数はなんでも良いと思います😂）

乱数の値を何にするかに迷うのであれば、特徴量エンジニアリングやモデリングなどに頭を使ったほうが良いと思います。なので、乱数は`Birthday Seed`にしてしまって、他のところに時間を使っていただければ嬉しいです！


本記事は以上です。皆様がゴールデンシードを引くことを願っております。


## 💡お知らせ
1人アドカレで生成AIについての記事を25件投稿しています！
この記事をご覧になられた方は、生成AIに興味がある方も多いと思いますので、よろしければご覧ください！

**生成AIアドベントカレンダー**

https://qiita.com/advent-calendar/2023/nebosuke-ai

**記念すべき第1回の記事：『生成AIを活用した勉強方法を体系的にまとめてみました』**

https://qiita.com/Isaka-code/items/6c81f89b48e9e74cb1c9


## 参考文献

この記事は以下を参考にして執筆しました。

https://book.impress.co.jp/books/1122101060

https://qiita.com/si1242/items/d2f9195c08826d87d6ad

https://www.opst.co.jp/keep_innovating_blog/220105/

https://qiita.com/ofutonton/items/8cb88b34375bf473e45e

https://qiita.com/upura/items/3c10ff6fed4e7c3d70f0

https://kutohonn.hatenablog.com/entry/2021/01/04/232434

https://qiita.com/kaggle_grandmaster-arai-san/items/d59b2fb7142ec7e270a5#seed_everything