target encoding 深掘り
ターゲットエンコーディングを CV 内で正しく適用し、平滑化でリークと過学習を抑える方法を学びます。
このトラックで学ぶこと#
このトラック(L8)では、上位入賞・グランドマスターを目指すための上級テクニックと、 運用・チーム戦略・称号獲得の実戦知見を体系化します。L7 までの土台の上に、勝負を分ける一手を積みます。
target encoding の威力と危うさ#
ターゲットエンコーディングは、カテゴリ変数を目的変数の統計量(多くは平均)で数値化する強力な手法です。 高カーディナリティでも効きますが、目的変数を使うため最もリークしやすいのが弱点です。
fold 内(out-of-fold)で適用する#
リークを防ぐ原則は単純です。各サンプルのエンコード値は、そのサンプルを含まないデータから計算します。
import numpy as np
from sklearn.model_selection import StratifiedKFold
def target_encode_oof(train, test, col, target, n_splits=5, smoothing=10):
oof = np.zeros(len(train))
prior = train[target].mean()
skf = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=42)
for tr, va in skf.split(train, train[target]):
agg = train.iloc[tr].groupby(col)[target].agg(["mean", "count"])
# 平滑化: 件数が少ない水準は全体平均(prior)へ寄せる
smooth = (agg["mean"] * agg["count"] + prior * smoothing) / (agg["count"] + smoothing)
oof[va] = train.iloc[va][col].map(smooth).fillna(prior).values
# test は train 全体で計算した平滑化値を使う
agg = train.groupby(col)[target].agg(["mean", "count"])
smooth = (agg["mean"] * agg["count"] + prior * smoothing) / (agg["count"] + smoothing)
test_enc = test[col].map(smooth).fillna(prior).values
return oof, test_enc平滑化(smoothing)の意味#
出現回数の少ない水準は、その平均が偏りやすく過学習の原因になります。 件数に応じて全体平均へ寄せる(平滑化)ことで、安定したエンコードになります。
理解度チェック#
次のステップ#
次は、train/test の分布差を検出する adversarial validation を学びます。