🏥 Lab 5: Naive Bayes Classifier

การวินิจฉัยโรคด้วย Probabilistic Classification


1. วัตถุประสงค์ (Objectives)


2. ทฤษฎีพื้นฐาน (Background)

2.1 หลักการ Naive Bayes

Naive Bayes Classifier ใช้ Bayes' Theorem ร่วมกับสมมติฐาน Conditional Independence ระหว่าง Features ทุกตัวเมื่อรู้คลาสแล้ว สูตรหลักคือ:

$$ P(C \mid x_1, x_2, \ldots, x_n) ;\propto; P(C) \times \prod_{i=1}^{n} P(x_i \mid C) $$

สัญลักษณ์ ความหมาย
P(C) Prior — ความน่าจะเป็นของคลาส C ก่อนเห็นข้อมูล
P(xᵢ | C) Likelihood — ความน่าจะเป็นของ Feature xᵢ ในคลาส C
P(C | x) Posterior — ความน่าจะเป็นของคลาสหลังเห็นข้อมูล
สัดส่วน (ไม่รวม Normalizing Constant)

2.2 Laplace Smoothing (Add-1 Smoothing)

เมื่อ Feature ใดไม่เคยปรากฏในคลาส → Likelihood = 0 → Posterior ทั้งหมดเป็น 0 แก้ด้วย:

$$ P(x_i \mid C) = \frac{\text{count}(x_i, C) + 1}{\text{count}(C) + |V|} $$

โดยที่ |V| = จำนวนค่าที่เป็นไปได้ของ Feature (Binary Feature → |V| = 2)

2.3 ประเภท Naive Bayes ที่ใช้ใน Lab นี้

ประเภท เหมาะกับข้อมูล ตัวอย่างการใช้งาน
Bernoulli NB Binary (0/1) มี/ไม่มีอาการ ✅ ใช้ใน Lab นี้
Multinomial NB Count (จำนวนครั้ง) Text Classification
Gaussian NB ตัวเลขต่อเนื่อง ข้อมูลวิทยาศาสตร์

3. ชุดข้อมูล (Dataset)

3.1 คำอธิบาย

3.2 ตารางข้อมูลทั้งหมด 50 แถว

# ไข้ ไอ ปวดกล้ามเนื้อ ผื่น โรค
1 1 1 1 0 ไข้หวัดใหญ่
2 1 1 0 0 ไข้หวัดใหญ่
3 1 1 1 0 ไข้หวัดใหญ่
4 1 0 1 0 ไข้หวัดใหญ่
5 0 1 1 0 ไข้หวัดใหญ่
6 1 1 1 0 ไข้หวัดใหญ่
7 1 1 0 0 ไข้หวัดใหญ่
8 1 1 1 0 ไข้หวัดใหญ่
9 0 1 0 0 ไข้หวัดใหญ่
10 1 0 1 0 ไข้หวัดใหญ่
11 1 1 1 0 ไข้หวัดใหญ่
12 1 1 0 0 ไข้หวัดใหญ่
13 1 1 1 0 ไข้หวัดใหญ่
14 0 0 1 0 ไข้หวัดใหญ่
15 1 1 1 0 ไข้หวัดใหญ่
16 1 1 0 0 ไข้หวัดใหญ่
17 0 1 1 0 ไข้หวัดใหญ่
18 1 1 1 0 ไข้หวัดใหญ่
19 1 0 1 1 ไข้เลือดออก
20 1 0 1 1 ไข้เลือดออก
21 1 0 0 1 ไข้เลือดออก
22 1 0 1 1 ไข้เลือดออก
23 1 0 1 0 ไข้เลือดออก
24 0 0 1 1 ไข้เลือดออก
25 1 0 1 1 ไข้เลือดออก
26 1 0 0 1 ไข้เลือดออก
27 1 1 1 1 ไข้เลือดออก
28 1 0 1 1 ไข้เลือดออก
29 0 0 1 1 ไข้เลือดออก
30 1 0 1 1 ไข้เลือดออก
31 1 0 0 1 ไข้เลือดออก
32 1 0 1 1 ไข้เลือดออก
33 1 0 1 0 ไข้เลือดออก
34 1 0 1 1 ไข้เลือดออก
35 1 1 1 0 โควิด-19
36 0 1 0 0 โควิด-19
37 1 1 1 0 โควิด-19
38 0 1 1 0 โควิด-19
39 1 1 0 0 โควิด-19
40 0 1 1 0 โควิด-19
41 1 1 1 0 โควิด-19
42 0 1 0 0 โควิด-19
43 1 1 1 0 โควิด-19
44 1 0 1 0 โควิด-19
45 0 1 1 0 โควิด-19
46 1 1 0 0 โควิด-19
47 0 1 1 0 โควิด-19
48 1 1 1 0 โควิด-19
49 0 1 0 0 โควิด-19
50 1 1 1 0 โควิด-19

4. การคำนวณด้วยมือ (Manual Calculation)

4.1 Prior Probability

นับจากตารางด้านบน หารด้วยจำนวนทั้งหมด (50)

โรค จำนวน P(โรค)
ไข้หวัดใหญ่ 18 18/50 = 0.36
ไข้เลือดออก 16 16/50 = 0.32
โควิด-19 16 16/50 = 0.32

4.2 Likelihood P(อาการ | โรค)

อาการ ไข้หวัดใหญ่ (n=18) ไข้เลือดออก (n=16) โควิด-19 (n=16)
ไข้ = 1 15/18 = 0.833 14/16 = 0.875 10/16 = 0.625
ไอ = 1 16/18 = 0.889 1/16 = 0.063 13/16 = 0.813
ปวดกล้ามเนื้อ = 1 14/18 = 0.778 14/16 = 0.875 10/16 = 0.625
ผื่น = 1 0/18 = 0.000 ⚠️ 13/16 = 0.813 0/16 = 0.000 ⚠️

⚠️ Zero Probability: ต้องใช้ Laplace Smoothing
P(ผื่น=1 | ไข้หวัดใหญ่) = (0+1)/(18+2) = 0.050
P(ผื่น=1 | โควิด-19) = (0+1)/(16+2) = 0.056

4.3 ตัวอย่างการคำนวณ Posterior

โจทย์: ผู้ป่วยมีอาการ → ไข้ = ✓, ไอ = ✗, ปวดกล้ามเนื้อ = ✓, ผื่น = ✓

Score(ไข้หวัดใหญ่) = 0.36 × 0.833 × 0.111 × 0.778 × 0.050  ≈  0.00130
Score(ไข้เลือดออก) = 0.32 × 0.875 × 0.063 × 0.875 × 0.813  ≈  0.01261
Score(โควิด-19)    = 0.32 × 0.625 × 0.813 × 0.625 × 0.056  ≈  0.00569

▶  วินิจฉัย: ไข้เลือดออก  (Score สูงสุด)

5. คำสั่งการทดลอง (Lab Instructions)

📌 ข้อกำหนด: เขียนโปรแกรม Python โดยใช้ข้อมูลจากตาราง 50 แถวในหัวข้อ 3 เท่านั้น
แต่ละคำสั่งให้เขียนเป็นไฟล์ .py แยกกัน หรือแบ่งเป็น Section ใน Jupyter Notebook


คำสั่งที่ 1 — สร้าง DataFrame และแสดงสถิติเบื้องต้น

จงเขียนโปรแกรมเพื่อ:

  1. นำข้อมูล 50 แถวจากตารางมาสร้าง pandas DataFrame
  2. แสดงจำนวนตัวอย่างของแต่ละโรค (value_counts)
  3. แสดงค่าเฉลี่ยของแต่ละอาการ แยกตามโรค (groupby + mean)

ตัวอย่างผลลัพธ์ที่คาดหวัง:

=== จำนวนตัวอย่างแต่ละโรค ===
ไข้หวัดใหญ่    18
ไข้เลือดออก    16
โควิด-19       16
dtype: int64

=== ค่าเฉลี่ยอาการแยกตามโรค ===
               ไข้      ไอ  ปวดกล้ามเนื้อ    ผื่น
โรค
โควิด-19      0.625   0.813         0.625   0.000
ไข้หวัดใหญ่   0.833   0.889         0.778   0.000
ไข้เลือดออก   0.875   0.063         0.875   0.813

คำสั่งที่ 2 — แบ่ง Train/Test และ Train โมเดล

จงเขียนโปรแกรมเพื่อ:

  1. แบ่งข้อมูล Train 70% / Test 30% (random_state=42, stratify=y)
  2. สร้างโมเดล BernoulliNB(alpha=1.0) และ Train ด้วยชุด Train
  3. แสดง Accuracy ของทั้ง Train Set และ Test Set

ตัวอย่างผลลัพธ์ที่คาดหวัง:

Train size : 35  |  Test size : 15
Training Accuracy : 0.9143
Testing  Accuracy : 0.8667

คำสั่งที่ 3 — ทำนายผู้ป่วยใหม่

จงเขียนโปรแกรมวินิจฉัยผู้ป่วยใหม่ 3 ราย ต่อไปนี้ โดยแสดงผลวินิจฉัยและความน่าจะเป็นของทุกโรค:

ผู้ป่วย ไข้ ไอ ปวดกล้ามเนื้อ ผื่น
คนที่ 1 1 0 1 1
คนที่ 2 1 1 1 0
คนที่ 3 0 1 0 0

ตัวอย่างผลลัพธ์ที่คาดหวัง:

===== ผลการวินิจฉัยผู้ป่วย =====

ผู้ป่วยคนที่ 1  [ไข้=1, ไอ=0, ปวด=1, ผื่น=1]
  วินิจฉัย      : ไข้เลือดออก
  ความน่าจะเป็น : ไข้หวัดใหญ่  =  4.31%
                  ไข้เลือดออก  = 91.27%
                  โควิด-19     =  4.42%

ผู้ป่วยคนที่ 2  [ไข้=1, ไอ=1, ปวด=1, ผื่น=0]
  วินิจฉัย      : ไข้หวัดใหญ่
  ความน่าจะเป็น : ไข้หวัดใหญ่  = 59.83%
                  ไข้เลือดออก  =  3.72%
                  โควิด-19     = 36.45%

ผู้ป่วยคนที่ 3  [ไข้=0, ไอ=1, ปวด=0, ผื่น=0]
  วินิจฉัย      : โควิด-19
  ความน่าจะเป็น : ไข้หวัดใหญ่  = 23.11%
                  ไข้เลือดออก  =  3.04%
                  โควิด-19     = 73.85%

คำสั่งที่ 4 — ประเมินโมเดลด้วย Classification Report

จงเขียนโปรแกรมเพื่อ:

  1. ทำนาย Label ของชุด Test ทั้งหมด
  2. แสดง Classification Report ครบทุกค่า (Precision, Recall, F1-Score, Support)

ตัวอย่างผลลัพธ์ที่คาดหวัง:

===== Classification Report =====

                 precision  recall  f1-score  support

  ไข้หวัดใหญ่      0.89      0.94      0.91        6
  ไข้เลือดออก      0.94      0.88      0.91        5
  โควิด-19          0.88      0.88      0.88        4

     accuracy                          0.90       15
    macro avg       0.90      0.90      0.90       15
 weighted avg       0.90      0.90      0.90       15

คำสั่งที่ 5 — วาด Confusion Matrix

จงเขียนโปรแกรมเพื่อ:

  1. คำนวณ Confusion Matrix จากผลทำนายบน Test Set
  2. แสดงเป็น Heatmap ด้วย seaborn พร้อม Label ครบถ้วน
  3. บันทึกภาพเป็น confusion_matrix.png

ตัวอย่างผลลัพธ์ที่คาดหวัง:

Confusion Matrix (Test Set):

                  ทำนาย:ไข้หวัด  ทำนาย:เลือดออก  ทำนาย:โควิด
จริง:ไข้หวัด           5               0               1
จริง:เลือดออก          0               4               1
จริง:โควิด             0               0               4

บันทึกไฟล์: confusion_matrix.png ✓

คำสั่งที่ 6 — วิเคราะห์ Feature Importance

จงเขียนโปรแกรมเพื่อ:

  1. ดึงค่า Log Feature Probability จาก model.feature_log_prob_
  2. แปลงเป็นค่าปกติด้วย np.exp() แล้วแสดงเป็นตาราง
  3. สรุปว่า Feature ใดมีพลัง Discriminative สูงสุด พร้อมเหตุผล

ตัวอย่างผลลัพธ์ที่คาดหวัง:

===== Feature Likelihood Probability =====

อาการ             ไข้หวัดใหญ่  ไข้เลือดออก  โควิด-19
ไข้                  0.800        0.833       0.611
ไอ                   0.850        0.111       0.778
ปวดกล้ามเนื้อ        0.750        0.833       0.611
ผื่น                 0.050        0.778       0.056

📊 Feature ที่แยกแยะโรคได้ดีที่สุด: "ผื่น"
   ไข้เลือดออก=0.778  vs  ไข้หวัดใหญ่=0.050  vs  โควิด-19=0.056

6. แบบฝึกหัดเพิ่มเติม (Additional Exercises)

ระดับพื้นฐาน ⭐

  1. คำนวณด้วยมือ: ผู้ป่วยมีอาการ ไข้ = ✓, ไอ = ✓, ปวดกล้ามเนื้อ = ✗, ผื่น = ✗
    จงคำนวณ Posterior Probability ของทั้ง 3 โรค พร้อมแสดงขั้นตอนอย่างละเอียด

  2. เปรียบเทียบ Smoothing: ทดลองเปลี่ยน alpha เป็น 0.5, 1.0, 2.0
    สร้างตารางเปรียบเทียบ Accuracy และสรุปว่าค่าใดเหมาะสมที่สุด

ระดับกลาง ⭐⭐

  1. เพิ่ม Feature ใหม่: เพิ่มอาการ "ปวดศีรษะ" โดยกำหนด:

    Train โมเดลใหม่และเปรียบเทียบ Accuracy กับ Baseline

  2. เปรียบเทียบโมเดล: ทดลองใช้ GaussianNB แทน BernoulliNB
    เปรียบเทียบ F1-Score ของทั้งคู่ พร้อมสรุปว่าแบบใดเหมาะกว่าและเพราะอะไร

ระดับสูง ⭐⭐⭐

  1. Cross-Validation: ใช้ cross_val_score แบบ k-fold (k=5)
    แสดงค่า Mean ± Std Accuracy เพื่อลด Variance จากการแบ่ง Train/Test

  2. Bayesian Network: ออกแบบ DAG ที่แสดงความสัมพันธ์ระหว่าง 3 โรคกับ 4 อาการ
    พร้อมระบุ CPT ของแต่ละโหนดและอธิบาย Causal Reasoning


7. สรุป (Summary)

แนวคิด ความสำคัญ
Prior P(C) สะท้อน Base Rate ของโรคในประชากร
Likelihood P(x|C) โอกาสเห็นอาการนี้ถ้าป่วยเป็นโรคนั้น
Posterior P(C|x) ความน่าจะเป็นหลังเห็นอาการ → ใช้ตัดสินวินิจฉัย
Laplace Smoothing ป้องกัน Zero Probability จาก Feature ที่ไม่เคยปรากฏ
Bernoulli NB เหมาะกับ Binary Feature เช่น มี/ไม่มีอาการ
F1-Score เมตริกที่ดีกว่า Accuracy สำหรับข้อมูลไม่สมดุล

เอกสารอ้างอิง (References)

  1. Russell, S., & Norvig, P. (2020). Artificial Intelligence: A Modern Approach (4th ed.). Pearson. — บทที่ 12
  2. Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer. — บทที่ 8
  3. scikit-learn Naive Bayes Documentation — https://scikit-learn.org/stable/modules/naive_bayes.html
  4. Murphy, K. P. (2012). Machine Learning: A Probabilistic Perspective. MIT Press.

เอกสารนี้จัดทำสำหรับรายวิชา Artificial Intelligence สาขาวิทยาการคอมพิวเตอร์
สำนักงานวิทยบริการและเทคโนโลยีสารสนเทศ | มหาวิทยาลัยเทคโนโลยีราชมงคลศรีวิชัย