2.4.7
LightGBM
まとめ
- LightGBMはMicrosoftが開発した勾配ブースティングライブラリで、ヒストグラム近似と葉優先(Leaf-wise)の木構築で大規模データを高速に処理する。
- カテゴリ変数のネイティブ処理、GPU学習、分散学習に対応し、前処理の手間を削減できる。
num_leaves・learning_rate・n_estimators・min_child_samplesが主なチューニング対象。
直感 #
通常の勾配ブースティングは木をレベルごとに均等に成長させるが、LightGBMは損失をもっとも減らせる葉を優先的に分割する(Leaf-wise)。これにより同じ木の数でも精度が出やすく、学習も速い。さらにヒストグラム近似で分割候補を大幅に減らすため、大規模データでも実用的な速度で動作する。
詳細な解説 #
ライブラリと実験データ #
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from lightgbm import LGBMClassifier
X, y = make_classification(
n_samples=1000, n_features=20, n_informative=10,
n_redundant=5, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
基本的な学習と評価 #
model = LGBMClassifier(
n_estimators=100,
num_leaves=31,
learning_rate=0.1,
random_state=42,
verbose=-1,
)
model.fit(X_train, y_train)
y_prob = model.predict_proba(X_test)[:, 1]
print(f"ROC-AUC: {roc_auc_score(y_test, y_prob):.4f}")
num_leavesの影響 #
num_leavesは木の最大葉数を制御します。大きくすると表現力が上がるが、過学習しやすくなります。max_depthよりも直接的にモデルの複雑さを決定するパラメーターです。
leaves_list = [8, 16, 31, 63, 127]
scores = []
for nl in leaves_list:
m = LGBMClassifier(
n_estimators=100, num_leaves=nl,
learning_rate=0.1, random_state=42, verbose=-1,
)
m.fit(X_train, y_train)
scores.append(roc_auc_score(y_test, m.predict_proba(X_test)[:, 1]))
plt.figure(figsize=(8, 4))
plt.plot(leaves_list, scores, "o-")
plt.xlabel("num_leaves")
plt.ylabel("ROC-AUC")
plt.title("num_leavesと精度の関係")
plt.grid(True)
plt.show()
learning_rateの影響 #
rates = [0.01, 0.05, 0.1, 0.3, 0.5]
scores = []
for lr in rates:
m = LGBMClassifier(
n_estimators=200, num_leaves=31,
learning_rate=lr, random_state=42, verbose=-1,
)
m.fit(X_train, y_train)
scores.append(roc_auc_score(y_test, m.predict_proba(X_test)[:, 1]))
plt.figure(figsize=(8, 4))
plt.plot(rates, scores, "o-")
plt.xlabel("learning_rate")
plt.ylabel("ROC-AUC")
plt.title("learning_rateと精度の関係")
plt.grid(True)
plt.show()
min_child_samplesの影響 #
葉ノードの最小サンプル数を増やすと、過学習を抑制できます。
min_samples = [5, 10, 20, 50, 100]
scores = []
for ms in min_samples:
m = LGBMClassifier(
n_estimators=100, num_leaves=31,
learning_rate=0.1, min_child_samples=ms,
random_state=42, verbose=-1,
)
m.fit(X_train, y_train)
scores.append(roc_auc_score(y_test, m.predict_proba(X_test)[:, 1]))
plt.figure(figsize=(8, 4))
plt.plot(min_samples, scores, "o-")
plt.xlabel("min_child_samples")
plt.ylabel("ROC-AUC")
plt.title("min_child_samplesと精度の関係")
plt.grid(True)
plt.show()
特徴量の重要度 #
importances = model.feature_importances_
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(10, 5))
plt.bar(range(len(importances)), importances[indices])
plt.xlabel("特徴量インデックス")
plt.ylabel("重要度(split)")
plt.title("LightGBM 特徴量重要度")
plt.show()
Level-wiseとLeaf-wiseの違い #
通常の勾配ブースティング(XGBoostのデフォルトなど)はLevel-wise、すなわち深さごとに全ノードを分割します。一方LightGBMはLeaf-wise、つまり損失をもっとも減らせる葉だけを分割します。
- Level-wise: バランスの取れた木になりやすく、過学習しにくい
- Leaf-wise: 同じ葉数ならより低い損失を達成できるが、深くなりすぎると過学習する
このため、LightGBMではmax_depthよりもnum_leavesでモデルの複雑さを制御するのが基本です。
- Gradient Boosting(回帰) — 勾配ブースティングの基礎
- XGBoost — 正則化重視の勾配ブースティング
- CatBoost — カテゴリ変数に強い勾配ブースティング