LightGBM

Basic

LightGBM | หลักการและแนวทางการปรับแต่ง

LightGBM คือไลบรารี gradient boosting ที่เร็วจาก Microsoft ด้วย histogram approximation และการเติบโตแบบ leaf-wise ทำให้ฝึกได้เร็วขึ้น โดยยังรักษาความแม่นยำกับข้อมูลขนาดใหญ่และมิติสูง

รองรับ GPU, การจัดการตัวแปรเชิงหมวดหมู่แบบ native และ distributed learning จึงนิยมทั้งใน Kaggle และงานจริง


1. จุดเด่นของ LightGBM #

  • Leaf-wise growth: ขยายใบที่ทำให้ loss ดีขึ้นมากที่สุด ควบคุมด้วย max_depth หรือ num_leaves
  • Histogram approximation: จัดค่าต่อเนื่องเป็น bin (เช่น 256) เพื่อลดเวลาและหน่วยความจำ
  • Reuse gradient/Hessian: รวมสถิติตาม bin เพื่อให้ cache ทำงานดีขึ้น
  • รองรับหมวดหมู่แบบ native: หา split แบบไบนารีที่เหมาะสมโดยไม่ต้อง one-hot
  • ฟีเจอร์พร้อมใช้งานจริง: early stopping, weight, monotonic constraints, GPU

2. สมการพื้นฐาน #

เหมือน gradient boosting ทั่วไป คือเพิ่มตัวเรียนรู้ตาม negative gradient

$$ \mathcal{L} = \sum_{i=1}^n \ell\big(y_i, F_{m-1}(x_i) + f_m(x_i)\big) + \Omega(f_m) $$

LightGBM รวมกราเดียนต์ \(g_i\) และเฮสเซียน \(h_i\) ตาม histogram bin แล้วคำนวณ gain:

$$ \text{Gain} = \frac{1}{2} \left( \frac{\left(\sum_{i \in L} g_i\right)^2}{\sum_{i \in L} h_i + \lambda} + \frac{\left(\sum_{i \in R} g_i\right)^2}{\sum_{i \in R} h_i + \lambda} - \frac{\left(\sum_{i \in (L \cup R)} g_i\right)^2}{\sum_{i \in (L \cup R)} h_i + \lambda} \right) - \gamma $$

\(\lambda\) คือ L2 regularization และ \(\gamma\) คือค่าปรับสำหรับการ split


3. ตัวอย่างการทำ binary classification #

import lightgbm as lgb
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, roc_auc_score

X, y = make_classification(
    n_samples=30_000,
    n_features=40,
    n_informative=12,
    n_redundant=8,
    weights=[0.85, 0.15],
    random_state=42,
)

X_train, X_valid, y_train, y_valid = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42
)

params = {
    "objective": "binary",
    "metric": ["binary_logloss", "auc"],
    "learning_rate": 0.05,
    "num_leaves": 31,
    "feature_fraction": 0.8,
    "bagging_fraction": 0.8,
    "bagging_freq": 5,
    "lambda_l2": 1.0,
    "min_data_in_leaf": 30,
}

train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_valid, label=y_valid)

gbm = lgb.train(
    params,
    train_data,
    num_boost_round=1000,
    valid_sets=[train_data, valid_data],
    valid_names=["train", "valid"],
    callbacks=[lgb.early_stopping(stopping_rounds=50, verbose=True)],
)

y_pred = gbm.predict(X_valid)
print("ROC-AUC:", roc_auc_score(y_valid, y_pred))
print(classification_report(y_valid, (y_pred > 0.5).astype(int)))

เมื่อใช้ early stopping จะสามารถตั้ง num_boost_round สูงได้โดยไม่ overfit


4. ไฮเปอร์พารามิเตอร์หลัก #

พารามิเตอร์บทบาท / เคล็ดลับ
num_leavesจำนวนใบ กำหนดขนาดโมเดล เพิ่มแบบค่อยเป็นค่อยไปโดยไม่เกิน 2 ** max_depth
max_depthจำกัดความลึก -1 คือไม่จำกัด แต่ค่าต่ำช่วยลด overfitting
min_data_in_leaf / min_sum_hessian_in_leafจำนวนตัวอย่าง/เฮสเซียนขั้นต่ำต่อใบ ค่าสูงขึ้นจะเรียบขึ้น
learning_rateยิ่งต่ำยิ่งเสถียร แต่ต้องใช้ต้นไม้มากขึ้น
feature_fractionสุ่มฟีเจอร์เพื่อช่วย generalization
bagging_fraction & bagging_freqสุ่มแถวข้อมูล ใช้เมื่อ bagging_freq > 0
lambda_l1, lambda_l2L1/L2 regularization
min_gain_to_splitgain ขั้นต่ำสำหรับ split เพื่อลด split จาก noise

5. หมวดหมู่และค่าหาย #

  • ส่งดัชนีหรือชื่อคอลัมน์เข้า categorical_feature ได้เลย ไม่ต้องทำ target encoding
  • ค่า missing จะถูกส่งไปสาขาเฉพาะ และอาจพิจารณาเติมค่าถ้ามีจำนวนมาก
  • ตั้ง monotonic constraints ได้ผ่าน monotone_constraints
categorical_cols = [0, 2, 5]
train_data = lgb.Dataset(
    X_train,
    label=y_train,
    categorical_feature=categorical_cols,
)

6. แนวทางการปรับแต่งแบบย่อ #

  1. Baseline: learning_rate=0.1, num_leaves=31, feature_fraction=1.0
  2. ปรับความจุ: ปรับ num_leaves และ min_data_in_leaf พร้อมดู loss ของ valid
  3. เพิ่มความสุ่ม: ตั้ง feature_fraction หรือ bagging_fraction ที่ 0.6–0.9
  4. Regularization: เพิ่ม lambda_l1/lambda_l2 หรือ min_gain_to_split
  5. ลด learning rate: ถ้าตัน ให้ลดลงเป็น 0.01 แล้วเพิ่ม num_boost_round
  6. Ensemble: รวม LightGBM หลายตัวด้วย seed ที่ต่างกัน

7. สรุป #

  • LightGBM ใช้ histogram และ leaf-wise growth เพื่อความเร็วและความแม่นยำ
  • ปรับ num_leaves และ learning_rate พร้อมใช้ regularization และ subsampling
  • รองรับหมวดหมู่ ค่าหาย และ GPU จึงเหมาะทั้งงานจริงและการทำ ensemble