コンセプト #
Ordered Target Statistics は、CatBoost が採用する「順序付きターゲットエンコーディング」です。
サンプルをランダム順または時間順に並べ、各サンプルをエンコードするときには それ以前に出現したデータのみ を使ってターゲット平均を計算します。
これにより、Target Encoding の強み(ターゲットとの強い相関を捉える)を保ちながら、未来の情報を使ってしまうリークを防げます。
実装ステップ #
import pandas as pd
from category_encoders.cat_boost import CatBoostEncoder
df = pd.read_csv("../data/sample.csv")
cat_col = "元号"
target_col = "人口総数"
encoder = CatBoostEncoder(cols=[cat_col], random_state=0)
df[f"{cat_col}_ots"] = encoder.fit_transform(df[cat_col], df[target_col])
df[[cat_col, f"{cat_col}_ots"]].head()
category_encoders.cat_boost.CatBoostEncoder が最も手軽です。内部でデータ順序をランダムに並べ替え、逐次平均を計算してくれます。
時系列データでの応用 #
df = df.sort_values("西暦")
encoder = CatBoostEncoder(cols=[cat_col], random_state=0)
df[f"{cat_col}_ots"] = encoder.fit_transform(df[cat_col], df[target_col])
時系列でリークを避けたい場合は、学習前に sort_values で時系列順に並べてから encoder に渡すだけで OK。CatBoostEncoder は与えられた順序を尊重します。
ハイパーパラメータ #
| パラメータ | 説明 | 推奨設定 |
|---|---|---|
random_state | ランダム順序の再現性 | モデル全体と同じ seed を指定 |
smoothing | 事前平均との平滑化強度 | 1.0 〜 5.0 をデータ量に応じて調整 |
a (sigma) | ノイズの大きさ | 0.0(ノイズなし)〜 0.05 程度 |
CatBoost では内部で ordered boosting を採用しており、同様の考え方でリークを抑えています。
可視化で挙動をチェック #
import matplotlib.pyplot as plt
import japanize_matplotlib
plt.figure(figsize=(8, 4))
for era in df[cat_col].unique():
subset = df.query(f"{cat_col} == @era")[f"{cat_col}_ots"]
plt.hist(subset, alpha=0.5, label=era, bins=20)
plt.title("Ordered Target Statistics の分布")
plt.legend()
カテゴリごとの分布を重ねると、時間経過に伴ってどのようにターゲット平均が更新されているか視覚的に確認できます。
運用 Tips #
- 学習・推論の再現性: 学習時に使用した encoder を pickle / joblib で保存し、推論環境にデプロイする。
- データシャッフル: ランダム順序で複数回学習し、スコアを平均することで分散を抑える。
- CatBoost のネイティブ機能: CatBoost を使っている場合は
cat_featuresに指定するだけで内部で同等の処理が行われるため、外部でエンコーディングする必要はない。
チェックリスト #
- 入力データの並び順(時間順 or ランダム順)を明示的に制御したか?
- Target Encoding と比較し、過学習が緩和されているかを CV で確認したか?
- 学習済み encoder を保存し、推論パイプラインに組み込んだか?
参考 #
- Prokhorenkova, Liudmila, et al. “CatBoost: unbiased boosting with categorical features.” arXiv:1706.09516 (2017).
- category_encoders.cat_boost.CatBoostEncoder