ทำไมต้องสถิติทนทาน?
ส่วนเบี่ยงเบนมาตรฐานเป็นตัววัดการกระจายตัวที่ทรงพลัง แต่มีจุดอ่อนสำคัญ: ความไวต่อค่าผิดปกติอย่างมาก ค่าสุดโต่งเพียงค่าเดียวสามารถทำให้ SD เพิ่มขึ้นอย่างมาก ให้ภาพที่ทำให้เข้าใจผิดของความแปรผันโดยทั่วไป
สถิติทนทาน ให้ตัววัดการกระจายตัวที่ต้านทานอิทธิพลของค่าผิดปกติ ทำให้จำเป็นสำหรับข้อมูลในชีวิตจริงที่ข้อผิดพลาดในการวัด ข้อผิดพลาดในการป้อนข้อมูล หรือกรณีสุดโต่งจริงเป็นเรื่องปกติ
ตัวอย่าง: ผลกระทบของค่าผิดปกติ
จุดพังทลาย
ค่าเบี่ยงเบนสัมบูรณ์จากมัธยฐาน (MAD)
MAD เป็นตัววัดการกระจายตัวที่ทนทานที่สุด คำนวณมัธยฐานของค่าเบี่ยงเบนสัมบูรณ์จากมัธยฐาน:
สูตร MAD
หามัธยฐาน
คำนวณค่าเบี่ยงเบน
หา MAD
การปรับ MAD เพื่อประมาณ σ: สำหรับข้อมูลที่มีการแจกแจงปกติ MAD ≈ 0.6745 × σ เพื่อประมาณ SD จาก MAD ให้คูณด้วย 1.4826:
ค่าประมาณ SD จาก MAD
ทำไมต้อง 1.4826?
พิสัยระหว่างควอร์ไทล์ (IQR)
IQR วัดการกระจายตัวของข้อมูล 50% ตรงกลาง ช่วงระหว่างเปอร์เซ็นไทล์ที่ 25 ถึงที่ 75:
สูตร IQR
IQR ถูกใช้กันอย่างแพร่หลายเพราะเข้าใจง่าย แสดงเป็นภาพในกล่องพล็อตได้ง่าย และเป็นพื้นฐานของ “กฎ 1.5×IQR” ที่ใช้กันทั่วไปสำหรับการตรวจจับค่าผิดปกติ
การปรับ IQR เพื่อประมาณ σ: สำหรับข้อมูลปกติ IQR ≈ 1.35 × σ เพื่อประมาณ SD จาก IQR:
ค่าประมาณ SD จาก IQR
การเปรียบเทียบตัววัดทนทาน
ส่วนเบี่ยงเบนมาตรฐาน
MAD
IQR
เมื่อไหร่ควรใช้สถิติทนทาน
- การวิเคราะห์เชิงสำรวจ: เมื่อคุณไม่รู้ว่ามีค่าผิดปกติหรือไม่ เริ่มด้วยตัววัดทนทาน
- ปัญหาคุณภาพข้อมูล: เมื่อข้อมูลอาจมีข้อผิดพลาดหรือปัญหาการวัด
- การแจกแจงหางหนัก: เมื่อคาดว่าจะมีค่าสุดโต่ง (ผลตอบแทนทางการเงิน การเรียกร้องประกัน)
- ตัวอย่างเล็ก: เมื่อค่าผิดปกติมีผลกระทบมากเกินสัดส่วนเนื่องจากข้อสังเกตน้อย
- การตรวจจับค่าผิดปกติ: การใช้ SD เพื่อตรวจจับค่าผิดปกติเป็นวงจรอุบาทว์ ใช้ IQR หรือ MAD แทน
ตัวอย่างการนำไปใช้
import numpy as np
from scipy import stats
def mad(data):
"""Median Absolute Deviation"""
median = np.median(data)
return np.median(np.abs(data - median))
def scaled_mad(data):
"""MAD scaled to estimate SD (for normal data)"""
return 1.4826 * mad(data)
def iqr(data):
"""Interquartile Range"""
return np.percentile(data, 75) - np.percentile(data, 25)
# Compare on data with outlier
data = [10, 12, 11, 13, 12, 11, 100]
print(f"SD: {np.std(data, ddof=1):.2f}")
print(f"MAD: {mad(data):.2f}")
print(f"Scaled MAD: {scaled_mad(data):.2f}")
print(f"IQR: {iqr(data):.2f}")