Python NormalDist: แปลงค่าเฉลี่ยกับส่วนเบี่ยงเบนเป็น threshold ที่อธิบายได้
การตั้ง alert ที่ “ค่าเฉลี่ยบวกสองเท่าของส่วนเบี่ยงเบนมาตรฐาน” มักถูกคัดลอกมาโดยไม่รู้ว่าครอบคลุมความน่าจะเป็นเท่าไรครับ statistics.NormalDist ทำให้สมมติฐานนั้นเป็น object และแปลงระหว่างค่า, percentile และ probability ได้ด้วย standard library
เปรียบเหมือนกองเมล็ดที่หนาตรงกลางและบางลงสองข้าง เราเลือกเส้นกั้นจากสัดส่วนที่ยอมให้ล้น แทนเดาตำแหน่งเส้นด้วยความรู้สึก
import unittest
from statistics import NormalDist
def upper_threshold(mean: float, stdev: float, percentile: float) -> float:
if not 0.0 < percentile < 1.0:
raise ValueError("percentile must be between zero and one")
return NormalDist(mu=mean, sigma=stdev).inv_cdf(percentile)
class NormalDistTests(unittest.TestCase):
def test_percentile_and_probability_are_inverse(self):
latency = NormalDist(mu=120.0, sigma=15.0)
threshold = upper_threshold(120.0, 15.0, 0.95)
self.assertAlmostEqual(latency.cdf(threshold), 0.95, places=10)
self.assertGreater(threshold, latency.mean)
def test_invalid_percentile_is_rejected(self):
with self.assertRaises(ValueError):
upper_threshold(10.0, 2.0, 1.0)
if __name__ == "__main__":
unittest.main()
สูตรถูกได้ แต่ model ผิดได้
cdf(x) ตอบโอกาสที่ค่าจะไม่เกิน x; inv_cdf(p) ตอบค่าที่ percentile p หากข้อมูลเป็น normal distribution ตาม mu และ sigma ที่ให้ แต่ latency, queue depth และยอดขายมักเอียงขวา มี outlier หรือเปลี่ยน regime ตามเวลา การใช้ NormalDist ไม่ได้ทำให้ข้อมูลจริงเป็นโค้งปกติ
ก่อนใช้ threshold ให้ดู histogram/quantile จริง แยกช่วงเวลาที่ workload ต่างกัน และวัด false positive/false negative หาก sample น้อยหรือ tail สำคัญ ใช้ empirical percentile อาจตรงกว่า ส่วน NormalDist.from_samples เหมาะกับการประมาณจากตัวอย่างเมื่อยอมรับข้อจำกัดเรื่อง sampling แล้ว อย่าส่ง sigma=0 เข้า calculation ที่ต้องหารด้วยส่วนเบี่ยงเบน และอย่าแปล percentile เป็น SLA โดยไม่มี business context
Recap
- ใช้
inv_cdfเพื่อคำนวณ threshold จาก percentile ที่ต้องการ - ใช้
cdfตรวจ probability ของค่าที่สังเกต - ตรวจรูป distribution จริงก่อนสมมติว่าเป็น normal
- ติดตาม error rate หลังนำ threshold ไปใช้