概要 #
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])
実装のポイント #
Out-of-Fold で生成する
学習に使った行で同じ統計値を使うとリークするため、KFold で分割し、検証側を推測する形にする。平滑化(smoothing)を入れる
出現回数が少ないカテゴリは全体平均に寄せる。smoothing=1.0などを指定するとcount / (count + smoothing)を重みとして混ぜてくれる。ノイズを加える
np.random.normal(0, 0.01)のような微小なノイズを足すと、木モデル+小規模データでの過学習を軽減できる。
リーク対策の比較 #
| 手段 | 目的 | 実装 Tip |
|---|---|---|
| KFold Out-of-Fold 生成 | 訓練行でのリーク防止 | n_splits=5 以上で安定化 |
| 時系列順の蓄積平均 | 未来情報を使わない | Ordered Target Statistics との比較を推奨 |
| 事前分布との平滑化 | 頻度の少ないカテゴリでの極端値を抑える | smoothing を count に応じて増減 |
| ノイズ注入 | 過学習の抑制 | np.random.normal(scale=0.01) などを加算 |
モデル投入時の検証ポイント #
バリデーションスキームとの整合性
Hold-Out / KFold / 時系列など、本番運用と同じスキームで Out-of-Fold を作成したか?重要度をモニタリング
重要度(Gain / SHAP)が極端に高い場合、リークの可能性あり。
→ 交差検証スコアと Public/Private LB の差分を定期チェック。カテゴリごとの値域を確認
df.groupby(cat_col)[f"{cat_col}_te"].agg(["count", "mean", "std"])で値域を可視化し、想定外の極端値がないかを見る。
チェックリスト #
- 学習データと検証データが完全に分離された状態でエンコードしているか?
- 平滑化・ノイズを入れたバージョンと入れていないバージョンを比較したか?
- 推論時に使う
TargetEncoderを保存し、再現性を担保したか? - 需要予測・行動予測など時系列依存が強い場合は Ordered Target Statistics も検討したか?
参考文献 #
- Micci-Barreca, Daniele. “A Preprocessing Scheme for High-Cardinality Categorical Attributes in Classification and Prediction Problems.” SIGKDD (2001).
- category_encoders.target_encoder.TargetEncoder