Kaggle Tutorial

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)の意味#

出現回数の少ない水準は、その平均が偏りやすく過学習の原因になります。 件数に応じて全体平均へ寄せる(平滑化)ことで、安定したエンコードになります。

注意

全データでターゲット平均を計算して付与すると、検証側の答えが漏れるデータリークになり、 CV だけ高くて本番で崩れます。必ず OOF で作り、交差検証で効果を確認します。

理解度チェック#

Quiztarget encoding で「出現回数の少ない水準」の過学習を抑える工夫は?

次のステップ#

次は、train/test の分布差を検出する adversarial validation を学びます。