Gradient Boosting (พื้นฐาน)

Basic

พื้นฐาน Gradient Boosting | แนวคิด สูตร และตัวอย่าง

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
from sklearn.ensemble import GradientBoostingRegressor

พื้นฐาน Gradient Boosting #

Gradient Boosting ทั่วไปกว่า AdaBoost โดยใช้ “กราดิเอนต์ของฟังก์ชันสูญเสีย” เป็นตัวชี้นำในการเพิ่ม weak learner ทีละตัว เลือก loss ได้อิสระจึงนำไปใช้กับงาน regression, classification, quantile prediction ได้


1. สัญชาติญาณ: เติม residual ไปทีละน้อย #

  1. เริ่มจากโมเดลง่าย ๆ เช่น ค่าเฉลี่ย
  2. คำนวณ residual (ค่าที่เหลือ) ระหว่างคำตอบจริงกับโมเดลปัจจุบัน
  3. ฝึก weak learner ตัวใหม่ให้เรียน residual แล้วบวกกลับไปด้วย learning rate
  4. ทำซ้ำ ⇒ เหมือนเติมส่วนที่ขาดทีละนิดจนฟิตกับข้อมูล

AdaBoost เน้นเพิ่มน้ำหนักตัวอย่างที่ผิด ส่วน Gradient Boosting ใช้ “กราดิเอนต์ของ loss” เป็นตัวแก้ไข


2. สูตรแบบทั่วไป (กรณี regression) #

ให้ (L = \sum_i \ell(y_i, F(x_i)))

  1. โมเดลเริ่มต้น
    (F_0(x) = \arg\min_c \sum_i \ell(y_i, c)) (เช่น ค่าเฉลี่ยเมื่อเป็น squared error)
  2. รอบที่ (m):
    • คำนวณ pseudo residual
      (r_{im} = - \left[\frac{\partial \ell(y_i, F(x_i))}{\partial F(x_i)}\right]{F=F{m-1}})
    • ฝึก weak learner (h_m(x)) ด้วย (r_{im})
    • หา step size
      (\rho_m = \arg\min_\rho \sum_i \ell(y_i, F_{m-1}(x_i) + \rho,h_m(x_i)))
    • อัปเดต
      (F_m(x) = F_{m-1}(x) + \nu,\rho_m, h_m(x)) ( (\nu) = learning rate )

3. ตัวอย่าง: ฟิตเส้นโค้งที่ไม่เชิงเส้น #

X = np.linspace(-10, 10, 500)[:, np.newaxis]
noise = np.random.rand(X.shape[0]) * 10
y = (
    (np.sin(X).ravel() + np.cos(4 * X).ravel()) * 10
    + 10
    + np.linspace(-10, 10, 500)
    + noise
)

reg = GradientBoostingRegressor(
    n_estimators=50,
    learning_rate=0.5,
    max_depth=3,
    random_state=42,
)
reg.fit(X, y)
y_pred = reg.predict(X)

plt.figure(figsize=(10, 5))
plt.scatter(X, y, c="k", marker="x", alpha=0.5, label="train data")
plt.plot(X, y_pred, c="r", label="prediction", linewidth=1.2)
plt.legend(); plt.show()

การฟิตเส้นโค้งด้วย Gradient Boosting


4. เปรียบเทียบ loss #

GradientBoostingRegressor รองรับหลาย loss

  • squared_error: ไวต่อ outlier
  • absolute_error: ทนต่อ outlier มากกว่า
  • huber: ผสมระหว่างสองแบบ
  • quantile: ใช้พยากรณ์ช่วง (prediction interval)

โค้ดเดิมมีตัวอย่างการเปรียบเทียบ loss รวมถึงรูปผลลัพธ์


5. เคล็ดลับใช้งาน #

  • learning_rate × n_estimators มีความสัมพันธ์กัน: ลด learning_rate แล้วเพิ่มจำนวนรอบเพื่อความนิ่ง
  • max_depth ของต้นไม้ย่อย (หรือ max_leaf_nodes) มีผลอย่างมาก ค่า default 3 มักให้ผลดี
  • ใช้ early_stopping หรือ validation set เพื่อหยุดเมื่อสกอร์ไม่ดีขึ้น
  • เลือก loss ให้ตรงกับข้อมูล: มี outlier เยอะให้ลอง huber หรือ absolute_error
  • ข้อมูลจำนวนมากสามารถลอง HistGradientBoostingRegressor, XGBoost, LightGBM เพื่อประสิทธิภาพสูงกว่า

สรุป #

  • Gradient Boosting คิดแบบ “เติม residual” โดยใช้กราดิเอนต์ของ loss
  • เลือก loss ได้อิสระ ทำให้ใช้ในงานหลากหลาย
  • ปรับ learning_rate, n_estimators, depth อย่างระมัดระวัง และใช้ early stopping
  • โค้ดใน sklearn ทำให้เริ่มต้นได้เร็ว ก่อนต่อยอดไปยัง XGBoost/LightGBM/CatBoost