9.2 係數的估計與標準誤#
本節目標#
- 說明「估計值」與「標準誤」為什麼必須一起報導
- 會算殘差變異數 \(s^2\) 與係數的標準誤
- 逐行讀懂
summary(lm)的輸出:Estimate、Std. Error、t value、Pr(>|t|) - 理解 \(R^2\) 的意義,以及單元迴歸中 \(R^2 = r^2\) 這個好用的關係
- 知道信賴區間是怎麼從「估計值 ± 標準誤」來的(完整版在 9.5)
問題場景:一個數字不夠#
上一節我們用最小平方法得到 Galton 資料的擬合線:
\(\hat{y} = 23.9415 + 0.6463 x\)
如果只把這兩個數字寫在報告上,讀者會以為「斜率就是 0.6463,這麼精確」。但我們都知道這是從 928 個家庭抽出來的估計值——如果重新抽 928 個家庭,斜率會不會很不一樣?
這就是統計上「估計值(estimate)」與「估計值的精度(standard error)」的分工:
- 估計值:點估計,回答「大概是多少」。
- 標準誤:估計值本身的變異程度,回答「這個數字有多可靠」。
沒有標準誤的估計值,就像只報身高不報體重誤差的體檢報告。
歷史:這套工具是怎麼來的#
- 1908 年,William Sealy Gosset(以筆名「Student」發表,因為他任職於愛爾蘭的都柏林 Guinness 啤酒廠,不允許員工發表論文)提出了 t 分配,用來處理小樣本下平均數與標準差的問題。他面對的正是「釀造原料含水量」這種只有十幾筆資料的困境。
- 1920 年代,R. A. Fisher 把「最小平方法」和「過度決定(overdetermined system)」的想法結合起來:一組方程、未知數比方程少時沒有解,多於方程時用最小平方找「最接近的解」。Fisher 同時引入了變異數分析(把總變異拆解成來源)與 F 分布。
- 1930 年代,Fisher 與 Yates、以及後來 Harold Hotelling、Jerzy Neyman 與 Egon Pearson,把這些工具整理成今天的推論統計學架構:估計量、標準誤、檢定、信賴區間。
換句話說,「係數 + 標準誤 + t 檢定」這三件套是同一個時代的產物,它們回答的是同一個問題的不同面向:這個係數可能是多少?它有多不確定?它跟 0 有差別嗎?
理論:從殘差到標準誤#
殘差變異數 \(s^2\)#
擬合之後,每個資料點都留下一個殘差 \(e_i = y_i - \hat{y}_i\) 。如果模型對了,這些殘差應該是「隨機的、不含系統性的」,它們的大小代表資料本身的噪音程度。我們用殘差平方和估計這個噪音:
\(s^2 = \hat{\sigma}^2 = \frac{\sum e_i^2}{n - 2}\)
為什麼除以 \(n-2\) 而不是 \(n\) ?因為自由度:估計 \(b_0\) 與 \(b_1\) 兩個參數之後,資料只剩下 \(n-2\) 個獨立的自由度。分母用 \(n\) 會系統性低估變異數(這與第 6 章「用樣本變異數估計母體變異數」是同一件事)。
\(s = \sqrt{s^2}\) 稱為殘差標準差(residual standard error),它的單位和 \(y\) 一樣,所以最好解釋。
斜率的標準誤#
簡單迴歸中,斜率估計值 \(b_1\) 的標準誤是
\(\mathrm{SE}(b_1) = s \sqrt{\frac{1}{S_{xx}}} = \frac{s}{\sqrt{\sum (x_i - \bar{x})^2}}\)
這個式子告訴我們兩件事:
- ** \(x\) 的離散程度越大,斜率估得越準。** 因為 \(S_{xx}\) 在分母, \(x\) 攤得越開,斜率就越容易被「看清楚」。
- 樣本數越多, \(S_{xx}\) 越大,斜率越準。 這是「資料越多越好」的第一個量化理由。
截距的標準誤#
\(\mathrm{SE}(b_0) = s \sqrt{\frac{1}{n} + \frac{\bar{x}^2}{S_{xx}}}\)
注意截距的標準誤比斜率大得多(當 \(\bar{x} \ne 0\) 時)。原因很直覺:截距是直線在 \(x=0\) 處的高度,必須靠「整條線往回推」來確定,而這正是最不穩定的部分。上一節 Galton 的 \(\mathrm{SE}(b_0) = 2.81\) 吋 vs \(\mathrm{SE}(b_1) = 0.041\) ,就是這個現象。
t 統計量與 p 值#
\(t = \frac{b_1 - 0}{\mathrm{SE}(b_1)}\)
在「誤差為常態、變異數固定」的假設下,這個 t 統計量服從自由度 \(n-2\) 的 t 分配(見 5.4 節)。所以 p 值就是
\(p = P\left(|T_{n-2}| \ge |t|\right)\)
而 95% 信賴區間(概念,完整公式在 9.5)是
\(b_1 \pm t_{0.975, n-2} \cdot \mathrm{SE}(b_1)\)
三件事是同一件事的三種說法:檢定(係數是否為 0)、信賴區間(係數可能落在哪裡)、p 值(在「係數為 0」的假設下,會看到這麼極端的資料的機率)。
動手:讀懂 summary(lm)#
資料用 R 內建的 women(15 位女性的體重與身高),小到能手算。
import rstatistics as r
HEIGHT = [58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0,
68.0, 69.0, 70.0, 71.0, 72.0]
WEIGHT = [115.0, 117.0, 120.0, 123.0, 126.0, 129.0, 132.0, 135.0, 139.0, 142.0,
146.0, 150.0, 154.0, 159.0, 164.0]
m = r.lm(WEIGHT, [HEIGHT], names=["height"])
sm = m.summary()
print(sm)
# ---------- 手算:殘差變異數、標準誤、t 值、p 值 ----------
n = len(HEIGHT)
res = [yi - fi for yi, fi in zip(WEIGHT, m.fitted_values)]
rss = sum(e * e for e in res)
s2 = rss / (n - 2)
sd_res = s2 ** 0.5
xb = r.mean(HEIGHT)
yb = r.mean(WEIGHT)
sxx = sum((xi - xb) ** 2 for xi in HEIGHT)
se_b = sd_res / sxx ** 0.5
se_a = sd_res * (1.0 / n + xb * xb / sxx) ** 0.5
t_b = m.coefficients[1] / se_b
p_b = 2 * r.pt(abs(t_b), n - 2, lower_tail=False)
print("手算對照:")
print(" n = %d, 自由度 = %d" % (n, n - 2))
print(" RSS = %.4f" % rss)
print(" s² = RSS/(n-2) = %.4f, s = %.4f (summary: %.4f)" % (s2, sd_res, sm.sigma))
print(" SE(b) = s/sqrt(Sxx) = %.5f (summary: %.5f)" % (se_b, sm.std_errors[1]))
print(" SE(a) = s*sqrt(1/n+xbar^2/Sxx) = %.5f (summary: %.5f)" % (se_a, sm.std_errors[0]))
print(" t(b) = %.4f (summary: %.4f)" % (t_b, sm.t_values[1]))
print(" p(b) = %.4g (summary: %.4g)" % (p_b, sm.p_values[1]))
# ---------- R² 與 cor 的關係 ----------
rho = r.cor(HEIGHT, WEIGHT)
print()
print("R² = %.6f" % sm.r_squared)
print("cor(x, y) = %.6f, cor² = %.6f" % (rho, rho * rho))
print("R² == cor² ? %s" % (abs(sm.r_squared - rho * rho) < 1e-12))
# ---------- 係數的信賴區間(概念,完整版在 9.5)----------
tcrit = r.qt(0.975, n - 2)
b = m.coefficients[1]
a = m.coefficients[0]
print()
print("95%% CI for 斜率 b: [%.4f, %.4f]" % (b - tcrit * se_b, b + tcrit * se_b))
print("95%% CI for 截距 a: [%.4f, %.4f]" % (a - tcrit * se_a, a + tcrit * se_a))
輸出:
Call:
lm(formula = y ~ height)
Residuals:
Min 1Q Median 3Q Max
-1.7333 -1.1333 -0.3833 0.7417 3.1167
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -87.51667 5.93694 -14.74 1.71e-09 ***
height 3.45000 0.09114 37.85 1.09e-14 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1.525 on 13 degrees of freedom
Multiple R-squared: 0.991, Adjusted R-squared: 0.9903
F-statistic: 1433 on 1 and 13 DF, p-value: 1.091e-14
手算對照:
n = 15, 自由度 = 13
RSS = 30.2333
s² = RSS/(n-2) = 2.3256, s = 1.5250 (summary: 1.5250)
SE(b) = s/sqrt(Sxx) = 0.09114 (summary: 0.09114)
SE(a) = s*sqrt(1/n+xbar^2/Sxx) = 5.93694 (summary: 5.93694)
t(b) = 37.8553 (summary: 37.8553)
p(b) = 1.091e-14 (summary: 1.091e-14)
R² = 0.991010
cor(x, y) = 0.995495, cor² = 0.991010
R² == cor² ? True
95% CI for 斜率 b: [3.2531, 3.6469]
95% CI for 截距 a: [-100.3427, -74.6907]
逐行解讀輸出的每一個欄位#
第一段 Residuals: — 殘差的五數摘要。Min -1.7333、Max 3.1167 是最小的與最大的殘差(本例資料幾乎是一條直線,所以殘差很小);Median -0.3833 表示殘差的中位數稍微偏負,也就是資料略微呈現曲率(下一節的診斷主題)。
Coefficients: 表格 — 整張表的重點:
| 欄位 | 意義 | 本例(height 那一列) |
|---|---|---|
Estimate | 係數的點估計 | 3.45:身高每多 1 公分,體重平均多 3.45 公斤 |
Std. Error | 係數的標準誤 | 0.09114:斜率的估計誤差約 ±0.09 |
t value | 檢定統計量 \(t = \hat\beta / \mathrm{SE}\) | 37.85 |
Pr(>|t|) | 雙尾 p 值 | 1.09e-14:極不可能是巧合 |
*** | 顯著性標記 | p < 0.001 |
Residual standard error: 1.525 on 13 degrees of freedom — 這就是 \(s = \sqrt{\mathrm{RSS}/(n-2)}\) 。它的意思是「扣掉模型能解釋的部分之後,資料還剩下約 1.5 公斤的典型誤差」。
Multiple R-squared: 0.991, Adjusted R-squared: 0.9903 — 模型解釋了 99.1% 的變異。調整 \(R^2\) ** 則把「用掉一個參數」的成本扣掉:在多元迴歸中多加一個變數幾乎一定會讓 \(R^2\) 變大(哪怕它一點用處都沒有),所以比較不同變數個數**的模型時,要看調整過的版本。
F-statistic: 1433 on 1 and 13 DF — 這是「整個模型是否比『只有截距』的模型好」的檢定。在只有一個預測變數時, \(F = t^2\) (本例 \(37.85^2 \approx 1433\) ),所以 F 檢定和 t 檢定是同一件事的兩種寫法;多元迴歸時 F 檢定才有獨立意義。
\(R^2 = r^2\) 這個好用的關係#
在簡單(單預測變數)迴歸中,有一個可以直接背下來的等式:
\(R^2 = r^2\)
其中 \(r = \mathrm{cor}(x, y)\) 是皮耳森相關係數。程式也驗證了這件事:
R² = 0.991010
cor(x, y) = 0.995495, cor² = 0.991010
R² == cor² ? True
為什麼會這樣? 因為在單元迴歸中, \(R^2 = 1 - \frac{\mathrm{RSS}}{\mathrm{TSS}}\) ,而 \(\mathrm{RSS} = \mathrm{TSS}(1-r^2)\) ,所以 \(R^2 = r^2\) 。這也解釋了為什麼 \(R^2\) 有個上限 1:相關係數的絕對值不超過 1。
這條等式有個實際用途:當你只想要「線性關係的強度」而不關心截距時,相關係數就是 \(R^2\) 的平方根,而且相關係數可以在任何一對變數之間計算,不一定要做迴歸。
信賴區間:估計值 ± 一個Margin#
看最後兩行:
95% CI for 斜率 b: [3.2531, 3.6469]
95% CI for 截距 a: [-100.3427, -74.6907]
斜率的區間不包含 0,所以「身高對體重有影響」的檢定會被拒絕;截距的區間則離 0 非常遠(因為身高不可能是 0),這個檢定在實務上毫無意義——這正是為什麼截距的 p 值通常沒有人看。
與 R 對照#
# 係數的估計與標準誤:R 對照(資料:women,身高體重)
data(women)
fit <- lm(weight ~ height, data = women)
sm <- summary(fit)
cat("=== summary(lm) ===\n")
print(sm)
cat("\n=== 手算:殘差變異數與標準誤 ===\n")
rss <- sum(residuals(fit)^2)
s2 <- rss / (nrow(women) - 2)
cat(sprintf("RSS = %.4f, s2 = %.4f, s = %.4f\n", rss, s2, sqrt(s2)))
xb <- mean(women$height); sxx <- sum((women$height - xb)^2)
cat(sprintf("SE(b) = %.5f, SE(a) = %.5f\n",
sqrt(s2) / sqrt(sxx), sqrt(s2) * sqrt(1 / nrow(women) + xb^2 / sxx)))
cat("\n=== 係數的信賴區間 confint() ===\n")
print(confint(fit))
cat("\n=== R squared 與 cor ===\n")
cat(sprintf("R-squared = %.6f, cor = %.6f, cor^2 = %.6f\n",
sm$r.squared, cor(women$height, women$weight),
cor(women$height, women$weight)^2))
cat("\n=== 變異數共變異矩陣 vcov() ===\n")
print(vcov(fit))
輸出:
=== summary(lm) ===
Call:
lm(formula = weight ~ height, data = women)
Residuals:
Min 1Q Median 3Q Max
-1.7333 -1.1333 -0.3833 0.7417 3.1167
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -87.51667 5.93694 -14.74 1.71e-09 ***
height 3.45000 0.09114 37.85 1.09e-14 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1.525 on 13 degrees of freedom
Multiple R-squared: 0.991, Adjusted R-squared: 0.9903
F-statistic: 1433 on 1 and 13 DF, p-value: 1.091e-14
=== 手算:殘差變異數與標準誤 ===
RSS = 30.2333, s2 = 2.3256, s = 1.5250
SE(b) = 0.09114, SE(a) = 5.93694
=== 係數的信賴區間 confint() ===
2.5 % 97.5 %
(Intercept) -100.342655 -74.690679
height 3.253112 3.646888
=== R squared 與 cor ===
R-squared = 0.991010, cor = 0.995495, cor^2 = 0.991010
=== 變異數共變異矩陣 vcov() ===
(Intercept) height
(Intercept) 35.247305 -0.539880952
height -0.539881 0.008305861
vcov() 印出的是係數的變異數共變異矩陣。它的對角線就是標準誤的平方(0.008305861 = 0.09114²),非對角線元素則是斜率與截距的共變異:這個例子裡是負的(-0.54),意思是「 \(x\) 的抽樣誤差讓斜率偏大時,截距會偏小」。多元迴歸中,這個矩陣的結構會讓係數的解讀變複雜(9.5 會再遇到)。
小結#
- 標準誤是估計值的精度:沒有標準誤的係數是無法評估的。
- \(s^2 = \mathrm{RSS}/(n-2)\) 、 \(s = \sqrt{s^2}\) 是殘差變異數與殘差標準差;除以 \(n-2\) 是因為估了兩個參數。
- \(\mathrm{SE}(b_1) = s/\sqrt{S_{xx}}\) ; \(x\) 越分散、樣本越大,斜率估得越準。
summary(lm)的每一欄都有意義:Estimate(點估計)、Std. Error(精度)、t value(係數是幾個標準誤 away from 0)、Pr(>|t|)(巧合的機率)。- 單元迴歸中 \(R^2 = r^2\) ;報告模型時要一併給出 \(R^2\) 與殘差標準差 \(s\) 。
- 信賴區間、檢定、p 值是同一件事的三種說法。
練習#
- 用
r.lm擬合weight ~ height但設intercept=False,比較係數與summary的輸出( \(t value\) 那一列會變成什麼?為什麼?)。提示:intercept=False時正規方程少了一條, \(t\) 檢定的自由度也跟著變。 - 手算 \(\mathrm{SE}(b_1)\) 時,把 \(s\) 換成 \(\sqrt{\mathrm{RSS}/n}\) (少除一個自由度),看看 \(t\) 值變大多少。這解釋了為什麼自由度要用 \(n-2\) 嗎?
- 把
women的資料點減半(例如只留身高 <= 65 的),重做擬合。 \(R^2\) 變大還是變小? \(\mathrm{SE}(b_1)\) 變大還是變小?兩者為什麼可能往不同方向走? - 用
r.cor算出women的相關係數,再用 \(R^2 = r^2\) 反推 \(R^2\) ,和summary印出的Multiple R-squared比較(應該差在浮點誤差內)。 - 想一想:為什麼截距的 p 值在實務上通常沒有人關心?在什麼情況下截距反而是有意義的(例如沒有原點的物理量、或做「校正」用的模型)?