機械学習の入力を整える特徴量エンジニアリング。エンコーディングとスケーリングが基本。
カテゴリ変数って機械学習にそのまま入れられないんだよね?
そうなのよ、そのままじゃ入れられないから数値化が必要なの。 エンコーディングにはいくつか種類があるわ。
import pandas as pd
from sklearn.preprocessing import LabelEncoder, StandardScaler, MinMaxScaler
df = pd.DataFrame({
'gender': ['F', 'M', 'F', 'M', 'F'],
'city': ['Tokyo', 'Osaka', 'Kyoto', 'Tokyo', 'Osaka'],
'age': [25, 32, 28, 45, 22],
'salary': [320000, 510000, 425000, 720000, 290000],
})
# (1) Label Encoding: カテゴリを整数に (順序がある場合)
le = LabelEncoder()
df['gender_le'] = le.fit_transform(df['gender']) # F=0, M=1
# (2) One-Hot Encoding: カテゴリを0/1の複数列に (順序なし)
df_onehot = pd.get_dummies(df, columns=['city'], prefix='city')
# city_Kyoto, city_Osaka, city_Tokyo の3列が追加される
# (3) Target Encoding: カテゴリを目的変数の平均で置換
city_mean = df.groupby('city')['salary'].mean()
df['city_te'] = df['city'].map(city_mean)
# (4) 標準化 (Z-score): 平均0、標準偏差1にする
scaler_std = StandardScaler()
df[['age_std', 'salary_std']] = scaler_std.fit_transform(df[['age', 'salary']])
# (5) 正規化 (Min-Max): [0, 1]に変換
scaler_mm = MinMaxScaler()
df[['age_mm', 'salary_mm']] = scaler_mm.fit_transform(df[['age', 'salary']])
Label EncodingとOne-Hot Encoding、使い分けはどうするんですかぁ?
順序があるカテゴリ(『低・中・高』など)はLabel、順序がない(都市名・色)はOne-Hot。 LabelEncoding を順序のないデータに使うと、機械学習モデルが順序を勝手に学習してしまうリスクがある。
じゃあ Target Encodingってのは何のために使うの?
カテゴリ数が多すぎてOne-Hotだと列数が爆発してしまう場合や、カテゴリと目的変数の関係を直接表現したいときに使うのよ。 ただし{kw('リーク')}には注意してね(訓練データから漏れた情報がテストデータに入ってしまうの)。
標準化と正規化の使い分け。 標準化は平均0・分散1、正規化は[0,1]の範囲に収める。 SVM・k-NN・ニューラルネットでは標準化必須、決定木系は不要。
決定木は標準化なしでOKなんですねぇ?
そうなのよ、決定木は分割の閾値が単位に依らないから影響を受けないの。 一方で、距離ベース(k-NN)や勾配法ベース(NN)は標準化が必須ね。
DS検定★では『One-Hot vs Label vs Target Encoding』『標準化と正規化の式』『どのモデルで標準化必須か』が頻出。
確認クイズ
順序のないカテゴリ変数 (例: 都市名 [東京、大阪、京都]) を機械学習モデルに入力する際の最適なエンコーディングはどれか。
- Label Encoding(東京=0, 大阪=1, 京都=2)
- One-Hot Encoding(3つの0/1列)
- そのまま文字列で渡す
- Min-Max正規化
こたえを見る
正解: 2. One-Hot Encoding(3つの0/1列)
One-Hot Encoding。 順序のないカテゴリにLabel Encodingを使うと、モデルが意図しない大小関係を学習してしまうリスクがあります。 One-Hotで各カテゴリを独立した0/1列にするのが安全です。