Machine Learning › พื้นฐาน ML และ scikit-learn
วัดผลโมเดล classification
ประมาณ 35 นาที
เป้าหมายของบท
- อ่าน confusion matrix และคำนวณ precision, recall, F1
- เข้าใจว่า ROC-AUC วัดการจัดอันดับโดยไม่ขึ้นกับ threshold
- รู้ทัน accuracy paradox เมื่อคลาสไม่สมดุล
accuracy อย่างเดียวไม่พอ
accuracy = สัดส่วนที่ทายถูก — ใช้ได้ดีเมื่อคลาสสมดุล แต่หลอกตาได้ง่ายเมื่อคลาสหนึ่งพบน้อยมาก (imbalanced) เพราะการทายคลาสส่วนใหญ่ทุกแถวก็ได้ accuracy สูงแล้ว
confusion matrix
ตารางนับผลการทำนายทั้ง 4 แบบ (คลาส 1 คือ “positive”):
| ทำนาย 0 | ทำนาย 1 | |
|---|---|---|
| จริง 0 | TN (ถูก) | FP (ทำนาย 1 ผิด) |
| จริง 1 | FN (พลาด) | TP (ถูก) |
from sklearn.metrics import confusion_matrix
tn, fp, fn, tp = confusion_matrix(y_test, pred).ravel()
precision, recall, F1
- precision = TP / (TP + FP) — ในกลุ่มที่ทำนายว่าเป็น 1 จริงๆ ถูกกี่ %
- recall = TP / (TP + FN) — ในกลุ่มที่เป็น 1 จริงๆ จับได้กี่ %
- F1 — ค่าเฉลี่ยแบบ harmonic ของ precision กับ recall (สูงเมื่อทั้งสองสูงพร้อมกัน)
precision กับ recall มักแลกกัน: ตั้งเกณฑ์ต่ำ → จับได้เยอะ (recall สูง) แต่ทายผิดเยอะ (precision ต่ำ) และกลับกัน
ROC-AUC
roc_auc_score(y_test, proba) วัดว่าโมเดล จัดอันดับ ได้ดีแค่ไหนโดยไม่ขึ้นกับ threshold — คือโอกาสที่ตัวอย่างคลาส 1 ที่สุ่มมาจะได้ความน่าจะเป็นสูงกว่าตัวอย่างคลาส 0 ที่สุ่มมา
0.5 = เดาสุ่ม, 1.0 = จัดอันดับสมบูรณ์แบบ
accuracy paradox: ตัวอย่างจริง
ลองทำนายว่าออเดอร์แรกของลูกค้า “ถูกยกเลิก” (พบเพียง ~6%) — ทายว่า “ไม่ยกเลิก” ทุกแถวได้ accuracy ~94% ทันที โมเดลที่ฝึกมาก็ได้เท่ากันเป๊ะ
แต่ recall = 0 (จับออเดอร์ที่ยกเลิกไม่ได้เลย) ตัวเลข accuracy สูงจึงไม่ได้แปลว่าโมเดลมีประโยชน์ ตัวเลือกหนึ่งคือ class_weight='balanced' ที่ให้น้ำหนักคลาสหายากมากขึ้น — ในข้อมูลนี้ recall เพิ่มจาก 0 เป็น 0.5778 แต่แลกด้วย precision เหลือ 0.0785 และ accuracy ตกเหลือ 0.5437 (เพราะทายเป็น “ยกเลิก” เยอะขึ้น)
ตัวอย่างแก้โจทย์
กด "ขั้นต่อไป" ทีละขั้น ลองรันและแก้โค้ดในแต่ละขั้นได้
confusion matrix และ precision/recall
โมเดลทำนายซื้อซ้ำ — พลาดแบบไหนบ้าง
นับ TN/FP/FN/TP ของโมเดลบนชุดทดสอบ
accuracy paradox
ทำนายว่าออเดอร์แรกจะถูกยกเลิก — accuracy 94% ดีจริงไหม
ดูสัดส่วนออเดอร์แรกที่ถูกยกเลิก และ accuracy ของการทายว่า "ไม่ยกเลิก" ทุกแถว
เติมช่องว่าง
แทน ___ ด้วยโค้ดที่ถูกต้อง แล้วกดตรวจคำตอบ
คำนวณ precision จากค่า confusion matrix เก็บไว้ในตัวแปร precision เติม ___ ให้ครบ
แบบฝึกท้ายบท
บทนี้จะนับว่าเสร็จเมื่อผ่านข้อพื้นฐานและประยุกต์ครบ ข้อท้าทายได้ดาวเพิ่ม
🟢 พื้นฐาน
นับ TN, FP, FN, TP ของโมเดลบนชุดทดสอบ (ใช้ confusion_matrix(...).ravel()) เก็บไว้ในตัวแปร tn, fp, fn, tp
precision ของโมเดลบนชุดทดสอบ ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร precision
recall ของโมเดลบนชุดทดสอบ ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร recall
F1 ของโมเดลบนชุดทดสอบ ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร f1
🟡 ประยุกต์
ROC-AUC ของโมเดลบนชุดทดสอบ (ใช้ความน่าจะเป็น ไม่ใช่คลาส) ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร auc
สัดส่วนลูกค้าที่ออเดอร์แรกถูกยกเลิก (first_status == "cancelled") ทั้งชุดข้อมูล ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร cancel_rate
accuracy บนชุดทดสอบถ้าทายว่า "ไม่ถูกยกเลิก" ทุกแถว ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร always0_acc
🔴 ท้าทาย
เทรน LogisticRegression(max_iter=2000) ปกติกับโจทย์ทำนายการยกเลิก แล้วหา recall ของคลาสยกเลิกบนชุดทดสอบ เก็บไว้ในตัวแปร cancel_recall
เทรนใหม่ด้วย class_weight="balanced" แล้วหา recall และ precision ของคลาสยกเลิกบนชุดทดสอบ (ปัด 4 ตำแหน่ง) เก็บไว้ในตัวแปร recall_bal, precision_bal
Quiz
สรุป
- confusion matrix นับ TN/FP/FN/TP — precision = TP/(TP+FP), recall = TP/(TP+FN), F1 คือค่าเฉลี่ยแบบ harmonic ของสองตัวนี้
- ROC-AUC วัดการจัดอันดับ 0.5 = เดาสุ่ม ในข้อมูลนี้โมเดลได้ประมาณ 0.62
- คลาสหายาก (ออเดอร์ที่ถูกยกเลิก ~6%) ทำให้ accuracy หลอกตา: ทายไม่ยกเลิกทุกแถวได้ ~94% แต่ recall = 0 ควรดู precision/recall และลอง class_weight="balanced"
คำถามสัมภาษณ์
อธิบาย precision กับ recall ให้ผู้บริหารฟังพร้อมตัวอย่างที่ต้องแลกกัน
precision ตอบว่า "คนที่เราส่งโปรโมชันไป ในนั้นมีกี่ % ที่ควรได้จริง" ส่วน recall ตอบว่า "คนที่ควรได้โปรโมชันทั้งหมด เราส่งถึงกี่ %" — ถ้าลดเกณฑ์ให้ส่งกว้างขึ้น recall เพิ่มแต่ส่งพลาดคนไม่ควรได้มากขึ้น (precision ลด) เลือกจุดสมดุลจากต้นทุนของการส่งเกินกับการพลาดลูกค้า
เจอโมเดลที่ accuracy 94% ในโจทย์ที่คลาสเป้าหมายมีแค่ 6% จะตรวจสอบอะไรต่อ
เทียบกับ baseline ที่ทายคลาสส่วนใหญ่ (ซึ่งได้ ~94% อยู่แล้ว) แล้วดู confusion matrix, recall/precision ของคลาสหายาก และ ROC-AUC ถ้า recall ใกล้ 0 แปลว่าโมเดลไม่ได้เรียนรู้อะไรเกี่ยวกับคลาสที่สนใจเลย จากนั้นลองปรับ class_weight หรือ threshold และรายงานตัวชี้วัดที่ตรงกับเป้าหมายทางธุรกิจ