ยินดีต้อนรับสู่โลกของ Decision Trees (แผนภาพต้นไม้ตัดสินใจ)!
ในบทนี้ เราจะมาเรียนรู้วิธี "ปลูก" Decision Tree ขึ้นมาจริงๆ และที่สำคัญกว่านั้นคือ วิธี "ตัดแต่งกิ่ง" เพื่อให้มันทำงานได้อย่างแม่นยำกับข้อมูลใหม่ ลองจินตนาการว่า Decision Tree เหมือนกับต้นไม้จริงๆ ถ้าคุณปล่อยให้มันโตไปเรื่อยๆ โดยไม่มีการดูแล มันก็จะกลายเป็นพุ่มไม้ที่รกรุงรังจนจัดการยาก แต่ถ้าคุณคอยตัดแต่งกิ่งอย่างระมัดระวัง มันจะกลายเป็นเครื่องมือที่สวยงามและทรงพลังสำหรับการพยากรณ์ข้อมูล
นักคณิตศาสตร์ประกันภัย (Actuaries) ชื่นชอบ Decision Trees มาก เพราะมันอธิบายให้ผู้มีส่วนได้ส่วนเสีย (เช่น หัวหน้าหรือลูกค้า) เข้าใจได้ง่าย และรูปแบบการทำงานของมันก็คล้ายกับวิธีที่มนุษย์ใช้ตัดสินใจในชีวิตประจำวัน มาเริ่มลุยกันเลย!
ทบทวนสั้นๆ: อย่าลืมว่า Decision Tree จะแบ่งข้อมูลของคุณออกเป็นกลุ่มต่างๆ (ที่เรียกว่า nodes) ตามค่าของตัวแปรต้น (input variables) และกลุ่มสุดท้ายที่อยู่ปลายสุดของกิ่งเรียกว่า leaves หรือ terminal nodes
ขั้นตอนที่ 1: การสร้างต้นไม้ (Recursive Binary Splitting)
เมื่อเราเริ่มสร้างต้นไม้ เราจะใช้กระบวนการที่เรียกว่า Recursive Binary Splitting ฟังดูชื่ออาจจะน่ากลัว แต่อย่าเพิ่งกังวลไปครับ จริงๆ แล้วมันเรียบง่ายมากถ้าเราแยกย่อยออกมา:
1. Recursive (แบบเรียกซ้ำ): เราทำกระบวนการเดิมซ้ำไปเรื่อยๆ ในทุกกิ่งก้านที่เกิดขึ้น
2. Binary (แบบทวิภาค): ในแต่ละจุดแยก จะแบ่งออกเป็นเพียง สอง กิ่งเท่านั้น (เช่น "ใช่" หรือ "ไม่ใช่")
3. Splitting (การแบ่ง): เรากำลังแยกข้อมูลออกเป็นกลุ่มที่เล็กลงเรื่อยๆ
กลยุทธ์แบบ "Greedy" (เห็นแก่ได้):
การสร้างต้นไม้เป็นอัลกอริทึมแบบ greedy หมายความว่าในทุกขั้นตอน คอมพิวเตอร์จะมองหา การแบ่งที่ดีที่สุดเพียงจุดเดียว ที่ทำได้ ในขณะนั้น เพื่อให้โมเดลดีขึ้น โดยมันจะไม่มองไปข้างหน้าว่าการแบ่งที่ดู "แย่กว่า" เล็กน้อยในตอนนี้ อาจนำไปสู่การแบ่งที่ดีกว่ามากในอนาคตหรือไม่ มันคือการทำทุกอย่างให้ดีที่สุด ณ วินาทีนั้นนั่นเอง!
เราจะตัดสินใจได้อย่างไรว่าการแบ่งไหนคือ "สิ่งที่ดีที่สุด"?
คำตอบขึ้นอยู่กับว่าเรากำลังพยายามพยากรณ์อะไร:
สำหรับ Regression Trees (พยากรณ์ค่าที่เป็นตัวเลข):
เราต้องการลดค่า Residual Sum of Squares (RSS) ให้เหลือน้อยที่สุด เราต้องการให้จุดข้อมูลในแต่ละ leaf มีค่าใกล้เคียงกับค่าเฉลี่ยของกลุ่มนั้นให้ได้มากที่สุด สูตรจะเป็นดังนี้:
\( RSS = \sum_{j=1}^{J} \sum_{i \in R_j} (y_i - \hat{y}_{R_j})^2 \)
อธิบายง่ายๆ: เราต้องการทำให้ผลรวมของ "ข้อผิดพลาด" กำลังสองในทุกๆ พื้นที่ (region) ปลายทาง (\( R_j \)) มีค่าน้อยที่สุด
สำหรับ Classification Trees (พยากรณ์ประเภทข้อมูล):
เราต้องการให้กลุ่มที่ได้มีความ "บริสุทธิ์" (pure) ถ้าในหนึ่ง leaf มีข้อมูล "ประเภท A" 100% และ "ประเภท B" 0% แสดงว่ามันบริสุทธิ์สมบูรณ์แบบ เรามักจะวัดค่านี้ด้วย Gini Index หรือ Entropy โดยค่าที่ต่ำกว่าจะหมายความว่ากลุ่มนั้นมีความ "บริสุทธิ์" มากกว่า
รู้หรือไม่? Gini Index มักถูกเรียกว่าการวัดค่า ความไม่บริสุทธิ์ของ node (node impurity) หาก Gini Index เป็น 0 แสดงว่า node นั้นบริสุทธิ์อย่างสมบูรณ์ (ทุกคนในกลุ่มเป็นประเภทเดียวกันหมด)
สรุปใจความสำคัญ: เราสร้างต้นไม้จากบนลงล่าง ทีละการแบ่ง โดยเลือกการแบ่งที่ลดค่าความผิดพลาด (RSS) หรือลดความไม่บริสุทธิ์ (Gini/Entropy) ได้มากที่สุด ณ เวลานั้น
ขั้นตอนที่ 2: อันตรายจากการเติบโตมากเกินไป
ถ้าเราแบ่งข้อมูลไปเรื่อยๆ จนกระทั่งข้อมูลทุกตัวในชุดข้อมูลของเรามี leaf เป็นของตัวเอง เราจะได้อัตราความผิดพลาด 0% ในข้อมูลชุด training แต่มันมีปัญหาใหญ่ที่ตามมาคือ: Overfitting (การเรียนรู้เกินพอดี)
Overfitting คือการที่ต้นไม้เรียนรู้ "สัญญาณรบกวน" (noise) หรือลักษณะเฉพาะตัวที่สุ่มเกินไปในชุดข้อมูลของคุณ แทนที่จะเรียนรู้รูปแบบที่แท้จริง ต้นไม้ที่ Overfit ก็เหมือนกับนักเรียนที่จำคำตอบข้อสอบเก่าได้แม่นยำทุกข้อ แต่ไม่เข้าใจหลักคณิตศาสตร์จริงๆ เมื่อเจอข้อสอบจริงที่มีตัวเลขเปลี่ยนไป นักเรียนคนนั้นก็จะทำไม่ได้!
การแลกเปลี่ยนระหว่าง Bias และ Variance (Bias-Variance Tradeoff):
- ต้นไม้ขนาดใหญ่และซับซ้อนจะมี High Variance (มันจะเปลี่ยนไปมหาศาลถ้าคุณเปลี่ยนข้อมูลเพียงเล็กน้อย)
- ต้นไม้ขนาดจิ๋วที่มีการแบ่งเพียงครั้งเดียวจะมี High Bias (มันเรียบง่ายเกินไปที่จะจับรูปแบบที่แท้จริงได้)
ขั้นตอนที่ 3: การตัดแต่งกิ่ง (Cost-Complexity Pruning)
เพื่อแก้ปัญหา Overfitting เราจะสร้างต้นไม้ขนาดใหญ่ขึ้นมาก่อน แล้วค่อย "ตัดแต่ง" มันกลับมาเพื่อหา subtree (ต้นไม้ย่อย) ที่เหมาะสมกว่า แต่เราไม่สามารถเลือก subtrees แบบสุ่มได้หรอกนะ! เพราะมันมีตัวเลือกเยอะเกินไป เราจึงใช้ Cost-Complexity Pruning (หรือที่รู้จักกันในชื่อ Weakest Link Pruning)
เราใช้คะแนนพิเศษในการตัดสินใจว่าจะตัดกิ่งไหน สูตรของคะแนนคือ:
\( \sum_{m=1}^{|T|} \sum_{i \in R_m} (y_i - \hat{y}_{R_m})^2 + \alpha|T| \)
ลองมาแยกส่วนสูตรนี้ใน "ภาษานักคณิตศาสตร์ประกันภัย" กัน:
1. ส่วนแรก \( \sum \sum (y_i - \hat{y}_{R_m})^2 \) คือค่า RSS (บอกว่าต้นไม้ fit กับข้อมูลดีแค่ไหน)
2. ส่วนที่สอง \( \alpha|T| \) คือค่า บทลงโทษ (Penalty)
- \( |T| \) คือจำนวน terminal nodes (leaves) ยิ่งมี leaf มาก ความซับซ้อนก็ยิ่งมาก
- \( \alpha \) (อัลฟ่า) คือ tuning parameter เป็นตัวเลขที่เราเลือกเพื่อควบคุมว่าเราจะ "ลงโทษ" ต้นไม้ที่ซับซ้อนเกินไปมากแค่ไหน
วิธีที่ \(\alpha\) ทำงาน:
- ถ้า \( \alpha = 0 \): ไม่มีการลงโทษ! เราจะได้ต้นไม้ขนาดใหญ่ต้นเดิม
- ถ้า \( \alpha \) มีค่าสูงมาก: บทลงโทษจะมหาศาล! เราจะเหลือต้นไม้ขนาดจิ๋ว (อาจเหลือแค่ node เดียว)
- เมื่อเราเพิ่มค่า \( \alpha \) จากศูนย์ กิ่งก้านจะถูกตัดออกไปทีละส่วนตามลำดับที่คาดการณ์ได้
เทคนิคช่วยจำ: ลองคิดว่า \( \alpha \) คือ "ภาษี" ที่ต้องจ่ายสำหรับ leaf ถ้าภาษีต่ำ ต้นไม้ก็จะมี leaf ได้เยอะ แต่ถ้าภาษีสูง ต้นไม้ต้องลดขนาดลงเพื่อให้ "อยู่รอด" ได้
สรุปใจความสำคัญ: การตัดแต่งกิ่งช่วยให้เราพบความสมดุลระหว่างต้นไม้ที่เรียบง่ายเกินไปกับต้นไม้ที่ซับซ้อนเกินไป โดยเราใช้ตัวแปรควบคุม \( \alpha \) ในการปรับสมดุลนี้
ขั้นตอนที่ 4: การเลือกค่า Alpha (\(\alpha\)) ที่ดีที่สุด
เราจะรู้ได้อย่างไรว่าควรใช้ค่า \(\alpha\) เท่าไหร่? คำตอบคือใช้ K-Fold Cross-Validation!
1. แบ่งข้อมูลของคุณออกเป็น \( K \) ส่วน (folds)
2. สำหรับค่า \(\alpha\) แต่ละค่า ให้สร้างต้นไม้จากข้อมูลบางส่วนแล้วนำไปทดสอบกับส่วนที่เหลือ
3. เลือกค่า \(\alpha\) ที่ให้ ค่าความผิดพลาดเฉลี่ยต่ำที่สุด ในช่วงข้อมูลทดสอบ
ข้อผิดพลาดที่พบบ่อย: อย่าเลือกค่า \(\alpha\) ที่ทำให้ต้นไม้ดูดีที่สุดในชุดข้อมูล training ของคุณ ให้ใช้ข้อมูล validation หรือใช้ Cross-Validation ในการเลือก \(\alpha\) เสมอ ไม่อย่างนั้นคุณก็จะกลับไปติดหลุมพรางของ Overfitting อีกครั้ง!
สรุปขั้นตอนแบบ Step-by-Step
ไม่ต้องกังวลถ้าดูเหมือนมีหลายขั้นตอน นี่คือสูตรสำเร็จในการสร้างต้นไม้ที่ดี:
1. ใช้ Recursive Binary Splitting เพื่อสร้างต้นไม้ขนาดใหญ่จากข้อมูล training (หยุดเมื่อ node เล็กมากเท่านั้น)
2. ใช้ Cost-Complexity Pruning เพื่อค้นหาลำดับของ subtrees ที่ดีที่สุดตามค่า \(\alpha\)
3. ใช้ K-Fold Cross-Validation เพื่อเลือกค่า \(\alpha\) ที่เหมาะสมที่สุด
4. เลือก subtree จากขั้นตอนที่ 2 ที่สอดคล้องกับค่า \(\alpha\) ที่คุณเลือก
สรุปทบทวนครั้งสุดท้าย
- กลยุทธ์การสร้าง: จากบนลงล่าง, Greedy, Recursive Binary Splitting
- เป้าหมาย Regression: ลดค่า RSS ให้ต่ำที่สุด
- เป้าหมาย Classification: ลดค่า Gini Index หรือ Entropy ให้ต่ำที่สุด
- ปัญหา: ต้นไม้ขนาดใหญ่ทำให้เกิด Overfitting (High Variance)
- ทางแก้: ตัดแต่งกิ่งโดยใช้เทอมบทลงโทษ \(\alpha|T|\)
- การปรับจูน: ใช้ Cross-Validation ในการคัดเลือกค่า \(\alpha\) ที่ดีที่สุด
คุณทำได้อยู่แล้ว! Decision Trees ก็แค่เรื่องของการแบ่งข้อมูลให้ดีที่สุดเท่าที่จะทำได้ แล้วค่อยจัดการเก็บกวาดให้เรียบร้อย เพื่อให้มั่นใจว่าโมเดลจะยังคง "ฉลาด" อยู่เสมอเมื่อเจอกับข้อมูลใหม่ๆ