2026/06/26

必要なライブラリのインポート

記事イメージ
※画像はイメージです。本文と直接の関係はありません

The user asks: "以下の本文を簡潔な標題(10文字以内)にまとめてください。" They want a concise title (10 characters or less) summarizing the provided text. Must output only pure Japanese, no English terms, no Chinese characters. Must be within 10 characters. Need to think of a title capturing the content: LightGBM category handling, preprocessing, etc. Possibly "LightGBMカテゴリ活用". Count characters: L i g h t G B M... but English letters not allowed. Must be Japanese. Could be "カテゴリ活用法". That's 6 characters? Let's count: カ (1) テ (2) ィ (3) グ (4) ロ (5) 活 (6) 用 (7) 法 (8) → 8 characters. Good within 10. Or "LightGBMのカテゴリ処理" includes English. Not allowed. Use Japanese only: "カテゴリ処理手順". Count: カ1 テ2 ィ3 ゴ4 ロ5 処6 理7 手8 順9 → 9 characters. Also good. Which is better? The text is about preprocessing and feature engineering for LightGBM categories. Title: "カテゴリ処

必要なライブラリのインポート

必要なライブラリのインポート

Quick Start(最短 3 行)

# 必要なライブラリのインポート
from sklearn.model_selection import train_test_split
from lightgbm import LGBMClassifier
from sklearn.metrics import accuracy_score

# 1. カテゴリ列を「category」型に変換
cat_cols = ['gender', 'city', ...]          # カテゴリ列のリスト
df[cat_cols] = df[cat_cols].astype('category')

# 2. 学習データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(
    df.drop('target', axis=1), df['target'],
    test_size=0.2, random_state=42
)

# 3. モデル学習と評価
model = LGBMClassifier(cat_l2=10, cat_smooth=10)
model.fit(X_train, y_train, categorical_feature=cat_cols)
pred = model.predict(X_test)
print('Accuracy:', accuracy_score(y_test, pred))

前提条件(動作仕様のルール)

カテゴリの整数化categorical_feature を指定するだけの場合は 0 から始まる整数 に変換する必要があります。category 型を利用すれば文字列のままでも内部で整数化されます。 ・category 型への変換(推奨):Pandas の列を category 型にすれば、LightGBM の API(LGBMClassifierLGBMRegressor)では categorical_feature を明示しなくても自動判別されます。 ・categorical_feature の明示(整数化のみの場合):整数化した列だけを使うときは、必ず categorical_feature に列名または列番号を指定してください。 ・ワンホットは不要:LightGBM は内部で最適な分割を探索するため、ワンホットに展開しなくても学習できます。 ・欠損値の取り扱いNaN は LightGBM が自動的に欠損として扱います。基本はそのまま渡すことが精度向上につながります。数値マーカー(例:-999)で埋める必要がある場合は、埋めた後に 整数化 または category 型への変換 を必ず行ってください。 ・カテゴリ列が多数ある場合:カテゴリ変数が 数百列以上 に及ぶとメモリ消費が増大します。その際は重要度の低い列を事前に除外するか、max_cat_to_onehot パラメータで One‑Hot への変換上限を調整してください。


前処理の具体的な流れ(基本編)

  1. 不要列の除去
df = df.drop(['id', 'name'], axis=1)
  1. 欠損の確認と対処
  • 欠損率が高い列は情報量が低くなる可能性があるため削除を検討
  • 欠損率が低い列はそのままでも LightGBM が自動で処理
  • 欠損を数値マーカーで埋める場合は fillna(-999) した後に 整数化 または category 型への変換 を忘れないこと
df = df.fillna(-999)   # 必要に応じて実施

ベストプラクティス
LightGBM は NaN をそのまま扱えるため、基本は欠損を埋めずに渡す方が精度向上につながります。埋める必要がある場合だけ、上記手順を踏んでください。

  1. カテゴリ変数のエンコード
  • 文字列のまま category 型に変換(最もシンプル)
cat_cols = ['gender', 'city', ...]   # カテゴリ列のリスト
df[cat_cols] = df[cat_cols].astype('category')
  • 整数化が必要な場合は OrdinalEncoder を利用LabelEncoder は目的変数専用)
from sklearn.preprocessing import OrdinalEncoder

encoder = OrdinalEncoder(
    handle_unknown='use_encoded_value',
    unknown_value=-1
)
df[cat_cols] = encoder.fit_transform(df[cat_cols].astype(str))

ポイント
- 学習データで fit し、テストデータは同じインスタンスで transform する
- テストデータに学習データに存在しないカテゴリが出た場合は handle_unknown が安全に処理します

  1. データ分割と categorical_feature の指定
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    df.drop('target', axis=1), df['target'],
    test_size=0.2, random_state=42
)

# pandas の DataFrame のまま渡すと `category` 型情報が保持されるため
# 明示的に指定しなくてもカテゴリとして認識されます。
# ただし NumPy 配列に変換して渡す場合は必ず `categorical_feature` を指定してください。

model = LGBMClassifier()
model.fit(
    X_train,
    y_train,
    categorical_feature=cat_cols   # 必要に応じて明示
)
  1. 評価・活用
from sklearn.metrics import accuracy_score

pred = model.predict(X_test)
print('Accuracy:', accuracy_score(y_test, pred))

回帰タスクの場合
LGBMRegressor を使用し、評価指標を平均絶対誤差や二乗平均平方根誤差に置き換えるだけで同様に実装できます。


特徴量の入れ方・削り方(応用・チューニング編)

  1. 重要度で特徴量を絞り込む
model.fit(X_train, y_train, categorical_feature=cat_cols)
importance_gain = model.booster_.feature_importance(importance_type='gain')
low_imp_cols = [
    col for col, imp in zip(X_train.columns, importance_gain) if imp < 1e-3
]
  • importance_type='gain' は「情報増加量」に基づく指標で、分割回数(split)よりも目的変数への寄与度を正確に表します。分割回数は頻出する特徴量が過大評価されやすい点に注意が必要です。
  1. 相関が高い数値特徴は統合
  • 相関係数が 0.9 以上 の数値列はどちらか一方に統合するか、主成分分析で次元削減すると木の分割が冗長になるのを防げます。
  1. 低頻度カテゴリの集約
freq = df[col].value_counts()
df[col] = df[col].where(df[col].map(freq) > 2, 'その他')
df[col] = df[col].astype('category')

リスク:サンプル数が極端に少ないカテゴリは分割に寄与しにくく、過学習の原因になることがあります。集約は安定性向上の手段として活用してください。

  1. 欠損フラグの活用

欠損自体が有用な情報であると判断した場合は、isnull 列を追加すると効果が出ることがあります。

  1. GPU 版でも同様に機能

GPU ビルドが有効であれば、CPU と同じコードで categorical_feature を指定できます。GPU を利用すれば学習速度がさらに向上しますが、カテゴリ処理のロジックは変わりません。

  1. カテゴリ系ハイパーパラメータの活用
  • cat_l2 … カテゴリ分割に対する L2 正則化。高カーディナリティ(種類が多数ある)列に適用すると過学習抑制に効果的です。
  • cat_smooth … カテゴリごとの統計量に対する平滑化係数。ノイズが多いデータセットで安定した分割を促します。
model = LGBMClassifier(cat_l2=10, cat_smooth=10)
model.fit(X_train, y_train, categorical_feature=cat_cols)
  1. ターゲットエンコーディングとの使い分け

LightGBM が内部でカテゴリを処理できるため基本的には不要ですが、種類が数千〜数万と極端に多い 場合はメモリ不足や過学習が顕著になることがあります。その際は以下の手順で検討してください。

  1. まずは標準の category 型処理を試す
  2. メモリ使用量や過学習の程度が問題になる場合に、ターゲットエンコーディングで数値化 する
  3. ターゲットエンコーディングは情報漏洩を防ぐため、必ず交差検証の枠組みで変換(例:K‑Fold ターゲットエンコーディング)する

category_encoders ライブラリの TargetEncoder を利用すると、K‑Fold によるリーク防止が容易になります。学習データで統計量を算出し、テストデータは同じ統計量で変換してください。エンコード後の列は数値型として扱われる点に注意してください。


まとめ

  • category 型への変換 が最もシンプルでミスが少なく、実務ではまずこちらを推奨します。
  • 整数化して categorical_feature を明示すれば同様にカテゴリとして扱えますが、列の順序が変わったときのバグに注意が必要です。
  • ワンホットエンコーディングは不要 で、メモリと学習時間の削減が期待できます(削減効果はデータ規模とカーディナリティに依存)。
  • カテゴリ列が 数百列以上 になるケースでは max_cat_to_onehot の調整や重要度ベースでの事前削除を検討してください。
  • 高カーディナリティ や木の深さ、ハイパーパラメータ(cat_l2cat_smooth など)との相互作用を意識すれば、精度向上 も期待できます。
  • 高カーディナリティや低頻度カテゴリ は「その他」への集約やターゲットエンコーディングで対処し、過学習リスクに注意しましょう。
  • 学習後は 特徴量重要度(情報増加量) を確認し、不要な列を除外することでモデルの軽量化と解釈性向上が図れます。

LightGBM のカテゴリ取り扱い機能と特徴量選択テクニックを正しく活用すれば、前処理の手間を大幅に削減しつつ、モデルの性能と学習速度を同時に改善できます。ぜひ本稿の手順を自分のデータに適用し、実務のデータサイエンス業務で活用してください。