ทั้งไฟล์อ่านเป็นประโยคเดียว: "อ่าน temp+humidity → คำนวณ dew/heat → เอาเข้าบันไดกฎ → เอาคลาสที่ชนะขึ้นจอพร้อมสี → เทียบกับกฎสำเร็จรูป"
ตัวเลข "เติม 1..4" ชี้ไปที่
# เติม:ในไฟล์ฝึก จำโครงนี้ไว้ เดี๋ยวไล่ดูทีละช่อง
ช่องเติมที่ 1 และ 2: ต้นลูป อ่านเซนเซอร์แล้วแปลงเป็นค่าอนุพัทธ์ที่กฎจะใช้:
while True:
p, t = sensors.dps368.pressure_temperature() # ความดัน + อุณหภูมิ (ให้ไว้แล้ว)
h = sensors.sht40.humidity() # ความชื้น %RH (ให้ไว้แล้ว)
# เติม: dp = dsp.dew_point(t, h) # จุดน้ำค้าง
dp = 0.0
pass
# เติม: hi = dsp.heat_index(t, h) # "รู้สึกเหมือน" กี่องศา
hi = t
pass
pass ด้วย dp = dsp.dew_point(t, h) · ช่อง 2: แทนด้วย hi = dsp.heat_index(t, h)dp = 0.0 / hi = t กันโปรแกรมพังตอนยังเติมไม่ครบ พอเติมแล้วบรรทัดจริงจะทับค่าตั้งต้นdp เอาไปโชว์บนการ์ด · hi เอาไปป้อนบันไดกฎ (คลาส hot/danger ตัดสินจาก hi)ทำไม
humidity()คืนค่าตัวเดียว (float) ไม่ใช่ tuple? เพราะมันคืน %RH อย่างเดียว ส่วนอุณหภูมิเราเอามาจาก DPS368 แล้ว — ลองเรียกsensors.sht40.humidity()ใน REPL ดูได้
ช่องเติมที่ 3 (หัวใจของชุดบทเรียน): เติมบันไดกฎในฟังก์ชัน classify():
def classify(t, h, hi):
# เติม: เขียนบันไดเงื่อนไข ไล่จาก "อันตรายสุด" ลงมา แล้ว return ชื่อคลาส (str)
# if hi >= 41: return "danger"
# if hi >= 32: return "hot"
# if h >= 70: return "humid"
# if t < 20: return "cold"
# if h < 30: return "dry"
# return "comfortable"
pass
pass ด้วยบันไดทั้งชุด — ลำดับต้องไล่จากรุนแรง/เฉพาะ (danger) ลงไปกว้าง (comfortable)COLORS ไม่งั้นตอนระบายสีจะได้สีขาว (fallback)ถ้าลืมเติมช่องนี้:
classify()คืนNone→verdictโชว์ว่างเปล่า และCOLORS.get(None)ได้สีขาว นี่คืออาการที่บอกว่าบันไดยังไม่ทำงาน
ช่องเติมที่ 4: เอาคลาสที่ classify คืนมา ขึ้นจอพร้อมสีประจำคลาส:
zone = classify(t, h, hi)
# เติม: verdict.text(zone)
# verdict.color(COLORS.get(zone, WHITE))
pass
pass ด้วยสองบรรทัด: verdict.text(zone) แล้ว verdict.color(COLORS.get(zone, WHITE))COLORS.get(zone, WHITE) = ถ้าคลาสอยู่ในแผนที่สี ใช้สีนั้น ถ้าไม่ (เช่นเติมบันไดพลาด) ใช้สีขาวpattern "สร้าง widget ครั้งเดียว แล้วในลูปแค่
.text()/.color()" คือของเดิมจาก บทเรียน 1.1–1.3 — เราไม่สร้าง Seg7 ใหม่ทุกรอบ แค่เปลี่ยนข้อความกับสีของอันเดิม จอจะได้ไม่กระพริบ
ท่อนสุดท้าย (ให้ไว้แล้ว) เอาคำตัดสินของเราไปเทียบกับ dsp.comfort_zone เพื่อ "ตรวจการบ้านตัวเอง":
lab_builtin.text("dsp.comfort_zone: %s" % dsp.comfort_zone(t, h))
examples/) เราเพิ่มไฟบอก = เมื่อตรงกัน x เมื่อต่างกัน ไว้สังเกตว่ากฎสองชุดเห็นพ้องกันบ่อยแค่ไหนจุดนี้คือประเด็นที่ควรคิดให้จบ: "เมื่อกฎสองชุดตัดสินต่างกันตรงไหน แล้วชุดไหนถูก?" คำตอบคือ ไม่มีชุดไหน 'ถูก' โดยสมบูรณ์ — กฎขึ้นกับนิยามที่เราเลือก นี่คือข้อจำกัดที่ ML จะเข้ามาช่วยด้วยข้อมูลจริง
ไม่มีบอร์ดก็เริ่มได้ (Emulator จำลองค่า temp/humidity ให้):
s07_rule_classifier.py# เติม:Emulator ใช้ค่าจำลองแต่
dsp.dew_point/heat_index/comfort_zoneคำนวณด้วยสูตรจริงเหมือนบอร์ด — เหมาะกับซ้อมตรรกะบันไดกฎที่บ้าน
BENTO Edge AI Emulator คือจอ emulator ที่รันได้จริงในเบราว์เซอร์ ไม่ต้องมีบอร์ดก็เขียนโค้ดแล้วเห็นผลบนจอจำลองได้ทันที
s07_rule_classifier.py ที่นี่)dsp.* คำนวณด้วยสูตรฟิสิกส์จริง ตรรกะบันไดกฎจึงซ้อมได้เหมือนอยู่หน้าบอร์ดเปิดที่ ide.tesaiot.dev ได้เลย เครื่องใครก็รันได้ ไม่ต้องลงอะไร — เหมาะมากสำหรับกลับไปซ้อมต่อที่บ้าน
บนบอร์ดจริงใช้เซนเซอร์จริง DPS368 + SHT40 บน AI Kit:
s07_rule_classifier.py ใน BENTO IDE กด Program to Devicehumidhotcomfortable หรือ coldค่าจากเซนเซอร์จริงจะสั่นเล็กน้อยตลอด ถ้าคลาสกระพริบคร่อมเส้นแบ่ง นั่นคือเหตุผลที่ฉบับเต็มใส่ ฮิสเทอรีซิส ไว้กันกระพริบ — เก็บไว้เป็นโจทย์ท้าทาย
เปิด s07_rule_classifier.py มี pass วางไว้ 4 จุด ตรงที่ต้องเติมตรรกะจริง:
| # | จุด | เติมด้วย | ถ้าลืม |
|---|---|---|---|
| 1 | ต้นลูป | dp = dsp.dew_point(t, h) |
dew point ค้างที่ 0.0 |
| 2 | ต้นลูป | hi = dsp.heat_index(t, h) |
feels-like = temp ดิบ กฎ hot/danger เพี้ยน |
| 3 | ใน classify() |
บันไดกฎ 6 ชั้น (danger→...→comfortable) | คลาสว่าง + สีขาว |
| 4 | หลัง classify | verdict.text(zone) + verdict.color(...) |
คำตัดสินไม่ขึ้นจอ |
ขั้นตอน:
# เติม: ทีละจุด แทน pass (และค่าตั้งต้น) ด้วยโค้ดจริงตามคำใบ้สี่ช่องนี้คือ pipeline ย่อของ classifier ทั้งตัว: แปลง (1,2) → ตัดสิน (3) → แสดง (4) เติมครบเมื่อไร คุณมี classifier ตัวแรกที่เข้าใจทุกบรรทัด
จุดแข็งที่สุดของบันไดกฎคือ ทุกคำตัดสิน สืบย้อนได้ว่าชั้นไหนยิงออกมา ในฉบับเต็มเราให้ classify() คืนเหตุผลด้วย:
def classify(t, h, hi):
if hi >= HI_DANGER:
return "danger", "feels-like %.0f >= %.0f" % (hi, HI_DANGER)
...
why: feels-like 43 >= 41 — ผู้ใช้/วิศวกรเห็นเลยว่าทำไมถึงตัดสิน dangerเวลาเลือกระหว่างกฎกับ ML อย่าถามแค่ "อันไหนแม่นกว่า" ถามด้วยว่า "เราต้องอธิบายคำตัดสินได้ไหม" — บางงานคำตอบข้อนี้สำคัญกว่าความแม่นเสียอีก
กฎมือดีในหลายงาน แต่มันชนกำแพงเมื่อ pattern ซับซ้อนขึ้น — นี่คือเหตุผลที่คอร์สนี้พาไปต่อที่ Training:
if ไหว แต่กับ 50 feature ของเสียง/การสั่น การเขียนกฎมือแทบเป็นไปไม่ได้วันนี้คุณจะได้ยินตัวเองพูดว่า "ถ้าเงื่อนไขเยอะกว่านี้ เขียน
ifไม่ไหวแน่" — ความรู้สึกนั้นแหละคือ แรงจูงใจที่แท้จริงของ ML เก็บมันไว้ เดี๋ยวเราไปปลดล็อกกันที่ โมดูล 5 (Training)
อยากต่อยอดเรื่อง derived metric และการจำแนกด้วยกฎ ลองตามลิงก์เหล่านี้ (เปิดดูได้ตามสะดวก):
วิดีโอ (ช่องการศึกษาที่เชื่อถือได้)
ภาพ / บทความอ้างอิง
วิดีโอ/ภาพภายนอกเป็นของเจ้าของต้นฉบับ ใช้เพื่อการศึกษา อ้างอิงลิงก์ต้นทาง
MVP ของบทเรียน 3.3–3.4 (เกณฑ์ผ่านของชุดบทเรียน): คุณเขียน classify() ด้วยบันไดกฎเอง แล้วบอร์ด/Emulator โชว์คลาสที่เปลี่ยนตามจริง เมื่อ temp/humidity เปลี่ยน (หายใจรด/กำบอร์ด)
heat_index หรือ dew_point) ในการตัดสิน"ตัดสินได้" ไม่ใช่แค่ "เห็นตัวหนังสือเปลี่ยน" — คุณต้องชี้ได้ว่าคลาส
hotมาจากเงื่อนไขhi >= 32และบอกได้ว่าทำไมใช้hiไม่ใช่t
ถ้าติด ให้ไต่บันไดนี้ทีละขั้น อย่าเพิ่งกระโดดไปดูเฉลย เพราะของจะเข้าหัวตอนที่คุณพยายามเองก่อน:
# เติม: ทั้ง 4 จุด + ตารางหน้าที่แล้ว บอกว่าแต่ละช่องเติมอะไรs07_rule_classifier.py มีโครงครบทั้งไฟล์ เหลือแค่ 4 จุดให้เติม (บันไดกฎยาวสุด)s07_rule_classifier.py เติมครบพร้อมคอมเมนต์อธิบายทุกชั้น (อ่านให้เข้าใจ ปิดไฟล์ แล้วพิมพ์เอง)s07_rule_classifier_full.py เพิ่ม rule trace (why), เทียบกฎสำเร็จรูปพร้อมไฟตรง/ต่าง, และฮิสเทอรีซิสกันคลาสกระพริบลองเขียนบันไดกฎเองให้สุดก่อนนะ พลาดลำดับชั้นก็ไม่เป็นไร นั่นแหละคือจุดที่เราจะได้เรียนรู้เรื่อง dead branch ด้วยกัน
การเขียน classifier ด้วยกฎ ซ่อนแนวคิดที่จะใช้ยาวไปถึง โมดูล 5 (Training) และ Apps:
ฝั่ง Edge AI / การจำแนก
ฝั่ง MicroPython / โครงโปรแกรม
ui.poll.text() / .color() จอไม่กระพริบทั้งหมดนี้คือฐานของ ML: พอเข้าใจว่ากฎมือ "ตั้งเส้นแบ่งเอง" แล้ว คุณจะเข้าใจทันทีว่า ML คือการ "ให้เครื่องหาเส้นแบ่งจากข้อมูลแทนเรา" — คนละวิธี งานเดียวกัน
classifier แบบกฎไม่ใช่ของเล่นในห้องเรียน มันคือหัวใจของอุปกรณ์ควบคุมนับล้านชิ้นที่ทำงานอยู่ตอนนี้:
สังเกตข้อ 3: บางงาน กฎหมายกำหนดเส้นแบ่งไว้แล้ว (เช่นค่า WBGT เตือนความร้อน) งานพวกนี้ต้องใช้กฎ ไม่ใช่ ML เพราะต้องตรงตามเกณฑ์เป๊ะและอธิบายได้ — วิศวกรที่ดีเลือกเครื่องมือให้ตรงงาน
งานทำเอง (ท้ายบทเรียน):
s07_rule_classifier.py ให้ครบทั้ง 4 จุด รันได้จริง (Emulator หรือ AI Kit)humid, กำบอร์ด→hot, ปกติ→comfortable) แล้วจดว่าต้องทำอะไรถึงได้แต่ละคลาสhi >= 32 เป็น >= 30) แล้วอธิบายว่าคำตัดสินเปลี่ยนยังไง และทำไมใบ้ข้อ 3 — ลองหาค่าที่ "คร่อมเส้น" (เช่น heat index ~31–33) แล้วดูว่าเปลี่ยนเส้นแบ่งเล็กน้อยพลิกคำตัดสินได้จริง นี่คือสัมผัสแรกของ "การจูนเส้นแบ่ง" ที่ ML ทำอัตโนมัติในชุดบทเรียนหลัง
วันนี้เราได้: เข้าใจว่า classifier คืออะไร · แปลงค่าดิบเป็น derived metric (dew_point/heat_index) · เขียนบันไดกฎ threshold เอง · เห็นจุดแข็ง (อธิบายได้) และจุดอ่อน (กฎบาน) ของกฎมือ ที่ปูทางสู่ ML
ชุดบทเรียนถัดไป (บทเรียน 4.1–4.2) เราเข้าสู่ Pillar 3 · Analysis — เริ่มจากตัวกรองสัญญาณ (EMA/median/Kalman) ทำสัญญาณสั่นๆ ให้เนียนขึ้นแบบเห็นกับตา เจอกันครับ