カテゴリ変数の処理方法

2025/03/03に公開

カテゴリ変数の処理方法にはさまざまな方法がありますが、代表的な One-hot encoding, Label encoding, Target encoding について詳しく説明します。


1. One-hot encoding(ワンホットエンコーディング)

概要

カテゴリ変数を 0/1のバイナリベクトル に変換する手法。

方法

  1. カテゴリごとに新しいカラムを作成。
  2. そのカテゴリに該当する場合は「1」、該当しない場合は「0」を入れる。

Color Red Blue Green
Red 1 0 0
Blue 0 1 0
Green 0 0 1

メリット

  • 数値の大小に意味がないため、学習が安定する。
  • 木構造(決定木系アルゴリズム)やニューラルネットワークと相性が良い。

デメリット

  • 次元爆発(カラム数が増える) → カテゴリ数が多いと計算量が増える。
  • メモリ消費が増えるため、大規模データには向かない。

適用例

  • カテゴリの種類が少ない場合(例:性別、曜日、天気など)。
  • 決定木系アルゴリズム(Random Forest, XGBoost, LightGBM)を使用する場合。

2. Label encoding(ラベルエンコーディング)

概要

カテゴリを 整数値に変換 する方法。

方法

  • 各カテゴリに 0,1,2,3... のような整数を割り当てる。

Color Encoded
Red 0
Blue 1
Green 2

メリット

  • One-hot encodingよりメモリ効率が良い。
  • カラム数が増えない。

デメリット

  • 数値の大小に意味がないのに、順序情報が生じる → 予測が歪む可能性あり。
  • 線形回帰やニューラルネットワークとは相性が悪い。

適用例

  • 決定木系アルゴリズム(XGBoost, LightGBM)では問題にならない ため、そのまま使えることが多い。
  • カテゴリ数が多い場合(One-hot encodingだとカラム数が爆発する場合)。
  • 高速な処理が求められる場合。

3. Target encoding(ターゲットエンコーディング)

概要

カテゴリを ターゲット(目的変数)の平均値 に変換する手法。

方法

  1. 各カテゴリごとに目的変数(ターゲット変数)の平均値を計算。
  2. その値でカテゴリ変数を置き換える。

例(目的変数が売上金額)

Color Sales (平均)
Red 200
Blue 150
Green 300

Red = 200, Blue = 150, Green = 300 に変換。

メリット

  • 数値として扱えるため、メモリ効率が良い。
  • 次元爆発を回避できる。

デメリット

  • リークのリスク(データが漏れる可能性) → 学習データとテストデータを分けた後にエンコーディングを行う必要あり。
  • 外れ値の影響を受けやすい。

適用例

  • カテゴリ数が多い場合(One-hot encodingが使えない場合)。
  • 特に線形モデル(回帰モデル、ニューラルネットワーク)で効果的。

どの手法を使うべき?

One-hot encoding Label encoding Target encoding
カテゴリ数が少ない ✅ 適用可能 ✅ 適用可能 ✅ 適用可能
カテゴリ数が多い ❌ メモリ増加 ✅ そのまま使える ✅ 有効
線形回帰・ニューラルネットワーク ✅ 良い ❌ 適さない ✅ 良いがリーク注意
決定木系(XGBoost, LightGBM) ✅ 良い ✅ 良い ❌ 適さない場合あり
  • カテゴリ数が少なければ One-hot encoding
  • カテゴリ数が多ければ Label encoding または Target encoding
  • 決定木系なら Label encoding でもOK
  • 線形回帰やニューラルネットワークなら Target encoding が有効だが、リークに注意

Pythonでの実装例

One-hot encoding

import pandas as pd
from sklearn.preprocessing import OneHotEncoder

df = pd.DataFrame({'Color': ['Red', 'Blue', 'Green', 'Red']})
encoder = OneHotEncoder(sparse=False)
encoded = encoder.fit_transform(df[['Color']])
print(pd.DataFrame(encoded, columns=encoder.get_feature_names_out()))

Label encoding

from sklearn.preprocessing import LabelEncoder

encoder = LabelEncoder()
df['Color_encoded'] = encoder.fit_transform(df['Color'])
print(df)

Target encoding

df = pd.DataFrame({'Color': ['Red', 'Blue', 'Green', 'Red'],
                   'Sales': [250, 150, 300, 200]})

# 各カテゴリのSalesの平均値を計算
df['Color_encoded'] = df['Color'].map(df.groupby('Color')['Sales'].mean())
print(df)

まとめ

  • One-hot encoding → カテゴリが少ない場合、ニューラルネットワーク・決定木系で使える。
  • Label encoding → カテゴリが多い場合、決定木系ならそのまま使える。
  • Target encoding → 線形モデル向けだが、リークに注意。

どの方法を選ぶかは データの特徴とアルゴリズム によるので、適切な方法を選ぶのが大事です!

Discussion