forcast / README.md
Therdpoom's picture
Upload 9 files
01c066b verified
|
Raw History Blame Contribute Delete
5.9 kB
metadata
title: Predicty Forecast API
emoji: 📈
colorFrom: green
colorTo: blue
sdk: docker
app_port: 7860
pinned: false

Predicty · Sales Forecast API (v2 — teaching edition)

Backend พยากรณ์ยอดขายสำหรับหลักสูตร Non-Degree นักวิเคราะห์ข้อมูลและแบบจำลองเชิงพยากรณ์ กรณีศึกษา: ENT Group (ข้อมูลใบเสนอราคา + ใบเสร็จจริง 90 เดือน)

หลักการออกแบบ: "อ่านผลอย่างซื่อสัตย์"

ตัวเลขความแม่นยำทุกตัวใน API นี้มาจาก การทดสอบย้อนหลังจริง (rolling-origin backtest) ไม่มีค่าใดที่คำนวณขึ้นเองเพื่อให้ดูดี

v1 v2
confidence = 1 - resid/mean (สูตรกุขึ้นเอง → โชว์ 94%) accuracy.mape จาก backtest จริง
ช่วงความเชื่อมั่นกว้างเท่ากันทุกเดือน σ วัดแยกตามระยะ → กว้างขึ้นตามระยะ
guardrails บีบค่าเงียบ ๆ ปิดโดยปริยาย เปิดแล้วรายงานว่าตัดเดือนไหน
เลือกโมเดลจาก holdout ครั้งเดียว ≤3 เดือน rolling-origin หลายจุดเริ่ม + ตารางอันดับทุกโมเดล + skill score
ไม่มี baseline naive / mean3 / seasonal_naive เป็นด่านที่โมเดลต้องเอาชนะ

Endpoints

Method Path ใช้ทำอะไร
GET / รายการ endpoint + คำอธิบายโมเดล
GET /health health check
GET /api/sample ข้อมูลจริง ENT 90 เดือน (ให้ UI กดโหลด)
POST /api/forecast พยากรณ์ + ตารางเทียบโมเดล + ยอดรวมทั้งช่วง + คำเตือน
POST /api/backtest ทดสอบย้อนหลังอย่างเดียว (หน้าจอ "เทียบโมเดล")
POST /api/decompose STL: trend / seasonal / residual + ความแรงองค์ประกอบ
POST /api/diagnostics ADF, ACF/PACF, คุณภาพข้อมูล, คำแนะนำพารามิเตอร์ SARIMA

ตัวอย่าง

curl -X POST https://Therdpoom-forcast.hf.space/api/forecast \
  -H "Content-Type: application/json" \
  -d '{"data":[{"date":"2025-01","sales":100}, ...],
       "periods":6, "model":"auto", "interval":80,
       "drop_last_incomplete":true, "guardrails":false}'

พารามิเตอร์ของ /api/forecast

ชื่อ ค่าปริยาย ความหมาย
data — [{date:"YYYY-MM", sales:number}] อย่างน้อย 6 เดือน
periods 6 จำนวนเดือนที่พยากรณ์ (1–24)
model auto auto | naive | mean3 | seasonal_naive | linear | holtwinters | sarima
interval 80 ระดับช่วงความเชื่อมั่น: 80 / 90 / 95
drop_last_incomplete false ตัดเดือนสุดท้าย (มักเก็บข้อมูลไม่ครบ) ก่อนฝึกโมเดล
guardrails false บีบค่าพยากรณ์ให้อยู่ใน [avg/3, avg×3] — เปิดแล้วจะรายงานเดือนที่ถูกตัด

ผลจริงกับข้อมูล ENT (89 เดือน, ตัด มิ.ย. 2026 ที่ยังไม่ครบ)

model            MAPE รายเดือน   MAPE ยอดรวม 6 เดือน   skill vs seasonal_naive
linear                   27.8%                 16.6%    +0.13
mean3 (baseline)         29.7%                 16.5%    +0.07
seasonal_naive           31.9%                 21.7%     0.00
holtwinters              32.7%                 16.8%    -0.03
sarima                   35.9%                 21.2%    -0.12
naive (baseline)         38.3%                 30.3%    -0.20

บทเรียนที่ได้จากตัวเลขชุดนี้

  1. โมเดลซับซ้อน (SARIMA / Holt-Winters) แพ้ ค่าเฉลี่ย 3 เดือนล่าสุด — สอดคล้องกับผล STL ที่วัดความแรงฤดูกาลได้เพียง 0.17 และ residual กินความผันผวนไป 63%
  2. พยากรณ์ ยอดรวม 6 เดือน ผิดแค่ ~17% เทียบกับรายเดือน ~28% → ถ้าจะตั้งเป้า ให้ตั้งเป็นยอดรวมไตรมาส/ครึ่งปี ไม่ใช่รายเดือน
  3. เพดานของการพยากรณ์ถูกกำหนดโดย ข้อมูล ไม่ใช่โมเดล — ตรงกับบทเรียนจาก Win/Loss Classifier (AUC ~0.65) ในกรณีศึกษาเดียวกัน

การรันในเครื่อง

pip install -r requirements.txt
python app.py            # http://localhost:7860