Gradient Boosting (พื้นฐาน)

2.4.5

Gradient Boosting (พื้นฐาน)

อัปเดต 2020-03-25 อ่าน 2 นาที
สรุป
  • สรุปเป้าหมาย สมมติฐาน และเงื่อนไขที่เหมาะสมของวิธีนี้.
  • ตรวจสอบว่ากฎการอัปเดตหรือเกณฑ์การแบ่งส่งผลต่อพฤติกรรมโมเดลอย่างไร.
  • ใช้ตัวอย่างโค้ดเพื่อกำหนดแนวทางปรับพารามิเตอร์อย่างเป็นรูปธรรม.

สัญชาตญาณ #

พื้นฐาน Gradient Boosting ควรเข้าใจผ่านสมมติฐาน กลไกการปรับปรุงโมเดล และรูปแบบความผิดพลาดบนข้อมูลจริง เพื่อให้เลือกโมเดลและปรับพารามิเตอร์ได้อย่างเหมาะสม.

คำอธิบายโดยละเอียด #

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 เพื่อประสิทธิภาพสูงกว่า