01.4.3
Count / Frequency Encoding
category_encoders の CountEncoder(normalize=True) で総務省の人口データの「元号」列を 0〜1 の出現確率に変え、LGBMRegressor の 5 分割交差検証に投入するまでを示します。出現頻度と目的変数の関係が弱いときは効果が薄いので、Target Encoding と組み合わせる判断基準も押さえます。直感 #
コンビニの商品 ID が 5,000 種類あるとき、One-Hot にすると 5,000 列の 0/1 ができますが、Count Encoding なら「その商品が何回売れたか」という 1 列で済みます。「売れ筋の商品ほど値が大きい」という情報だけが残り、どの商品かという個別性は捨てられます。Count Encoding(Frequency Encoding)は、各カテゴリの出現回数や出現確率を数値として付与する手法です。ワンホットより低次元で、カテゴリの人気度を暗に表現できるため、LightGBM や XGBoost などの木モデルでよく使われます。
特徴 #
利点は、次元数が 1 列で済んで学習・推論が高速なことと、「平成の行は 60%、令和の行は 5%」のようなカテゴリ間の頻度差をヒューリスティックに取り込めることです。欠点は、頻度が目的変数との関連を表すとは限らないことで、出現回数と人口総数に関係がないデータでは情報が足りず、Target Encoding などと組み合わせる必要があります。
実装レシピ #
次のコードは、総務省の人口データ sample.csv の「元号」列を出現確率に変えた 元号_freq 列を追加し、元の値と並べて先頭 5 行を表示します。
| |
主要オプション #
| パラメータ | 意味 | 推奨値 |
|---|---|---|
normalize | 出現回数をそのまま使うか、全体で割って確率にするか | 次元スケールを合わせたい場合は True |
min_group_size | 少数カテゴリをまとめる閾値 | データ量が偏る場合に活用 |
handle_unknown | 未知カテゴリをどう扱うか | "value" にして平均頻度を代入する等 |
典型的なユースケース #
最初のケースは、「町名」「商品ID」のように大量カテゴリだがターゲットとの相関は弱そうなときです。Count Encoding でベースラインを作り、特徴量重要度が高かった列だけ Target Encoding へ切り替えると、リークの手間を必要な列に絞れます。二つ目は、数値特徴量との交互作用を作りたいときで、Count Encoding した列と売上やアクセス数などを掛け合わせると「カテゴリ別トラフィック重み付き特徴量」が 1 列で作れます。三つ目はデータリークを避けたいときです。Target Encoding と違い目的変数を直接参照しないため、KFold で分けずに全データで fit してもリークリスクが低く、実装が単純になります。
モデル学習での扱い #
次のコードは、頻度に変えた「元号」と数値の「西暦」の 2 列で人口総数を予測する LGBMRegressor を 5 分割交差検証し、決定係数の平均を表示します。
| |
Count Encoding 列は 1 本なので、そのままモデルに渡すだけで済みます。パイプラインの一部に category_encoders を入れておくと、本番環境での再現性も担保しやすくなります。
品質チェックリスト #
最初に確認したいのはカテゴリの分布です。大半の行が同一カテゴリ(例: 90% が「平成」)なら、頻度列はほぼ定数になって効果が薄いです。二つ目は Count(回数)と Frequency(割合)のどちらがモデルに合うかで、normalize を切り替えて交差検証スコアを比べて決めます。三つ目は未知カテゴリや欠損(NaN)に対する挙動で、学習時にない元号が推論時に来たときに handle_unknown の設定どおりの値が入るかをテストします。最後に、元号_freq の特徴量重要度が高かった場合は、追加で Target Encoding や「カテゴリごとの目的変数の平均」との比較を試し、頻度が効いているのか、頻度が別の何かの代理になっているのかを見極めます。
参考 #
- category_encoders.count.CountEncoder
- 実プロジェクトでは Count Encoding + Target Encoding のハイブリッドを試す価値が高い(Count をベースに、上位カテゴリだけ Target Encoding するなど)。