COM6005 Statistical Modeling · Module 4
Linear Regression
COM6005 · Module 4 · Source: L4_Linear_Regression_V2.pdf (46 slides)
Contents · 11 sections
🎯 本講重點 (Learning outcomes)
- Simple linear regression :適用條件、dependent / independent variable 嘅叫法。
- OLS:最小化 ;用
smf.ols('fuel~dlic', data).fit()、讀model.summary()、model.params、model.predict()。 - Matrix 解法:,識用 3 點例子手計。
- 嘅意思;。
- Regression 幾時 fail:non-linearity、residuals 唔 i.i.d. normal;四幅 diagnostic plots 點讀。
- Multiple linear regression、coefficient interpretation、train/test split、Bias / RMSE、in-sample vs out-of-sample、AIC / BIC。
- (Optional)interval prediction、ANOVA F-test、coefficient t-test 同 standard error 公式。
⭐ 考試必溫 Top-5
- OLS 目標函數同 ;3 點 (1,2), (2,3), (3,5) → 。
- 讀 summary:;slope 解讀(X 加 1 單位,Y 平均變幾多)、p-value、95% CI、。
- ,; = perfect fit。
- Residual diagnostics:Residual vs Fitted(linearity、constant variance)、vs Index(independence)、Lag plot(autocorrelation)、QQ-plot(normality)。
- Big model in-sample RMSE 一定較細,但 out-of-sample 唔一定;用 test data RMSE / AIC / BIC(越低越好)揀 model。
1. Regression problem:Simple linear regression
Slide 1:適合以下問題——
- 只有 個 predictor;
- X 同 Y 都係 numerical and continuous;
- X、Y 嘅 scatter plot 理想上似一條直線。
| Y | X |
|---|---|
| Dependent variable / response / predicted target (statsmodels 叫 endogenous variable, endog) | Independent variable / predictor (statsmodels 叫 exogenous variable, exog) |
Slides 2–5 例子:美國 48 個州嘅 fuel consumption vs number of driving licenses(dlic;Module 1 slide 8 叫 %Driving License)。Slide 3 嘅 scatter plot 顯示 dlic 越高、fuel 越高,大致線性。
- Problem:根據 X 同 Y 嘅數學關係,由 X 預測 Y。
- Linear model:(a = intercept,b = slope)。
- Regression:由 training data 估計 a、b 嘅統計方法 → 。新數據只知 X → 預測 。
- Slide 5 嘅 prediction problem:如果新政策將 license 數目減至 50%,執行後 fuel consumption 會係幾多?
Module 1 講過:numeric prediction → Linear regression;classification → Logistic regression。COM6004 Classification 嘅 training / test set、overfitting 概念同本講 §8 完全一致。
2. Problem Solving with Python:OLS
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import seaborn as sns
fueldata = pd.read_csv("fueldata.csv")
plt.scatter(fueldata['dlic'], fueldata['fuel']) # 先睇 scatter plot 係咪線性
plt.show()
Slide 7:Simple linear regression 搵 、 令 sum of squared errors 最細——OLS (Ordinary Least Squares):
model = smf.ols('fuel~dlic', data=fueldata).fit() # 'Y~X':左邊 dependent,右邊 independent
print(model.summary())
print(model.params) # 睇 a-hat 同 b-hat
讀做 “a-hat”,代表由數據估計出嚟嘅值。
(由 、 推出,即 Module 1 提過嘅 calculus:derivatives → minimum。)
2.1 讀 OLS Regression Results(slide 8)
| 項目 | 值 | 意思 |
|---|---|---|
| Dep. Variable | fuel | Y |
| No. Observations | 48 | n |
| Df Residuals / Df Model | 46 / 1 | / |
| R-squared / Adj. R-squared | 0.489 / 0.477 | dlic 解釋到 fuel 約 48.9% 嘅 variation |
| F-statistic / Prob (F) | 43.94 / 3.29e-08 | 整個 model 顯著(ANOVA F-test) |
| AIC / BIC | 559.9 / 563.6 | model selection 用,越低越好 |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | −227.3091 | 121.862 | −1.865 | 0.069 | −472.604 | 17.986 |
| dlic | 14.0984 | 2.127 | 6.629 | 0.000 | 9.817 | 18.380 |
- Slope 14.0984:dlic 每增加 1 單位(1 個百分點),預期 fuel consumption 平均增加約 14.10 單位。
- Intercept −227.31: 時嘅預測 fuel——負數冇實際意義,因為 遠超出數據範圍(extrapolation),intercept 只係令條線位置正確。
- :14.0984 / 2.127 = 6.629;p-value ≈ 0.000 < 0.05 → reject → dlic 對 fuel 有顯著線性關係。Intercept → 喺 5% 唔顯著。
- 95% CI of slope:[9.817, 18.380],唔包 0 → 同 t-test 結論一致(Module 3:CI 唔包 null value ⇔ reject )。手計:14.0984 ± 2.013 × 2.127 = 14.0984 ± 4.282()。
- Simple regression 入面 : ✔。
2.2 畫 fitted line 同 prediction(slides 9–10)
plt.scatter(fueldata['dlic'], fueldata['fuel'])
predicted_values = model.predict() # training data 嘅 fitted values
plt.plot(fueldata['dlic'], predicted_values)
plt.show()
newdata = pd.DataFrame({'dlic': [50]}) # test dataset:column 名要同 formula 一樣
prediction = model.predict(newdata) # 477.61
newdata = pd.DataFrame({'dlic': [50, 55, 60]})
predictions = model.predict(newdata) # 477.61, 548.10, 618.59
:。
:。
3. Step-by-step numerical example:Matrix OLS(slides 11–19)
3 個數據點:(1, 2)、(2, 3)、(3, 5)。Slide 12 嘅圖顯示 OLS line 穿過三點附近。
3.1 Derivation(slides 13–16)
Objective function(slide 14):選 令 Sum of Squared Residuals 最細;column vector 嘅平方和 = inner product :
(因為 係 scalar,等於自己嘅 transpose ,兩個中間項可以合併。)
Matrix differentiation & first-order conditions(slide 15):兩條 matrix calculus rules——Linear rule ;Quadratic rule(A symmetric):
Normal Equations(slide 16):
前提:design matrix X 有 full column rank(冇 perfect multicollinearity),咁 先可逆。
3.2 手計(slides 17–18)
- Define matrices: ,(第一欄全 1 = intercept;第二欄 = independent variable)
- Transpose:
- :
- Invert(2×2:):determinant = 3×14 − 6×6 = 6;
- :
- Solve:
Intercept ,Slope → 。
;; → , ✔。
3.3 Python code(slide 19)
import numpy as np
import statsmodels.api as sm
x_data = np.array([1, 2, 3])
Y = np.array([2, 3, 5]).reshape(-1, 1)
X = np.column_stack((np.ones_like(x_data), x_data)) # design matrix:加一欄 1
XT = X.T
XTX = XT @ X
XTX_inv = np.linalg.inv(XTX)
XTY = XT @ Y
beta_hat = XTX_inv @ XTY
print(f"Intercept (Beta 0): {beta_hat[0][0]:.3f}") # 0.333
print(f"Slope (Beta 1): {beta_hat[1][0]:.3f}") # 1.500
# 同 library 比較:endog = dependent,exog = independent(要自己加 constant 欄)
model = sm.OLS(endog=Y, exog=X).fit()
print(model.summary())
sm.OLS(大寫,array API)唔會自動加 intercept,要自己加一欄 1(或 sm.add_constant(x));smf.ols(細寫,formula API)會自動加 Intercept。
4. R squared(slide 20)
係 0 至 1 之間嘅數,描述 Y 嘅 variation 有幾多比例被 model 解釋。
Explained / Regression SS (ESS):。 代表 perfect fit()。
Slide 20 原文寫 “R squared: 1 means perfect fit. It implies that ESS = 0”——正確應該係 RSS(Residual SS)= 0(所有點都喺線上),。考試要寫 。
- ;
- Fitted:;residuals = 0.167, −0.333, 0.167
- → model 解釋 96.4% variation。
:dlic 只解釋到 fuel 大約一半嘅差異,其餘可能嚟自 income、tax 等其他因素 → 引出 multiple regression。
5. When does regression fail?(slides 21–22)
- Relationship does not look linear。
- Error terms / residuals are not i.i.d. normal(independent and identically distributed):
- Independent:check serial correlation → 改善:加 time series model component。
- Identically distributed:Var(error) 應該 constant,唔應該跟 fitted values 或 time/index 改變 → 否則係 Heteroskedasticity(non-constant variance)→ time-varying variance model (GARCH)。
- Normal:residuals 應該 bell-shaped:QQ-plot(intuitive)同 Anderson-Darling test(rigorous,not discussed)→ 否則其他 model 可能更好。
5.1 Visual diagnostics check(slides 23–25)
resid = model.resid
fitted = model.fittedvalues
n = len(resid)
fig, axs = plt.subplots(2, 2, figsize=(10, 10))
axs[0, 0].scatter(fitted, resid); axs[0, 0].axhline(0, color='red', lw=2) # e(i) vs fit(i)
axs[0, 1].scatter(np.arange(n), resid); axs[0, 1].axhline(0, color='red', lw=2) # e(i) vs i
axs[1, 0].scatter(resid[:-1], resid[1:]); axs[1, 0].axhline(0, color='red', lw=2) # e(i) vs e(i-1)
sm.qqplot(resid, ax=axs[1, 1]); axs[1, 1].set_title('Normal Q-Q')
plt.show()
plt.hist(resid, bins=20); plt.show() # residual histogram
| Plot | Check 咩 | 理想 | 問題 pattern |
|---|---|---|---|
| Top-left:Residuals vs Fitted | Linearity + homoscedasticity | 圍繞 0 嘅 random、均勻點雲 | 曲線 / U 形 → non-linearity;漏斗 / cone 形 → heteroscedasticity |
| Top-right:Residuals vs Order/Index | Independence(時間/次序) | 圍繞 0 隨機散佈 | Trends、cycles、clusters → 次序影響 error(time series) |
| Bottom-left:Lag plot vs | First-order autocorrelation(lag-1) | 冇結構、冇方向 | 正斜線 → positive autocorrelation;負斜線 → negative |
| Bottom-right:Q-Q plot | Normality of residuals | 貼住對角直線 | 兩端偏離 / S 形 → skewness、heavy tails、outliers |
| Residual histogram (20 bins) | Normality、symmetry、skewness | 以 0 為中心嘅鐘形 | 偏斜、多峰 |
Slide 24 係 fuel model 嘅四幅 diagnostic plots:residual vs predicted fuel、vs index、vs lagged error 大致都係圍繞 0 嘅散點,冇明顯 pattern;QQ-plot 大致沿直線,但右上尾有幾個大 residual(約 180、250)偏離 → 可能有 outliers/少少 right skew。(Summary 嘅 Skew = 0.747、Prob(Omnibus) = 0.049 亦提示 residual 唔算完全 normal;Durbin-Watson = 1.645 接近 2,autocorrelation 唔嚴重。)
Module 2c:residual normal + mean 0 → random,model 冇得再改善 mean prediction;QQ-plot 用法一樣。
6. Multiple linear regression(slides 26–29)
Applicable if:
- 所有 X 同 Y 都係 numerical and continuous;
- p 相對 n 細( can be very problematic)。
Lecture 4 第二部分內容:basic ideas of regression for 、doing prediction using Python、selecting important predictors。
例子(slide 29):What affects the saving rate?savings.csv:50 個國家 1960–1970 數據(Belsley, Kuh & Welsch 1980, Regression Diagnostics)。
| Variable | 意思 |
|---|---|
| personal saving ÷ disposable income | |
| % population under age 15 | |
| % population over age 75 | |
| per capita disposable income (US$) | |
| % growth rate of dpi |
7. Multiple regression with Python(slides 30–34)
要識:點寫 regression formula、計 coefficients、指定 training / test data。
model = smf.ols('sr~pop75+dpi', data=savings).fit() # 多個 X 用 + 連接
print(model.summary()) # β-hat 喺 "coef" 欄
Slide 32 嘅 output:
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 7.0566 | 1.290 | 5.468 | 0.000 | 4.461 | 9.653 |
| pop75 | 1.3050 | 0.778 | 1.678 | 0.100 | −0.259 | 2.869 |
| dpi | −0.0003 | 0.001 | −0.337 | 0.738 | −0.002 | 0.002 |
、Adj. 、、Prob (F) = 0.0791、、Df Residuals = 47、Df Model = 2、AIC = 291.5、BIC = 297.2。
- pop75 = 1.3050:在 dpi 不變(holding other variables constant)下,75 歲以上人口比例每增加 1 個百分點,saving rate 平均增加約 1.305 個百分點。 → 喺 5% 水平唔顯著;95% CI [−0.259, 2.869] 包 0,結論一致。
- dpi = −0.0003:pop75 不變下,人均可支配收入每增加 US$1,saving rate 平均跌 0.0003(每增加 $1000 跌 0.3); → 完全唔顯著。
- Overall F-test: → 喺 5% 水平唔能夠 reject “”。
- :只解釋 10.2% variation,model 解釋力弱。
Multiple regression 嘅 coefficient 一定要加「holding other variables constant」;同 simple regression 嘅 slope 唔同。Coefficient 大細亦受單位影響(dpi 係美元,所以 coef 好細),唔代表重要性。
7.1 Matrix notation(slide 33)
Gradient = ,設 = 0:
第一欄全 1 係「for intercept」。Simple regression 只係 p = 1 嘅特例。
7.2 Prediction for new data(slide 34)
newdata = pd.DataFrame({'pop15': [30], 'pop75': [3], 'dpi': [2000], 'ddpi': [5]})
newdata = pd.DataFrame({'pop15': [30, 25], 'pop75': [3, 4],
'dpi': [2000, 2000], 'ddpi': [5, 5]})
predictions = model.get_prediction(newdata) # 有 summary_frame,可出 interval
predictions = model.predict(newdata) # point prediction
例:用 slide 32 model,、:(用四捨五入後嘅 coef;多出嚟嘅 columns 如 pop15、ddpi 會被 model 忽略)。
8. Measuring prediction ability(slides 35–39)
- 將 full data split 做 training data 同 testing data,例如 70% vs 30%。
- 用 training data 做
ols。 - 假裝唔知 test data 嘅 Y,用
predict。 - 比較 actual 同 predicted:用 bias 同 mean squared error 量度 prediction accuracy。
- 小心分清 in-sample prediction(training data)同 out-of-sample prediction(test data)。
- Training data 係 model 見過嘅,用嚟訓練 model、得到 coefficients / parameters。
- Model 嘅目的係應用喺 unseen data——只有 test data 係 unseen。
savings_train = savings.iloc[:35] # 頭 35 個國家做 training(70%)
savings_test = savings.iloc[35:50] # 其餘 15 個做 test(30%)
model = smf.ols('sr~pop15+ddpi', data=savings_train).fit()
from sklearn.metrics import mean_squared_error
pre_val = model.predict(savings_test)
act_val = savings_test['sr']
bias = np.mean(pre_val - act_val) # 正 = 系統性高估;負 = 系統性低估
rmse = np.sqrt(mean_squared_error(act_val, pre_val))
print("Bias:", bias)
print("RMSE:", rmse) # 亦可以用 MSE
Actual = 10, 12, 8;Predicted = 11, 11, 10。Errors (pred − act) = 1, −1, 2。(平均高估);;。
8.1 Big model vs small model(slides 36–39)
- In-sample RMSE:YES(大 model 一定唔會差過細 model)——但冇用,只係 fit 咗見過嘅 data。
- Out-of-sample RMSE:NO——大 model 可能 overfit,喺 unseen data 表現更差。
- 點決定?AIC / BIC → Lower is better(佢哋會懲罰多餘 parameters)。
# Small model vs Big model(slide 39)
small_model = smf.ols('sr~pop15+ddpi', data=savings_train).fit()
big_model = smf.ols('sr~pop15+pop75+dpi+ddpi', data=savings_train).fit()
for name, m in [("small", small_model), ("big", big_model)]:
in_rmse = np.sqrt(mean_squared_error(savings_train['sr'], m.predict(savings_train)))
out_rmse = np.sqrt(mean_squared_error(savings_test['sr'], m.predict(savings_test)))
print(f"{name}: AIC={m.aic:.1f}, BIC={m.bic:.1f}, In-RMSE={in_rmse:.4f}, Out-RMSE={out_rmse:.4f}")
用 training data 嘅 / RMSE 去揀 model——加任何 variable(就算係 random noise) 都只會升唔會跌。要睇 out-of-sample RMSE、Adj. 、AIC / BIC。Slide 39 冇顯示實際輸出數字,重點係概念:small model 嘅 out-of-sample RMSE 可以更低。
COM6004 Classification:training error vs test (generalization) error、model overfitting、holdout method——同一個概念。COM6001 Week 1 講過嘅 train/test split 同 Module 2a 嘅 np.random.choice(range(0,100), 70, replace=False) 都係做呢件事(slide 37 用 iloc[:35] 係按次序切,唔係 random)。
9. Optional topics(slides 40–46)
9.1 Interval prediction(slide 41)
newdata = pd.DataFrame({'dlic': [50]}) # simple regression 例子
predictions = model.get_prediction(newdata)
prediction_summary = predictions.summary_frame(alpha=0.05)
print(prediction_summary)
# mean_ci_lower/upper:population mean(平均 Y)嘅 CI
# obs_ci_lower/upper :future prediction / new data point 嘅 prediction interval(更闊)
CI of mean:「 嘅州,平均 fuel 喺邊個範圍」;Prediction interval:「某一個 嘅州 fuel 喺邊」——要加埋個別 error 嘅 variance,所以更闊。
9.2 Is X helpful to predict Y?(slides 42–43)
| ANOVA (F-statistic) | T-tests | |
|---|---|---|
| 所有 regression coefficients(intercept 除外)= 0: | :第 j 個 predictor 對 Y 冇 effect(given other variables) | |
| 至少一個 | : 同 Y 有顯著線性關係 | |
| 測試咩 | 整個 model 係咪比 intercept-only mean model 解釋顯著更多 variance | 個別 predictor 係咪顯著 |
| Source of variation | Sum of squares | Degree of freedom | Mean square | F-ratio |
|---|---|---|---|---|
| Regression | SSR | 1 | ||
| Error | SSE | |||
| Total | SST |
F-test:比較 F-ratio 同 (記法 )。F-ratio 大過 critical value → reject 。
Slide 44 係 F-table():column = Numerator DF(1–10),row = Denominator DF(1–50)。例如 、、、。
,;查表 。43.94 > 4.052 → reject ,dlic 有助預測 fuel(同 Prob(F) = 3.29e-08 一致)。
Savings model:,;。2.680 < 3.195 → do not reject(同 Prob(F) = 0.0791 > 0.05 一致)。
9.3 Is the coefficient significantly different from zero?(slides 45–46)
統計估計同 prediction 通常會附上 standard error 量度準確度/不確定性。
Slide 46 係 t-table(同 Module 3a 一樣,row 、column )。
- ; →
- 5.196
- (,)→ 5.196 < 12.706 → 唔能 reject 。只有 3 點,,證據唔夠。
- ANOVA 驗證:, → (); → 同樣唔 reject。
;。
- →
- ; →
- ;
- 10.31; → reject ,廣告開支顯著影響 sales。
- 95% CI of slope:0.8444 ± 3.182 × 0.0819 = (0.584, 1.105)。
Regression coefficient t-test 嘅 (simple regression;multiple regression 係 ),唔係 。two-sided 用 97.5% quantile。
t-test of coefficient 就係 Module 3a t-test 嘅延伸(estimate ÷ S.E. 對比 t critical value);coefficient CI 就係 Module 3 嘅「CI 唔包 0 ⇔ reject 」。ANOVA F 用嘅 between / within variation 概念同 Module 3a slide 32 一樣。
自我測驗 Self-test
Q1. 用 matrix 方法計 (0, 1), (1, 3), (2, 2) 嘅 OLS line。
,det = 15 − 9 = 6,;; → 。
Q2. 繼續 Q1:計 TSS、RSS、。
;。Fitted = 1.5, 2, 2.5;residuals = −0.5, 1, −0.5;。。
Q3. 某 output:coef of X = −2.35,std err = 0.80,(simple regression)。做 two-sided t-test()並解讀 coefficient。
;,。|−2.94| > 2.069 → reject 。解讀:X 每增加 1 單位,Y 平均減少 2.35 單位。
Q4. Fuel model: 時嘅預測?如果政策令 dlic 由 60 跌到 30,預測 fuel 變化?有咩問題?
:−227.3091 + 14.0984 × 65 = 689.09。60 → 30:變化 = 14.0984 × (−30) = −422.95。問題: 可能遠超出 training data 範圍(extrapolation),linear 關係未必成立;而且 regression 只顯示 association,唔一定係 causation。
Q5. Residual vs fitted plot 呈漏斗形(fitted 越大,residual 越散),代表咩問題?違反咩 assumption?
Heteroskedasticity(non-constant variance),違反 identically distributed(constant Var(error))assumption。可考慮 transformation(例如 log Y)或 GARCH 類 time-varying variance model。
Q6. Simple regression,,,。完成 ANOVA table 並做 F-test()。 係幾多?
df:Regression 1、Error 20、Total 21。;;。 → 12 > 4.351 → reject 。,。
Q7. 點解 big model 嘅 in-sample RMSE 一定 ≤ small model,但 out-of-sample 唔一定?點樣揀?
OLS 喺 training data 上最小化 SS;多咗 parameters 最差都可以將佢哋設 0 得返 small model,所以 in-sample error 唔會更大。但多餘 parameters 會 fit 埋 noise(overfitting),喺 unseen test data 表現可能更差。揀 model:比較 out-of-sample RMSE,或 AIC / BIC(越低越好)。
Q8. 寫 Python:用 savings 頭 35 行 fit sr ~ pop15 + pop75,計 test set 嘅 bias 同 RMSE。
m = smf.ols('sr~pop15+pop75', data=savings.iloc[:35]).fit(); te = savings.iloc[35:50]; pred = m.predict(te); bias = np.mean(pred - te['sr']); rmse = np.sqrt(mean_squared_error(te['sr'], pred))
Q9. Savings output 中 pop75 coef = 1.305、。用完整句子解讀,並講喺 嘅結論。
喺 dpi 不變下,75 歲以上人口比例每增加 1 個百分點,saving rate 平均增加 1.305 個百分點。: → 唔顯著;: 啱啱喺邊界(p 唔細過 0.10),嚴格嚟講都唔 reject。
一頁總結 Cheat sheet
- Model:;Y = dependent / response / endogenous;X = independent / predictor / exogenous。
- OLS:min ;,;matrix:(X 第一欄全 1)。
- 3 點 (1,2),(2,3),(3,5):,det 6, → 。
- Python:
smf.ols('y~x1+x2', data).fit()、.summary()、.params、.predict(newdata)、.get_prediction().summary_frame(alpha=0.05);sm.OLS(endog, exog)要自己加 constant。 - Fuel:,,slope ,; → 477.61。
- Slope 解讀:X 加 1 單位,Y 平均變 (multiple:holding others constant);intercept 可能無實際意義(extrapolation)。
- ;;。
- Fail:non-linear;residuals 唔 independent(serial correlation)/唔 identical(heteroskedasticity → GARCH)/唔 normal(QQ-plot、Anderson-Darling)。
- Diagnostics:resid vs fitted(曲線 = non-linear,漏斗 = heteroscedastic);vs index(trend = dependence);lag plot(斜線 = autocorrelation);QQ(直線 = normal);histogram。
- Multiple regression:p 相對 n 細( 有問題)。
- Prediction ability:train/test(70/30);;;in-sample 大 model 必勝,out-of-sample 唔一定;AIC / BIC 越低越好。
- ANOVA:Regression df 1、Error df 、Total ; vs ;:所有 slopes = 0。
- ;;; vs 。