ml/ library Learn by doing
ALGORITHM 22 · PYTHON / JAVASCRIPT

Bagging

ฝึกหลายโมเดลจากข้อมูลคนละชุดแล้วโหวต

LEARNING LEVEL2
ต่อยอดโดยตรงควรรู้มาก่อน · Decision Tree และ bootstrap sampling
ลองใน Playground

01Overall Concept

OVERALL CONCEPT

ไอเดียหลัก — Bagging สร้างโมเดลหลายตัวจากตัวอย่างข้อมูลคนละชุด แล้วให้ทุกตัวช่วยกันตอบ การรวมหลายความเห็นช่วยลดโอกาสที่ความบังเอิญในข้อมูลชุดเดียวจะพาโมเดลไปผิดทาง

ลองนึกภาพว่า — เหมือนให้เพื่อนหลายคนอ่านโจทย์จากแบบฝึกหัดที่สุ่มมาไม่เหมือนกัน แล้วขอให้ทุกคนลงคะแนนคำตอบ เสียงรวมมักนิ่งกว่าการเชื่อเพื่อนเพียงคนเดียว

ตัวอย่างการนำไปใช้ — ทำให้ Decision Tree ทำนายเสถียรขึ้น ลดความผันผวนของโมเดล หรือสร้างคำตอบรวมจากผู้เรียนหลายตัว

02อธิบายภาษาคนเข้าใจง่ายๆ

เล่าแบบไม่ใช้ศัพท์ยาก

Bagging ย่อมาจาก Bootstrap Aggregating

ชื่อฟังดูน่ากลัว แต่แนวคิดง่ายมาก

สมมติเรามีข้อมูลลูกค้า 10,000 คน

แทนที่จะสร้างโมเดลเดียว เราสุ่มข้อมูลออกมาเป็นหลายชุด

ชุด A ชุด B ชุด C ...

แล้วสร้างโมเดลหนึ่งตัวจากแต่ละชุด

สมมติสร้าง 100 โมเดล

ตอนมีลูกค้าใหม่เข้ามา เราถามทั้ง 100 โมเดล

60 ตัวตอบ “ซื้อ” 40 ตัวตอบ “ไม่ซื้อ”

ก็เลือกซื้อ

เหตุผลคือโมเดลแต่ละตัวอาจผิดคนละแบบ เมื่อเอามาเฉลี่ยกัน ความผิดพลาดบางอย่างจะหักล้างกัน

เหมือนการถามความคิดเห็นหลายคนแทนที่จะเชื่อผู้เชี่ยวชาญคนเดียว

Bagging มีประโยชน์มากกับโมเดลที่ผลลัพธ์เปลี่ยนง่ายเมื่อข้อมูลเปลี่ยน เช่น Decision Tree

ภาพจำ: คณะกรรมการหลายคนดูข้อมูลคนละชุด แล้วโหวต

03How it works

ค่อยๆ ทำไปด้วยกัน ตั้งแต่ข้อมูลแถวแรกจนถึงการตรวจคำตอบ

  1. เริ่มจากข้อมูลลูกค้าที่แบ่งชุดไว้แล้ว

    เตรียม X เป็นพฤติกรรมก่อนตัดสินใจซื้อ y เป็นซื้อ/ไม่ซื้อ และกัน test ไว้ก่อนสร้างถุงข้อมูล ทุกถุงต้องสุ่มจาก train เท่านั้น หากสุ่มก่อนแล้วค่อยแยก test อาจมีลูกค้าคนเดียวกันหลุดไปอยู่ทั้งฝั่งฝึกและตรวจจนคะแนนดูดีเกินจริง

  2. สร้างถุงที่มีคนซ้ำได้

    สมมติ train มีรหัส A, B, C, D ถุงหนึ่งอาจได้ A, A, C, D อีกถุงได้ B, C, C, D นี่คือ bootstrap หรือการสุ่มแบบใส่คืน จำนวนแถวต่อถุงอาจเท่าเดิม แต่คนในถุงต่างกัน แล้วฝึกโมเดลฐานหนึ่งตัวต่อถุง เช่นต้นไม้หนึ่งต้นต่อถุง

  3. รวมความคิดเห็นให้ตรงกับเครื่องมือ

    ในภาพง่ายๆ คือโหวตคลาส แต่ BaggingClassifier เมื่อสมาชิกมี predict_proba จะเฉลี่ยความน่าจะเป็นของสมาชิกแล้วเลือกคลาสที่ได้สูงสุด ไม่จำเป็นต้องเหมือนการนับคำตอบแข็งๆ ของทุกต้น หากสมาชิกไม่มี probability จึงใช้การโหวต ส่วน BaggingRegressor เฉลี่ยค่าตัวเลข

  4. เลือกจำนวนกรรมการกับข้อมูลที่ให้เห็น

    เริ่ม BaggingClassifier(estimator=DecisionTreeClassifier(min_samples_leaf=3), n_estimators=100, max_samples=0.8, bootstrap=True, random_state=42) แล้ว fit(X_train, y_train) n_estimators คือจำนวนสมาชิก max_samples=0.8 คือแต่ละถุงใช้จำนวนแถว 80% ของ train และ estimator กำหนดนิสัยของโมเดลฐาน

  5. ดูว่ารวมแล้วช่วยจริงหรือไม่

    เทียบ predict(X_test) กับต้นไม้เดี่ยวด้วย confusion matrix และเวลาทำนาย ลองเพิ่มสมาชิกจาก 20 เป็น 100 โดยคงอย่างอื่นไว้ ถ้า bootstrap=True สามารถเปิด oob_score=True เพื่อดูคะแนนจากแถวที่สมาชิกนั้นไม่ได้ฝึกด้วยได้ แต่ยังควรมี test สุดท้าย Bagging ช่วยลดความผันผวนได้มากขึ้นเมื่อสมาชิกผิดต่างกัน ไม่ได้แก้ข้อมูลผิดหรือ feature ที่รั่วได้

เปิดตัวอย่างโค้ดเพื่อลองทำตาม →ตัวอย่างตัวเลขในเรื่องใช้ช่วยอธิบาย ส่วนโค้ดและ Playground ใช้ชุดข้อมูลสาธิตของแต่ละหน้าอ่านเอกสารอ้างอิงของเทคนิคนี้ ↗

ข้อมูล พารามิเตอร์ และภาพรวมการคำนวณ

DATA INX · featuresy · targettrain = [A, B, C, D] → ถุงหนึ่ง [A, A, C, D]
CALCULATEBagging
n_estimatorsmax_samplesestimator
RESULT0.800.150.05class / probabilityBaggingClassifier + ต้นไม้ → เฉลี่ย probability แล้วเลือกคลาส
เส้นทางของข้อมูล: จากค่าที่รับเข้า ผ่านการคำนวณด้วยพารามิเตอร์ ไปเป็นผลลัพธ์
INPUT

ข้อมูลที่รับเข้ามา

รับ X และ y ตามชนิดของ base estimator จากนั้นสร้างชุดฝึกย่อยหลายชุดจากแถวหรือ feature ของข้อมูลเดิม

train = [A, B, C, D] → ถุงหนึ่ง [A, A, C, D]
PARAMETERS

พารามิเตอร์ที่ใช้

n_estimators
จำนวนโมเดลสมาชิกที่ฝึกและนำมารวม
max_samples
จำนวนหรือสัดส่วนแถวต่อหนึ่งสมาชิก
estimator
ชนิดโมเดลฐาน เช่น Decision Tree
OUTPUT

ผลลัพธ์ที่ได้

ได้คำทำนายรวมและสามารถดูผลของสมาชิกแต่ละตัวได้ ความผันผวนมักต่ำกว่าโมเดลเดี่ยว

BaggingClassifier + ต้นไม้ → เฉลี่ย probability แล้วเลือกคลาส
CALCULATION

คำนวณทีละขั้น

  1. 01

    สุ่ม bootstrap sample ด้วยการหยิบแถวแล้วใส่คืนให้แต่ละสมาชิก

  2. 02

    ฝึก base estimator แยกกันบนชุดสุ่ม ทำให้แต่ละตัวเรียนรู้กฎต่างกัน

  3. 03

    BaggingClassifier เฉลี่ย probability เมื่อสมาชิกมี predict_proba มิฉะนั้นโหวตคลาส; Regressor เฉลี่ยค่าตัวเลข

ควรรู้อีกนิด — โมเดลที่มี bias สูงจะไม่ได้ดีขึ้นมาก และจำนวนโมเดลเพิ่มต้นทุนคำนวณ

04Make it yours

Python · scikit-learn
# ติดตั้ง: pip install numpy scikit-learn matplotlibfrom sklearn.ensemble import BaggingClassifierfrom sklearn.metrics import accuracy_score from sklearn.datasets import make_classificationfrom sklearn.model_selection import train_test_split X, y = make_classification(    n_samples=150, n_features=2, n_redundant=0,    n_informative=2, n_classes=3, n_clusters_per_class=1,    class_sep=1.4, random_state=42,)X_train, X_test, y_train, y_test = train_test_split(    X, y, test_size=0.2, random_state=42, stratify=y) model = BaggingClassifier(n_estimators=11, random_state=42)model.fit(X_train, y_train)pred = model.predict(X_test)print("Accuracy:", accuracy_score(y_test, pred))

โค้ดเปลี่ยนตามค่าที่เลือกใน Playground · แต่ละภาษาใช้ข้อมูลตัวอย่างตามที่ระบุในโค้ด

05Learn by playing

ปรับ จำนวน estimators แล้วสังเกตรูปแบบคำทำนายและตัวชี้วัดที่คำนวณใหม่ทันที

Sample dataset / Three classes● คำนวณใหม่เมื่อปรับค่า
จำนวนโมเดลมากขึ้นลดความผันผวนของการโหวต
พื้นที่สีคือคำทำนาย จุดคือคำตอบจริงFeature x → · Feature y ↑ · ขอบเข้ม = ชุดทดสอบ
Test accuracy96.7%
ลักษณะการรวมเสียงข้างมาก
พารามิเตอร์ที่ลอง11

Playground เป็น implementation เพื่อการเรียนรู้ที่คำนวณในเบราว์เซอร์ ส่วนโค้ด Python ใช้ scikit-learn จึงอาจให้ค่าต่างกันเล็กน้อยจากรายละเอียดการ optimize และค่าเริ่มต้นของไลบรารี ผลนี้ไม่ใช่ benchmark บนข้อมูลจริง