Data Project ปลายทาง
ปิดเฟส Data ด้วยการ "เล่าเรื่องด้วยข้อมูล" · เก็บข้อมูลจริง → ทำความสะอาด → วิเคราะห์ → ทำกราฟ → เขียน insight 1 หน้า · จบขั้นนี้ = ทำ data report ได้เอง
เป้าหมายสัปดาห์นี้
- เก็บข้อมูล ของจริง แบบที่ ถูกต้องตามจริยธรรม
- ทำ "data cleaning" — handle missing, duplicate, wrong format
- ตอบ 3 คำถามด้วยข้อมูล + ทำกราฟแต่ละคำถาม
- ตรวจ AI — ไม่เชื่อ output ก่อนยืนยันเอง
- เขียน insight report 1 หน้า A4 + ระบุข้อจำกัด
- ตัดสินใจเรื่อง privacy — AI ไม่รู้ว่าเพื่อนคุณยินยอมให้ใช้ข้อมูลมั้ย · ไม่รู้ว่า GPA / สุขภาพ / เงิน ของใคร · ไม่รู้ว่า raw data จะไป public หรือเปล่า
- ตรวจว่า analysis ถูก — AI hallucinate ตัวเลขได้ · เสนอ correlation ที่ไม่มี · drop row ที่ไม่ควร drop · สรุปเกินที่ data รองรับ · คุณคือคนที่ลงชื่อใน report
🔐 Privacy & Security — ก่อนเก็บข้อมูลคนอื่น
ถ้าโจทย์ของคุณคือ "ขอให้เพื่อน 30 คนกรอก Google Form" — คุณกำลังเป็น "data controller" ตามกฎหมาย PDPA (พ.ร.บ. คุ้มครองข้อมูลส่วนบุคคล 2562) · ทำผิดมีโทษได้ · ทำถูกใช้งานได้ทั้งชีวิต
✅ 6-Question Consent Checklist
ก่อนส่ง form ให้เพื่อน ตอบ checklist นี้ทั้ง 6 ข้อให้ครบ:
| คำถาม | ต้องตอบยังไง |
|---|---|
| 1. คนตอบรู้มั้ย ว่าฉันเอาข้อมูลไปทำอะไร? | ใส่ใน description ของ Form: "ใช้สำหรับวิชา CP เท่านั้น · จะรายงานเฉพาะค่าเฉลี่ย ไม่ระบุชื่อ" |
| 2. ให้ตัวเลือก "ไม่ตอบ" มั้ย? | Form ทุกคำถามต้อง ไม่บังคับ (uncheck "Required") ยกเว้น consent |
| 3. ขอ consent ชัด ๆ มั้ย? | คำถามแรก: "ฉันยินยอมให้ใช้ข้อมูลนี้สำหรับงานในคอร์ส" ☐ ยินยอม / ☐ ไม่ยินยอม |
| 4. ขอข้อมูลที่ ระบุตัวตน มั้ย? | ลบ Email collection ใน Form settings · ห้ามถามชื่อจริง · student_id ถ้าไม่จำเป็น ห้ามถาม |
| 5. ใครเห็น raw data ได้บ้าง? | แค่คุณ + อาจารย์ · ห้าม commit raw CSV ขึ้น GitHub public |
| 6. หลังคอร์สจบ ลบมั้ย? | ใส่ใน Form: "ข้อมูลจะถูกลบหลังเทอมจบ" · แล้วลบจริง ๆ |
🏷 ระดับความเสี่ยงของข้อมูล (Sensitivity Tiers)
| Tier | ประเภท | ตัวอย่าง | วิธีจัดการ |
|---|---|---|---|
| 🟢 Tier 1: Safe | Public / Aggregate | PM2.5, สภาพอากาศ, public dataset, lab equipment usage | ใช้ได้เลย · public ได้ทุกระดับ |
| 🟡 Tier 2: Care | Personal Habits | นอน, อาหาร, AI usage, time tracking ของ user แต่ละคน | ต้อง consent + anonymize · raw data ห้าม public |
| 🔴 Tier 3: Sensitive | GPA / Health / Finance / Opinions | คะแนน, สุขภาพ, รายได้, รายจ่าย, ความคิดเห็นแอบ | หลีกเลี่ยงถ้าทำได้ · ถ้าจำเป็น → consent + ลบ identifier + รายงานเฉพาะ aggregate |
| ⛔ ห้ามทำ | ข้อมูลที่ระบุ + เปิดเผยได้ | คะแนนของเพื่อนที่ระบุชื่อ · รูปคนอื่นที่ไม่ขอ · social media posts ที่ไม่ใช่ของตัวเอง | ไม่ทำ · ใช้ public alternative |
🛡 Anonymization — ลบ identifier ก่อน analyze
📁 Folder structure ที่ปลอดภัย
my-data-project/
├── .gitignore ← สำคัญที่สุด
├── private/ ← ใน .gitignore
│ └── raw_responses.csv ← มี email + name
├── data/ ← commit ได้
│ ├── responses_anon.csv ← anonymized
│ └── responses_clean.csv
├── notebook.ipynb
├── README.md
└── .env ← ใน .gitignore (ถ้ามี API key)
.gitignore ต้องมี:
private/
*.raw.csv
.env
.env.local
git filter-branch หรือ BFG Repo-Cleaner ลบจริง ๆ ·
ทางที่ดีที่สุดคือ "ไม่ commit ตั้งแต่แรก"
📋 Project Spec — Mini Data Story
แต่ละนักศึกษาเลือก 1 หัวข้อ · ทำ end-to-end ใน 1 สัปดาห์ · เลือกตาม Tier
หัวข้อที่แนะนำ (จัดตาม Tier ความเสี่ยง)
| Tier | หัวข้อ | วิธีได้ข้อมูล | คำถามตัวอย่าง |
|---|---|---|---|
| 🟢 1 | มลพิษ PM2.5 / อากาศ | IQAir API หรือ aqicn.org |
วันไหน/ช่วงไหนค่าสูงสุด? เปลี่ยนตามฤดูยังไง? |
| 🟢 1 | การใช้ห้อง lab / เครื่องมือ | booking log ของห้องภาควิชา (anonymous) | เครื่องไหนใช้บ่อย? วันไหน peak? |
| 🟢 1 | การเดินทาง / TomTom | data.go.th / TomTom Traffic API | เวลาไหนช้าที่สุด? |
| 🟢 1 | Public dataset | Kaggle · data.go.th | วิเคราะห์ trend |
| 🟡 2 | นิสัยการนอน / กิจวัตร | Form 30+ คน · consent + anon | กิจกรรมไหนกินเวลามากที่สุด? |
| 🟡 2 | การใช้ AI ของนักศึกษา | Form 30+ คน · consent + anon | ใช้ AI กับงานไหนบ่อยที่สุด? |
| 🟡 2 | ค่าใช้จ่ายของตัวเอง (1 คน) | บันทึกของตัวเอง 30 วัน — ไม่ขอจากเพื่อน | หมวดไหนใช้เยอะ? |
| 🔴 3 | GPA / ผลคะแนน | หลีกเลี่ยง — ถ้าจำเป็น ใช้ของตัวเองเทียบกับ public average เท่านั้น | — |
🔄 Pipeline 5 ขั้น
Forms / API / CSV"/] clean["2. Clean
fix missing/wrong"] analyze["3. Analyze
groupby · calc · stats"] viz[("4. Visualize
4-5 กราฟ")] story(["5. Tell Story
insight 1 หน้า"]) collect --> clean --> analyze --> viz --> story classDef io fill:#0d3f3a,stroke:#2dd4bf,color:#fff classDef wrangle fill:#5c2618,stroke:#ffd43b,color:#fff classDef compute fill:#3b2962,stroke:#8b5cf6,color:#fff classDef plot fill:#1e3a5f,stroke:#3776ab,color:#fff classDef final fill:#064e3b,stroke:#34d399,stroke-width:2px,color:#fff class collect io class clean wrangle class analyze compute class viz plot class story final
ทุกขั้นเชื่อมกัน — ถ้าขั้นใดทำผิด ผลลัพธ์ขั้นถัด ๆ ไปจะ "แตกตาม"
1️⃣ Collect — เก็บข้อมูล
วิธี A: Google Forms
- สร้าง Form ที่
forms.google.com - ออกแบบคำถาม "ที่ตอบง่าย / ตอบเหมือนกันได้" — multiple choice ดีกว่า open-ended
- กระจายให้เพื่อน → รอ 30+ responses
- Form → Responses → Download as CSV
วิธี B: Public dataset
- data.go.th — ข้อมูลภาครัฐไทย
- Kaggle Datasets — หลากหลาย
- Bank of Thailand — เศรษฐกิจ
วิธี C: API call (preview ของ W12)
import requests
import pandas as pd
# IQAir example (PM2.5)
url = "https://api.airvisual.com/v2/city?city=Ubon Ratchathani&state=Ubon Ratchathani&country=Thailand&key=YOUR_KEY"
r = requests.get(url)
data = r.json()
2️⃣ Clean — ทำความสะอาด
ข้อมูลจริง "สกปรกเสมอ" — missing, typo, duplicate · ต้องจัดการก่อน แต่ระวัง AI ที่ลบของไม่ควรลบ
df.dropna() ทันที — ระวัง!
dropna() "ไม่มี argument" = ลบทุกแถวที่มี null แม้แต่ column เดียว ·
ถ้าเรา gpa null 30% และ sleep_hr null 10% — อาจ ลบไป 40% ของข้อมูล ·
ใช้ subset=["col1"] เสมอ — ระบุชัดว่าจะลบเมื่อ column ไหนเป็น null
3️⃣ Analyze — ตอบคำถาม
4️⃣ Visualize — 1 คำถาม = 1 กราฟ
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# Q1
gpa_by_sleep["mean"].plot(kind="bar", ax=axes[0], color="#3776ab")
axes[0].set_title("GPA เฉลี่ยตามการนอน")
axes[0].set_ylabel("GPA")
# Q2
spend_by_cat.plot(kind="barh", ax=axes[1], color="#ffd43b")
axes[1].set_title("ค่าใช้จ่ายแต่ละหมวด")
# Q3
pm_by_day.plot(kind="line", ax=axes[2], marker="o", color="#ec4899")
axes[2].set_title("PM2.5 ตามวันในสัปดาห์")
plt.tight_layout()
plt.savefig("report.png", dpi=150)
plt.show()
🤖 ตรวจ AI ก่อนเชื่อ — Data Verification
AI "พูดมั่นใจ" ทั้งที่ผิด · ในงาน data — บางทีต่างกัน 1 บรรทัด = ผิดทั้ง report · สัปดาห์นี้ฝึก "distrust + verify"
🚨 5 รูปแบบ Hallucination ของ AI ใน Data Work
| รูปแบบ | ตัวอย่าง | วิธีจับ |
|---|---|---|
| 1. Made-up numbers | "p-value = 0.043, statistically significant" — ไม่เคยรัน scipy เลย | ขอ code ที่คำนวณ + รันด้วยตัวเอง · ห้ามรับตัวเลขที่ AI พิมพ์ตรง ๆ |
| 2. Wrong column name | df.groupby("Year") ทั้งที่จริงคือ "year" (lowercase) |
รัน — ถ้า KeyError = พังตรงไหน · ถ้าเงียบ ๆ = ระวังกว่า |
| 3. dropna ที่ลบมากเกิน | df.dropna() ลบ 40% โดยไม่บอก · n เหลือ 18 จาก 30 |
เช็ค len(df) ก่อน/หลัง · ทุก cleaning step |
| 4. Off-by-one ใน aggregation | bins=[0, 6, 8, 24] — เวลา 6 ชม. ตกหมวดไหน? · บางครั้ง AI เขียน right=False ลืม |
รัน value_counts() ของ category ใหม่ — รวมแล้วเท่า total เดิมมั้ย? |
| 5. สรุปเกินที่ data รองรับ | "นอนน้อยทำให้ GPA ลดลง" จาก n=30 · เป็น correlation ไม่ใช่ cause | ดูหัวข้อ "Correlation ≠ Causation" ด้านล่าง |
📐 Pattern 1: Data Validation — ใส่ assert ทุกขั้น
ก่อน analyze — เช็คก่อนว่า data ที่เรามี "เป็นไปตามที่คิด"
assert สำคัญ — fail fast
ถ้า data ผิด · ให้ "พังตรงนี้" · ไม่ใช่ "ผ่านไปแล้วได้ report ผิด" · ดีกว่ารู้ทีหลังตอน demo
🔍 Pattern 2: Manual Cross-Check — เช็คด้วยมือ 3 rows
หลัง groupby/aggregate ทุกครั้ง · เลือก 3 rows สุ่ม · คำนวณด้วยมือ · เทียบกับ AI
⚠️ Pattern 3: Correlation ≠ Causation
นี่คือ correlation · ไม่ใช่ causation · อาจเป็นเพราะ:
- ทิศทางตรงข้าม: GPA ต่ำ → เครียด → นอนไม่หลับ (ไม่ใช่นอนน้อยทำ)
- Confounding variable: งานพิเศษ → ทั้งนอนน้อย ทั้งไม่มีเวลาเรียน
- Selection bias: เฉพาะคนที่ตอบ Form (ปกตินอนเยอะกว่าค่าเฉลี่ย)
- Small sample: n=30 — coincidence ได้ง่าย
📊 Pattern 4: ดูกราฟก่อน trust ตัวเลข
Anscombe's Quartet — 4 datasets ที่ "mean / variance / correlation เหมือนกันทุกตัว" แต่กราฟต่างกันโดยสิ้นเชิง · บางอันมี outlier · บางอันไม่ใช่ linear · กราฟแสดงสิ่งที่ summary ตัวเลขไม่บอก
หลัง groupby ทุกครั้ง → ทำ plt.scatter หรือ boxplot ดูก่อนเชื่อ mean
📏 Pattern 5: ระบุข้อจำกัดใน Report — แม้ AI จะไม่บอก
| ข้อจำกัด | ต้องเขียนใน report |
|---|---|
| Sample size เล็ก (n < 100) | "ผลนี้จากตัวอย่าง n=X เท่านั้น · อาจไม่สะท้อนประชากรทั้งหมด" |
| Self-selection bias | "เฉพาะคนที่ยินดีตอบ Form · อาจ skew" |
| Self-report | "ข้อมูลจากการรายงานตนเอง · อาจเอียงไปทาง 'น่าจะดูดี'" |
| Time window | "เก็บช่วง X-Y · อาจไม่สะท้อนช่วงสอบ/ปิดเทอม" |
| Missing demographic mix | "คนตอบ 90% เป็น MAE · ไม่สะท้อนสาขาอื่น" |
5️⃣ Tell Story — Insight Report
Template — Insight Report
# Data Story: [หัวข้อ]
## คำถาม
1. ...
2. ...
3. ...
## ที่มาของข้อมูล
- จาก: [Google Form / data.go.th / etc.]
- ขนาด: [กี่ records, period ไหน]
- ข้อจำกัด: [bias / sample size / coverage]
## ผลที่พบ
1. **[คำถาม 1]** → [ตัวเลข + กราฟ + ความหมาย 2-3 ประโยค]
2. ...
3. ...
## ที่ "ทำให้แปลกใจ"
[1 ประโยค — สิ่งที่ไม่คาด]
## ข้อจำกัด
- [bias ที่อาจมี]
- [confounding variable ที่ไม่ได้คุม]
## ใช้กับใคร / ทำต่อยังไง
- [ใครได้ประโยชน์จาก insight นี้]
- [ถ้ามีเวลาอีก จะทำอะไรต่อ]
🧪 Workshop — Full Pipeline
- เลือกหัวข้อ + วิธีเก็บข้อมูล — ภายในวันแรก
- เก็บข้อมูลให้ได้ ≥ 30 records — ถ้า Form ก็ส่งให้เพื่อน · ถ้า dataset ก็ download
-
เขียน 3 คำถาม ที่อยากตอบ
ลงใน
questions.mdก่อนเริ่ม analyze (อย่าให้ data ชี้นำ) -
เปิด Jupyter/Colab ทำ data cleaning · เซฟ
clean.csv - ตอบ 3 คำถามด้วย pandas + วาดกราฟแต่ละคำถาม
-
เซฟกราฟเป็น
report.pngหรือcharts/folder - เขียน Insight Report ตาม template (1 หน้า A4)
- Demo กับเพื่อน 1 คน · บันทึก feedback
🎯 Rubric — ประเมิน Data Project
| เกณฑ์ | คะแนน | มาตรฐาน |
|---|---|---|
| Data collection | 20 | ≥ 30 records จริง · มี source ที่ verify ได้ |
| Data cleaning | 15 | handle missing + duplicate + type · log ใน notebook |
| Analysis | 20 | ตอบ 3 คำถามถูก · มี groupby/agg |
| Visualization | 20 | ≥ 3 กราฟ · มี title/label · เลือกชนิดถูก |
| Insight | 15 | เห็น pattern · เขียนเป็นภาษาคนได้ |
| Limitations | 10 | ระบุ bias / sample / confound |
ข้อผิดที่พบบ่อย
ส่งงานสัปดาห์นี้
- 📓 notebook ครบ pipeline + raw.csv + clean.csv
- 🖼️ 3+ กราฟใน folder
charts/หรือreport.png - 📄 insight-report.md 1 หน้า ตาม template
- 🎤 บันทึก feedback จาก demo กับเพื่อน 1 คน
Reference จาก slide เดิม
ครอบคลุม Topic 10 — Pandas + Stat ครบ + ขยายเป็น end-to-end project ตาม Mainidea