02.2.13
【ベンチマーク】混合型特徴量の分類
OrdinalEncoder だけで高い精度を出します。LogisticRegression や SVC の線形モデルは OneHotEncoder と StandardScaler を両方入れないと、「関東=3 は北海道=1 より大きい」という偽の順序を学習してしまいます。読み終えると、「とりあえず OneHot」ではなく、使う分類器に合わせてエンコーディングを選ぶ判断ができるようになります。顧客データ・医療記録・アンケート結果など、実務データは連続値とカテゴリ変数が混在していることがほとんどだ。「とりあえずOneHotEncoding」で済ませがちだが、エンコーディングの選択がモデルの精度を大きく左右する。ここでは混合型特徴量を持つ合成データで最適な組み合わせを検証する。
1. データの特徴 #
n=1000 の 3 クラス分類で、特徴量は 3 種類に分かれます。連続値特徴量が 3 つ(クラスごとに平均をずらした正規分布)、順序尺度特徴量が 2 つ(低/中/高、S/M/L/XL のように順序がある)、カテゴリ特徴量が 2 つ(地域名や職種のように順序がなく、水準数は 5〜8)です。順序尺度は整数に置き換えてよいが、カテゴリに整数を振ると存在しない大小関係が生まれる、という違いがこのページの出発点です。
2. 合成データの生成 #
次のコードは、クラスラベルを先に決めてから、クラスごとに分布を変えた連続値・順序尺度・カテゴリの 7 列を作り、DataFrame にまとめて 3 枚の分布図で確認します。
| |

3. 比較するパイプライン #
| エンコーディング | 説明 | 分類器 |
|---|---|---|
| OrdinalEncoding | すべての変数を整数に変換 | 6分類器 |
| OneHotEncoding | カテゴリ変数をダミー変数化 | 6分類器 |
| OneHot + StandardScaler | ダミー化後にスケーリング | 6分類器 |
| TargetEncoding | カテゴリをクラス平均で置換(CV内) | 6分類器 |
4. 実験と結果 #
次のコードは、ColumnTransformer で列の種類ごとに違う変換を当てる 4 種類のパイプラインを作り、6 分類器と組み合わせた 24 本を同じ 5 分割で交差検証して、F1-macro のヒートマップにします。
| |

読み方のポイント #
木系モデル(DecisionTreeClassifier・RandomForestClassifier・GradientBoostingClassifier)は Ordinal エンコーディングだけで十分な精度を出します。カテゴリに振った整数を「スプリット可能な数値」として扱い、分割を重ねれば任意の水準の組を切り出せるためです。線形モデル(LogisticRegression・SVC)は OneHot と StandardScaler の両方が必須で、Ordinal のままでは「地域=3 は地域=1 より大きい」という偽の順序を学習してしまいます。KNeighborsClassifier は距離ベースなので、同じ OneHot でもスケーリングの有無で精度が大きく変わります。
5. 誤差パターン分析 #
ヒートマップから、木系に Ordinal、線形に OneHot+Scale、そして線形に Ordinal という「合う組・合わない組」を 1 つずつ選び、同じ 70/30 分割の混同行列で比べます。
| |

Ordinal で SVM を使うとカテゴリ変数の偽順序により特定クラス間の混同が増える。RF は Ordinal で問題なく動作し、Logistic は適切なエンコーディング + スケーリングで安定する。
6. よくある失敗パターン #
最初の失敗は、カテゴリ変数に LabelEncoder を使って線形モデルに渡すことです。「関東=3 は北海道=1 の 3 倍」のような偽の大小関係を学習してしまうので、線形モデルには OneHotEncoder を使います。二つ目は、高カーディナリティ変数を OneHot することです。カテゴリ数が 100 を超えると特徴量が爆発するので、TargetEncoder や頻度エンコーディングを検討してください。
まとめ #
連続値・順序尺度・カテゴリが混在するデータでは、エンコーディングの正解が分類器の種類で変わります。木系モデルは OrdinalEncoder の整数をそのまま分割に使えるので OneHot にする必要がなく、線形モデルと距離ベースのモデルは OneHotEncoder と StandardScaler を両方入れないと偽の順序と尺度差に引きずられます。順序尺度は ordered=True の Categorical から .cat.codes で整数化すれば大小関係が保たれ、どのモデルにもそのまま渡せます。エンコーディングはすべて ColumnTransformer と Pipeline の中に置き、交差検証の各分割で学習データだけから当てはめてください。