2.4.3
AdaBoost (classification)
- AdaBoost สำหรับงานจำแนกจะฝึก weak learner แบบลำดับขั้น โดยเพิ่มน้ำหนักให้ตัวอย่างที่ทำนายผิดในรอบก่อนหน้า.
- การตั้งค่า
learning_rateและn_estimatorsมีผลโดยตรงต่อความเร็วการเรียนรู้และความเสี่ยง overfitting. - เมื่อใช้ต้นไม้ตื้นเป็นตัวเรียนพื้นฐาน โมเดลรวมจะค่อยๆ แก้ขอบเขตการจำแนกที่ยากได้ดีขึ้น.
สัญชาตญาณ #
หัวใจของ AdaBoost คือการย้อนกลับไปแก้ข้อผิดพลาดเดิมในแต่ละรอบ แม้ตัวเรียนแต่ละตัวจะไม่ซับซ้อน แต่เมื่อรวมผลแบบถ่วงน้ำหนักแล้วจะได้ตัวจำแนกที่แข็งแรงขึ้นอย่างชัดเจน.
คำอธิบายโดยละเอียด #
AdaBoost สำหรับการจำแนก | จากแนวคิดสู่สูตรและโค้ด #
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 เพื่อประเมินในงานที่ต้องการค่าความน่าจะเป็น