AdaBoost (classification)

2.4.3

AdaBoost (classification)

อัปเดต 2020-02-26 อ่าน 2 นาที
สรุป
  • AdaBoost สำหรับงานจำแนกจะฝึก weak learner แบบลำดับขั้น โดยเพิ่มน้ำหนักให้ตัวอย่างที่ทำนายผิดในรอบก่อนหน้า.
  • การตั้งค่า learning_rate และ n_estimators มีผลโดยตรงต่อความเร็วการเรียนรู้และความเสี่ยง overfitting.
  • เมื่อใช้ต้นไม้ตื้นเป็นตัวเรียนพื้นฐาน โมเดลรวมจะค่อยๆ แก้ขอบเขตการจำแนกที่ยากได้ดีขึ้น.

สัญชาตญาณ #

หัวใจของ AdaBoost คือการย้อนกลับไปแก้ข้อผิดพลาดเดิมในแต่ละรอบ แม้ตัวเรียนแต่ละตัวจะไม่ซับซ้อน แต่เมื่อรวมผลแบบถ่วงน้ำหนักแล้วจะได้ตัวจำแนกที่แข็งแรงขึ้นอย่างชัดเจน.

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

AdaBoost สำหรับการจำแนก | จากแนวคิดสู่สูตรและโค้ด #

AdaBoost เป็นอัลกอริทึม Boosting ที่ให้น้ำหนักใหม่กับตัวอย่างที่โมเดลก่อนหน้าทำผิด แล้วฝึกตัวเรียนรู้แบบอ่อน (weak learner) ตัวถัดไปให้โฟกัสจุดยากมากขึ้น เมื่อรวม weak learner จำนวนมากเข้าด้วยกันจะได้ตัวจำแนกที่แข็งแรง


1. ภาพรวมเชิงสัญชาติญาณ #

  1. โมเดลตัวแรกฝึกบนข้อมูลที่ให้น้ำหนักเท่ากันทุกตัวอย่าง
  2. มองหาตัวอย่างที่ทำนายผิด เพิ่มน้ำหนักให้จุดเหล่านั้น
  3. ฝึก weak learner ตัวใหม่โดยให้จุดที่มีน้ำหนักมากมีผลกระทบต่อ loss มากขึ้น
  4. ทำซ้ำ T รอบ จากนั้นรวมผลด้วยการโหวตแบบถ่วงน้ำหนัก (ค่าถ่วงคือ \(\alpha_t\) ที่ขึ้นกับความแม่นของโมเดลย่อย)

2. สูตรสำหรับกรณีสองคลาส #

ให้ป้าย \(y_i \in {-1, +1}\) และ weak learner \(h_t(x) \in {-1, +1}\)

  • คำนวณอัตราความผิดพลาดแบบถ่วงน้ำหนัก $$ \varepsilon_t = \frac{\sum_i w_i^{(t)} \,\mathbf{1}[y_i \ne h_t(x_i)]}{\sum_i w_i^{(t)}} $$
  • น้ำหนักของ weak learner $$ \alpha_t = \tfrac{1}{2}\ln\frac{1-\varepsilon_t}{\varepsilon_t} $$
  • อัปเดตน้ำหนักตัวอย่าง $$ w_i^{(t+1)} = w_i^{(t)} \exp\!\big(\alpha_t\,\mathbf{1}[y_i \ne h_t(x_i)]\big) $$

การพยากรณ์สุดท้าย

$$ H(x) = \operatorname{sign}\!\bigg(\sum_{t=1}^T \alpha_t\, h_t(x)\bigg) $$

3. มุมมองผ่านมาร์จินและ loss #

AdaBoost ลด exponential loss

$$ \mathcal{L} = \sum_{i=1}^n \exp(-y_i F(x_i)), \qquad F(x) = \sum_t \alpha_t h_t(x) $$

มาร์จิน \(m_i = y_i F(x_i)\) ใหญ่แปลว่าโมเดลมั่นใจและถูกต้อง Loss จะเล็ก ส่วนมาร์จินเล็กหรือติดลบจะโดนลงโทษหนัก

ใน scikit-learn มี algorithm="SAMME" (ใช้เมื่อโมเดลย่อยให้ผลเป็นฉลาก) และ algorithm="SAMME.R" (ใช้ผลจาก predict_proba). ค่า default คือ SAMME.R และรองรับหลายคลาส


4. ตัวอย่างโค้ด #

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, RocCurveDisplay
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier

X, y = make_classification(
    n_samples=2500,
    n_features=20,
    n_informative=10,
    n_redundant=4,
    n_clusters_per_class=5,
    random_state=42,
)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.33, random_state=42
)

base = DecisionTreeClassifier(max_depth=2, random_state=117117)

clf = AdaBoostClassifier(
    estimator=base,
    n_estimators=50,
    learning_rate=0.5,
    algorithm="SAMME.R",
    random_state=117117,
).fit(X_train, y_train)

y_score = clf.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_score)
print(f"ROC-AUC: {auc:.3f}")

RocCurveDisplay.from_predictions(y_test, y_score)
plt.grid(alpha=0.3)
plt.show()

5. ผลของไฮเปอร์พารามิเตอร์ #

  • learning_rate: เล็กลงจะทำให้แต่ละ weak learner มีค่าน้ำหนักน้อยลง ต้องเพิ่ม n_estimators เพื่อชดเชย
  • n_estimators: เพิ่มจำนวนโมเดลย่อย เพื่อประสิทธิภาพสูงขึ้น แต่ระวัง overfitting/เวลาเรียนรู้นาน
  • base_estimator: โดยมากใช้ decision tree ลึก 1–3 ระดับ (stumps) เพื่อให้เป็น “weak learner” จริง ๆ

สามารถวาดกราฟ learning_rate หรือนับจำนวน estimator เพื่อดูแนวโน้ม AUC ได้เหมือนในตัวอย่างต้นฉบับ


6. เชิงปฏิบัติ #

  • ใช้ sample_weight หรือ class_weight เมื่อคลาสไม่สมดุล
  • ถ้าต้องใช้ความน่าจะเป็นที่ calibrate ดีขึ้น ให้ต่อด้วย CalibratedClassifierCV
  • ตรวจ curve ของ train/test เพื่อตรวจจับ overfitting (เพิ่ม n_estimators หรือปรับ learning_rate)
  • ใช้ ROC-AUC หรือ PR-AUC เพื่อประเมินในงานที่ต้องการค่าความน่าจะเป็น