AdaBoost เป็นอัลกอริทึม Boosting ที่ให้น้ำหนักใหม่กับตัวอย่างที่โมเดลก่อนหน้าทำผิด แล้วฝึกตัวเรียนรู้แบบอ่อน (weak learner) ตัวถัดไปให้โฟกัสจุดยากมากขึ้น เมื่อรวม weak learner จำนวนมากเข้าด้วยกันจะได้ตัวจำแนกที่แข็งแรง
1. ภาพรวมเชิงสัญชาติญาณ #
- โมเดลตัวแรกฝึกบนข้อมูลที่ให้น้ำหนักเท่ากันทุกตัวอย่าง
- มองหาตัวอย่างที่ทำนายผิด เพิ่มน้ำหนักให้จุดเหล่านั้น
- ฝึก weak learner ตัวใหม่โดยให้จุดที่มีน้ำหนักมากมีผลกระทบต่อ loss มากขึ้น
- ทำซ้ำ 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 เพื่อประเมินในงานที่ต้องการค่าความน่าจะเป็น
สรุป #
- AdaBoost = การเน้นจุดที่ยากขึ้นเรื่อย ๆ + การรวมเสียงแบบถ่วงน้ำหนัก
- มีพื้นฐานจากการเพิ่มมาร์จินและลด exponential loss
- ปรับ
learning_rate × n_estimators × ความลึกของต้นไม้ให้เหมาะ - ใช้ได้ดีกับข้อมูลที่มี noise ปานกลางและแสดงผลผ่านกราฟได้ง่าย