Target / Mean Encoding

Prep

Target / Mean Encoding

概要 #

Target Encoding(Mean Encoding)は、カテゴリごとの目的変数の平均(または中央値)でカテゴリを数値化する手法です。高次元なカテゴリを 1 列に落とし込みながら、目的変数との結び付きを直接反映できるため、テーブルデータの Kaggle などで定番になっています。その一方で リーク(過大評価)との戦い が最大のテーマになります。


Pipeline 例(KFold + TargetEncoder) #

import pandas as pd
import numpy as np
from category_encoders.target_encoder import TargetEncoder
from sklearn.model_selection import KFold

df = pd.read_csv("../data/sample.csv")
cat_col = "元号"
target_col = "人口総数"

te = TargetEncoder(smoothing=1.0)  # 事前分布との平滑化
df[f"{cat_col}_te"] = 0.0

kf = KFold(n_splits=5, shuffle=True, random_state=0)
for train_idx, valid_idx in kf.split(df):
    te.fit(df.loc[train_idx, cat_col], df.loc[train_idx, target_col])
    df.loc[valid_idx, f"{cat_col}_te"] = te.transform(df.loc[valid_idx, cat_col])

# 最終的に全データで再学習し、推論時はこの encoder を使う
te.fit(df[cat_col], df[target_col])

実装のポイント #

  1. Out-of-Fold で生成する
    学習に使った行で同じ統計値を使うとリークするため、KFold で分割し、検証側を推測する形にする。

  2. 平滑化(smoothing)を入れる
    出現回数が少ないカテゴリは全体平均に寄せる。smoothing=1.0 などを指定すると count / (count + smoothing) を重みとして混ぜてくれる。

  3. ノイズを加える
    np.random.normal(0, 0.01) のような微小なノイズを足すと、木モデル+小規模データでの過学習を軽減できる。


リーク対策の比較 #

手段目的実装 Tip
KFold Out-of-Fold 生成訓練行でのリーク防止n_splits=5 以上で安定化
時系列順の蓄積平均未来情報を使わないOrdered Target Statistics との比較を推奨
事前分布との平滑化頻度の少ないカテゴリでの極端値を抑えるsmoothingcount に応じて増減
ノイズ注入過学習の抑制np.random.normal(scale=0.01) などを加算

モデル投入時の検証ポイント #

  1. バリデーションスキームとの整合性
    Hold-Out / KFold / 時系列など、本番運用と同じスキームで Out-of-Fold を作成したか?

  2. 重要度をモニタリング
    重要度(Gain / SHAP)が極端に高い場合、リークの可能性あり。
    → 交差検証スコアと Public/Private LB の差分を定期チェック。

  3. カテゴリごとの値域を確認
    df.groupby(cat_col)[f"{cat_col}_te"].agg(["count", "mean", "std"]) で値域を可視化し、想定外の極端値がないかを見る。


チェックリスト #

  • 学習データと検証データが完全に分離された状態でエンコードしているか?
  • 平滑化・ノイズを入れたバージョンと入れていないバージョンを比較したか?
  • 推論時に使う TargetEncoder を保存し、再現性を担保したか?
  • 需要予測・行動予測など時系列依存が強い場合は Ordered Target Statistics も検討したか?

参考文献 #