✨
カテゴリ変数の処理方法
カテゴリ変数の処理方法にはさまざまな方法がありますが、代表的な One-hot encoding, Label encoding, Target encoding について詳しく説明します。
1. One-hot encoding(ワンホットエンコーディング)
概要
カテゴリ変数を 0/1のバイナリベクトル に変換する手法。
方法
- カテゴリごとに新しいカラムを作成。
- そのカテゴリに該当する場合は「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(ターゲットエンコーディング)
概要
カテゴリを ターゲット(目的変数)の平均値 に変換する手法。
方法
- 各カテゴリごとに目的変数(ターゲット変数)の平均値を計算。
- その値でカテゴリ変数を置き換える。
例(目的変数が売上金額)
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