← ทำไมตาถึงอ่านกราฟนี้ได้เร็วกว่า
LEVEL 2 · ระดับกลาง
เมื่อค่าสรุปปิดบังความจริง
มาถึงตรงนี้ทั้งเล่มพูดเรื่องเดียวกันมาตลอด คือความสูญเสียตอนตาถอดรหัส ซึ่งอาจทำให้คุณคิดว่า ถ้าอย่างนั้นอ่านจากตัวเลขก็สิ้นเรื่อง ไม่ต้องวาดเลย
บทนี้คือบทที่หักล้างความคิดนั้น และมันคือคำตอบของปริศนาข้อที่สามที่ปลูกไว้ตั้งแต่บทที่ 1
10.1 สี่ชุดข้อมูลที่ค่าสรุปเหมือนกันหมด
ทั้งสี่ชุดมีค่าเฉลี่ยของ x เท่ากัน ค่าเฉลี่ยของ y เท่ากัน ความแปรปรวนเท่ากัน สหสัมพันธ์เท่ากัน และเส้นถดถอยเป็นเส้นเดียวกันเป๊ะ
ถ้าคุณได้รับแค่ตารางค่าสรุป คุณจะรายงานว่าทั้งสี่ชุดเป็นเรื่องเดียวกัน แต่พอวาดออกมา
- ชุด I กระจายรอบเส้นตามปกติ เป็นชุดเดียวที่เส้นถดถอยอธิบายได้จริง
- ชุด II โค้งชัดเจน การลากเส้นตรงผ่านมันคือการอธิบายผิดชนิด
- ชุด III เรียงตรงเป๊ะ ยกเว้นจุดเดียวที่ดึงเส้นให้เอียงไปจากความจริง
- ชุด IV x เท่ากันหมดยกเว้นจุดเดียว ซึ่งแปลว่า จุดเดียวนั้นลากเส้นทั้งเส้นไปเอง ลบมันออก แล้วความชันจะไม่มีความหมายอะไรเลย
ชุด IV คือชุดที่น่ากลัวที่สุดในงานจริง เพราะค่าสรุปดูดีทุกตัว แต่ข้อสรุปทั้งหมดแขวนอยู่บนข้อมูลจุดเดียว
10.2 พิสูจน์ด้วยตัวเอง
ชุดนี้เรียกว่า Anscombe's quartet เผยแพร่โดย Francis Anscombe ปี 1973 · สคริปต์ข้างล่าง (anscombe.py) คำนวณค่าสรุปทั้งห้าตัวจากข้อมูลดิบ ไม่ได้ลอกตัวเลขมา แล้วพิมพ์พิกัดทุกจุดที่ใช้วาด FIG 10.1 ต่อท้าย
"""ชุด Anscombe — ค่าสรุปเท่ากันเกือบทุกตัว แต่ภาพคนละเรื่อง"""
X123 = [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5]
SETS = {
"I": (X123, [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68]),
"II": (X123, [9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74]),
"III": (X123, [7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73]),
"IV": ([8, 8, 8, 8, 8, 8, 8, 19, 8, 8, 8],
[6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 12.50, 5.56, 7.91, 6.89]),
}
def mean(v):
return sum(v) / len(v)
def var(v): # ความแปรปรวนแบบกลุ่มตัวอย่าง (หารด้วย n-1)
m = mean(v)
return sum((x - m) ** 2 for x in v) / (len(v) - 1)
def corr(x, y):
mx, my = mean(x), mean(y)
sxy = sum((a - mx) * (b - my) for a, b in zip(x, y))
sxx = sum((a - mx) ** 2 for a in x)
syy = sum((b - my) ** 2 for b in y)
return sxy / (sxx * syy) ** 0.5
def fit(x, y): # เส้นถดถอยด้วยวิธีกำลังสองน้อยสุด
mx, my = mean(x), mean(y)
slope = sum((a - mx) * (b - my) for a, b in zip(x, y)) / sum((a - mx) ** 2 for a in x)
return my - slope * mx, slope
print(f"{'ชุด':<5}{'x เฉลี่ย':>9}{'y เฉลี่ย':>10}{'var x':>8}{'var y':>8}"
f"{'สหสัมพันธ์':>12} เส้นถดถอย")
for name, (x, y) in SETS.items():
b0, b1 = fit(x, y)
print(f"{name:<5}{mean(x):>9.2f}{mean(y):>10.2f}{var(x):>8.2f}{var(y):>8.2f}"
f"{corr(x, y):>12.3f} y = {b0:.2f} + {b1:.2f}x")
print(f"\nค่าสรุปตรงกันถึงทศนิยมตำแหน่งที่สอง (คลาดกันในหลักสุดท้ายบ้าง) แต่ลองวาดดูสิ")
# --- พิกัดที่ใช้วาด FIG 10.1: x 4-19 -> 0-190 px, y 3-13 -> 150-0 px ---
print("\n=== พิกัดจุดของ FIG 10.1 (px) ===")
for name, (x, y) in SETS.items():
pts = [(round((a - 4) / 15 * 190, 1), round(150 - (b - 3) / 10 * 150, 1))
for a, b in zip(x, y)]
print(f" {name}: {pts}")
b0, b1 = fit(*SETS["I"])
print(f"\nเส้นถดถอยร่วม y = {b0:.2f} + {b1:.2f}x")
for xv in (4, 19):
yv = b0 + b1 * xv
print(f" x={xv} -> px ({round((xv - 4) / 15 * 190, 1)}, "
f"{round(150 - (yv - 3) / 10 * 150, 1)})")ผลรันจริง
ชุด x เฉลี่ย y เฉลี่ย var x var y สหสัมพันธ์ เส้นถดถอย
I 9.00 7.50 11.00 4.13 0.816 y = 3.00 + 0.50x
II 9.00 7.50 11.00 4.13 0.816 y = 3.00 + 0.50x
III 9.00 7.50 11.00 4.12 0.816 y = 3.00 + 0.50x
IV 9.00 7.50 11.00 4.12 0.817 y = 3.00 + 0.50x
ค่าสรุปตรงกันถึงทศนิยมตำแหน่งที่สอง (คลาดกันในหลักสุดท้ายบ้าง) แต่ลองวาดดูสิ
=== พิกัดจุดของ FIG 10.1 (px) ===
I: [(76.0, 74.4), (50.7, 90.8), (114.0, 81.3), (63.3, 62.8), (88.7, 70.0), (126.7, 45.6), (25.3, 86.4), (0.0, 131.1), (101.3, 32.4), (38.0, 122.7), (12.7, 109.8)]
II: [(76.0, 57.9), (50.7, 72.9), (114.0, 63.9), (63.3, 63.5), (88.7, 56.1), (126.7, 73.5), (25.3, 103.0), (0.0, 148.5), (101.3, 58.0), (38.0, 86.1), (12.7, 123.9)]
III: [(76.0, 83.1), (50.7, 93.5), (114.0, 3.9), (63.3, 88.3), (88.7, 77.9), (126.7, 62.4), (25.3, 103.8), (0.0, 114.2), (101.3, 72.8), (38.0, 98.7), (12.7, 109.0)]
IV: [(50.7, 96.3), (50.7, 108.6), (50.7, 79.4), (50.7, 62.4), (50.7, 67.9), (50.7, 89.4), (50.7, 116.2), (190.0, 7.5), (50.7, 111.6), (50.7, 76.3), (50.7, 91.7)]
เส้นถดถอยร่วม y = 3.00 + 0.50x
x=4 -> px (0.0, 120.0)
x=19 -> px (190.0, 7.5)10.3 คำตอบของปริศนาข้อที่สาม
คำถามที่ปลูกไว้ตั้งแต่บทที่ 1 คือ ถ้าตาถอดค่าจากกราฟได้ไม่แม่น แล้วเราจะเชื่อกราฟไปทำไม
คำตอบคือ กราฟกับตัวเลขไม่ได้ทำงานเดียวกัน
| ตัวเลข | ภาพ |
|---|---|
| แม่นทุกหลัก | อ่านค่าได้ไม่แม่น |
| บอกรูปร่างไม่ได้เลย | บอกรูปร่างได้ทันที |
| ซ่อนจุดผิดปกติ | จุดผิดปกติเด้งขึ้นมาเอง (บทที่ 2) |
| ตอบว่า "เท่าไหร่" | ตอบว่า "มันเป็นแบบไหน" |
การถอดรหัสที่ไม่แม่นซึ่งเราไล่มาเก้าบท คือราคาของคอลัมน์ขวา และมันคุ้ม เพราะคอลัมน์ซ้ายไม่มีทางบอกคุณได้เลยว่าข้อมูลของคุณเป็นชุด I หรือชุด IV
ตัวเลขบอกว่าเท่าไหร่ ภาพบอกว่ามันเป็นแบบไหน — และคุณผิดพลาดได้ราคาแพงกว่ามาก เวลาไม่รู้ว่ามันเป็นแบบไหน
10.4 นิสัยเดียวที่ควรติดตัวจากบทนี้
วาดก่อนสรุปเสมอ แม้จะไม่มีใครได้เห็นภาพนั้นเลยก็ตาม
ภาพที่คุณวาดให้ตัวเองดูสามสิบวินาทีก่อนส่งรายงาน ไม่ต้องสวย ไม่ต้องมีหัวข้อ ไม่ต้องเลือกสี มันมีหน้าที่เดียวคือบอกคุณว่าค่าสรุปที่คุณกำลังจะเขียนลงไปนั้น อธิบายข้อมูลจริงหรือกำลังปิดบังมันอยู่