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

โมเดลทำนายซื้อซ้ำ — พลาดแบบไหนบ้าง

  1. นับ TN/FP/FN/TP ของโมเดลบนชุดทดสอบ

    Python

accuracy paradox

ทำนายว่าออเดอร์แรกจะถูกยกเลิก — accuracy 94% ดีจริงไหม

  1. ดูสัดส่วนออเดอร์แรกที่ถูกยกเลิก และ accuracy ของการทายว่า "ไม่ยกเลิก" ทุกแถว

    Python

เติมช่องว่าง

แทน ___ ด้วยโค้ดที่ถูกต้อง แล้วกดตรวจคำตอบ

ยังไม่ได้ทำ

คำนวณ 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

1. precision วัดอะไร
2. recall วัดอะไร
3. accuracy paradox คืออะไร
4. ROC-AUC = 0.5 แปลว่าอะไร

สรุป

  • 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 และรายงานตัวชี้วัดที่ตรงกับเป้าหมายทางธุรกิจ