1.3 離散與分位#
本節目標#
- 理解變異數與標準差的定義,以及「為什麼除 \(n-1\) 」(Bessel 修正),並用模擬驗證 \(E[s^2] = \sigma^2\)
- 認識穩健的離散度量:IQR 與 MAD
- 會用
r.var/r.sd/r.IQR/r.mad/r.scale
平均數說一半,離散說另一半#
「這班平均 170 公分」聽起來完整,其實漏了關鍵一半:是人人 170±1,還是有人 155 有人 185?兩種班的平均可以一模一樣。離散度量(dispersion)負責補上這另一半:資料散得多開。
變異數與標準差#
最直接的想法:算每個點離平均的距離,再平均。但 \(\sum (x_i - \bar{x})\) 恆為 0(正負抵銷),所以取平方:
\(s^2 = \dfrac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2, \qquad s = \sqrt{s^2}\)
平方把單位也平方了(cm² 變 cm²),開根號回到原單位——這就是標準差存在的理由。
import rstatistics as r
g = r.set_seed(7)
x = g.rnorm(10, mean=50, sd=5)
print([round(v, 2) for v in x])
print(r.var(x), r.sd(x))
輸出:
[61.44, 44.02, 46.53, 47.94, 45.15, 45.26, 53.74, 49.42, 50.76, 60.95]
40.110904772833166 6.333317043448336
母體設定是 \(\sigma = 5\) ,這個 \(n = 10\) 的小樣本算出 \(s = 6.33\) ——單一樣本的估計本來就會晃,晃多少,下面馬上用模擬看。
為什麼除 \(n-1\) :Bessel 修正#
多數初學者的第一個抗議是:平均已經用了 \(\bar{x}\) (而不是真正的 \(\mu\) ),資料點到 \(\bar{x}\) 的距離天生偏小——畢竟 \(\bar{x}\) 就是最小化這些距離平方的那一點(1.2 節的結論!)。樣本內部互相靠攏的結果, \(\`\frac{1}{n}\sum(x_i-\bar{x})^2`\) 系統性地低估 \(\sigma^2\) 。
數學上可以證明(自由度論證):
\(E\!\left[\frac{1}{n}\sum_{i=1}^{n}(x_i-\bar{x})^2\right] = \frac{n-1}{n}\,\sigma^2\)
把它乘上 \(\dfrac{n}{n-1}\) ——也就是分母改用 \(n-1\) ——期望值恰好回到 \(\sigma^2\) 。這個修正叫Bessel 修正(Bessel's correction,19 世紀天文測量傳統中的 Friedrich Bessel 所用);除掉的 1 對應「 \(\`\bar{x}`\) 吃掉一個自由度」。
空話不如模擬。從 \(\sigma = 2\) 的母體抽樣,分別用分母 \(n\) 與 \(n-1\) 算變異數,各重複 5000 次看平均值:
import rstatistics as r
for n in (3, 10, 100):
g2 = r.set_seed(123)
biased = r.mean([(lambda v: sum((a - r.mean(v)) ** 2 for a in v) / n)(g2.rnorm(n, mean=10, sd=2))
for _ in range(5000)])
g2 = r.set_seed(123)
unbiased = r.mean([r.var(g2.rnorm(n, mean=10, sd=2)) for _ in range(5000)])
print(n, biased, unbiased)
輸出:
3 2.658664315908029 3.9879964738620433
10 3.6066346198699026 4.007371799855447
100 3.969040028000778 4.009131341414927
三個事實一目瞭然:
- 除以 \(n-1\) 的估計穩定貼著 \(\sigma^2 = 4\) ;
- 除以 \(n\) 的估計偏低,且 \(\frac{n-1}{n}\) 預測的理論低率吻合: $`n=3
$ 時應為 $4 \times \frac{2}{3} \approx 2.67$ (實際 2.659), $\n=10`$ 時應為 \(4 \times \frac{9}{10} = 3.6\) (實際 3.607); - \(n\) 越大兩者越接近——Bessel 修正是小樣本的救命補丁,不是大樣本的必要品。
什麼時候用 \(n\) ?當你手上就是整個母體(例如全班成績,你想描述這班本身而非推論別的班),描述性計算可用 \(n\) ;只要是要從樣本推論母體(本書主要場景),一律 \(n-1\) 。
穩健離散:IQR 與 MAD#
標準差用到了每個數的平方,因此比平均數更怕離群值(平方放大極端值)。1.2 節的中位數邏輯搬過來,就得到穩健的離散度量:
- IQR(四分位距)= \(Q_3 - Q_1\) ,中間 50% 資料的寬度,砍掉頭尾各 25%。
- MAD(中位絕對偏差)= 各點到中位數的距離再取中位數。為了在常態資料上與 \(\sigma\) 對得上,實務上乘一個常數 \(1.4826\) (R 與
r.mad的內定值)。
print(r.IQR(x), r.mad(x), r.mad(x, constant=1.0))
輸出:
7.416509991592086 5.147235487708059 3.4717627733090914
離群值來襲時的表現才是重點。在 x 尾端塞一個 500:
y = x + [500.0]
print(r.mean(y), r.sd(y), r.median(y), r.mad(y))
輸出:
91.38170753600606 135.65647716668917 49.41522387056424 6.328612388217272
一個 500 讓平均從 50.5 飛到 91.4、標準差從 6.3 暴漲到 135.7;中位數與 MAD 幾乎紋風不動。報告離散度之前,先問自己資料裡有沒有怪物。
標準化:z 分數#
r.scale(x) 把資料減平均、除標準差,轉成平均 0、標準差 1 的 z 分數——不同單位的量(身高 cm 與體重 kg)因此可以並排比較:
z = r.scale(x)
print([round(v, 3) for v in z])
print(r.mean(z), r.sd(z))
輸出:
[1.724, -1.027, -0.63, -0.408, -0.848, -0.83, 0.509, -0.174, 0.038, 1.647]
2.220446049250313e-16 1.0
平均值是 \(10^{-16}\) 級別的浮點殘渣、標準差恰為 1。z 分數的解讀: \(z = 1.7\) 表示「比平均高 1.7 個標準差」。
只看平均會犯的錯:兩個班的身高#
平均數相同、離散不同,結論可以天差地遠。模擬兩個班,平均都約 170,但標準差一個 3、一個 10:
g = r.set_seed(3)
a = [round(v, 1) for v in g.rnorm(20, mean=170, sd=3)]
b = [round(v, 1) for v in g.rnorm(20, mean=170, sd=10)]
print(r.mean(a), r.sd(a))
print(r.mean(b), r.sd(b))
輸出:
169.505 2.353826671613695
170.54 8.87174106214131
A 班 s ≈ 2.4(大家都在 165–175 之間),B 班 s ≈ 8.9(有人 150、有人 190)。若校服只有一種尺寸,A 班皆大歡喜,B 班勉強穿;若要挑籃球隊,B 班才有 190 的人選。「平均多少」回答不了「接下來會發生什麼」,標準差才回答得了。
變異數有個好性質:獨立就相加#
標準差看似直觀,但標準差不可相加;可以相加的是變異數:兩個獨立量之和的變異數等於變異數之和, \(\`\mathrm{Var}(X+Y) = \mathrm{Var}(X) + \mathrm{Var}(Y)`\) 。用模擬驗證:
g2 = r.set_seed(9)
n = 500
u = g2.rnorm(n)
v = g2.rnorm(n)
s_u, s_v = r.sd(u), r.sd(v)
s_uv = r.sd([ui + vi for ui, vi in zip(u, v)])
print(s_u ** 2, s_v ** 2, s_uv ** 2, s_u ** 2 + s_v ** 2)
輸出:
0.9296238421506865 0.9151167487320517 1.738930989131087 1.8447405908827381
和的變異數 1.739 ≈ 兩變異數之和 1.845(500 筆的模擬誤差內)。這條性質是 1.1 節「標準誤 \(\sigma/\sqrt{n}\) 」的來源: \(\`n`\) 個獨立觀測的總和變異數是 \(n\sigma^2\) ,除以 \(n\) 後變異數剩 \(\sigma^2/n\) ,開根號就是 \(\sigma/\sqrt{n}\) 。數學在這裡接回來了。
與 R 對照#
set.seed(7)
x <- rnorm(10, 50, 5)
cat(var(x), sd(x), "\n")
cat(IQR(x), mad(x), "\n")
print(round(scale(x), 3))
輸出:
40.1109 6.333317
7.41651 5.147236
[1] 1.725 -1.023 -0.630 -0.408 -0.848 -0.831 0.509 -0.017 0.039 1.645
r.var / r.sd / r.IQR / r.mad / r.scale 與 R 同名函數逐位一致(連 Bessel 修正、MAD 常數 1.4826 都相同)。
小結#
- 變異數 \(s^2\) 、標準差 \(s\) 量「平均而言離中心多遠」;分母 \(n-1\) 是 Bessel 修正,補償 \(\bar{x}\) 已吃掉一個自由度,使 \(E[s^2] = \sigma^2\) (模擬驗證過,連 \(\frac{n-1}{n}\) 的低率都吻合)。
- IQR、MAD 是離散度的「中位數版」:砍掉極端值,穩健但不利用全部資訊。
r.scale標準化後的 z 分數讓不同單位的資料可比。- 選擇:乾淨、對稱資料用 sd;有離群值用 IQR/MAD。下節的箱型圖正是 IQR 的圖形化。
練習#
- 把模擬中的 \(n\) 改成 2 與 5,檢查除以 \(n\) 的估計是否符合 \(\frac{n-1}{n} \cdot 4\) 。
- 對
x = [1, 2, 3, 4, 100],分別算r.sd(x)與r.mad(x),然後把 100 改成 1000 再算一次。哪個量變化超過 10 倍? - 用
r.scale把你的身高(公分)換算成 z 分數,並用r.pnorm查「隨機一人比你高的機率」(提示:1 - r.pnorm(z))。 - IQR 與 sd 在常態資料上應約有固定比例關係:用 \(n = 1000\) 的
g.rnorm驗證r.IQR(x) / r.sd(x) ≈ 1.349。 - 思考題:報導寫「本市平均所得 90 萬,標準差 120 萬」。從標準差比平均還大這件事,你對這組資料的形狀能推論出什麼?(提示:想想離群值與偏斜。)