COM6005 Statistical Modeling · Module 6
Model Comparison / Feature Selection
COM6005 · Module 6 · Source: L6_Model_Comparison_L02_Complete.pdf (23 slides)
Contents · 8 sections
🎯 本講重點 (Learning outcomes)
- 明白 Big model is not necessarily good model:加 predictors 一定令 RSS 細咗,但唔代表 out-of-sample prediction 好。
- Method 1 — Penalty:用 Mallows' 、AIC、BIC 懲罰大 model;全部 lower is better。
- Method 2 — Cross Validation:Train-test split、K-fold CV、Leave-one-out (LOOCV),比較 prediction ability。
- Best subset selection:試晒 個 models;識用
ExhaustiveFeatureSelector。 - Forward / Backward selection:大 p 時嘅實用(但 sub-optimal)方法;識用
SequentialFeatureSelector同Pipeline。
⭐ 考試必溫 Top-5
- 點解 small RSS 唔保證 prediction 好:model 越大 RSS 越細(in-sample),但 prediction 係針對 unseen(out-of-sample)data。
- ;AIC ;BIC 。Lower is better, 包括 intercept。
- BIC penalty 最重 → 揀出嚟嘅 model 通常 predictors 較少(parsimonious)。
- K-fold CV:分 K 份,每份輪流做 test,平均 K 個 MSE;LOOCV = n-fold CV(500 個 data 要 fit 500 次,computationally expensive)。
- Best subset 有 個 models(p = 4 → 16;p = 20 → 1,048,576);Forward / Backward selection 較平但 唔保證搵到 best subset。
1. Big model is not necessarily good model(slides 1–3)
呢講用 multiple linear regression 做例子,講點樣喺「大 model」同「細 model」之間揀。Slide 1 列出成講嘅路線:
- Discouraging big model by penalty term(、AIC、BIC)
- 呢啲諗法用嚟做 variable selection(feature selection)
- Prediction ability vs cross validation
Module 4 講過 OLS 嘅「best result」係 minimize Residual sum of squares (RSS):
- The bigger is the model, the smaller is RSS.
- Small RSS does NOT guarantee a good prediction performance.
- WHY? Prediction 係對 out-of-sample data (unseen) 做嘅,而 RSS 係用 training data 本身計(in-sample)。
- Crucial idea:Big model is not necessarily good model.
大 model 包含細 model:如果新加嘅 完全冇用,OLS 大可以揀 ,RSS 就同細 model 一樣。所以 OLS minimize 出嚟嘅 RSS 只會相等或者更細。問題係,佢可能用新 predictor 去「fit noise」——即係記住 training data 嘅隨機波動,去到新 data 就唔 work,呢個就係 overfitting。
例子:用學生學號尾數做 predictor 去 predict 考試分,training RSS 都可能跌少少,但對新學生完全冇預測力。
點樣 compare 大細 model?本講提供兩個方法:
| Method 1:Penalty(slides 3–6) | Method 2:Cross Validation(slides 7–12) | |
|---|---|---|
| 諗法 | Punish big model:RSS + penalty term | 直接睇 prediction ability on unseen data |
| 工具 | Mallows' 、AIC、BIC | Train-test split、K-fold CV、LOOCV |
| 用嘅 data | Full training set(fit 一次) | Split data,fit 多次 |
| 準則 | Lower is better | CV error(MSE)lower is better |
2. Method 1:用 Penalty 懲罰大 model(slides 3–6)
2.1 Mallows' (slide 4)
- :用 個 predictors(including intercept)嘅 sub-model 嘅 residual SS。
- 最重要係 :加落 RSS 度去 discourage big model,所以統計學家叫佢做 penalty。Big models get punished.
點理解: 隨 增加而跌(fit 得好啲),penalty 隨 增加而升。 係兩股力嘅 trade-off:新加嘅 predictor 要令 RSS 跌多過 ,先值得加。
Slide 4 寫 。分母用 (全部 predictors 數目),一般教科書(ISLR)嘅做法係用 full model(包含全部 p 個 predictors) 估計 ,然後所有 sub-models 用同一個 比較。考試請跟 slide 嘅寫法;如有疑問可以問 lecturer。
2.2 AIC 同 BIC(slide 5)
除咗 ,仲有其他方法懲罰大 model:
Akaike information criterion (AIC)
Bayesian information criterion (BIC),with sample size
The penalty in BIC is even heavier than those in AIC and .
| Criterion | 每個 predictor 嘅 penalty | 特點 |
|---|---|---|
| (再除 ) | Lower is better | |
| AIC | (再除 ) | ,同 成正比 |
| BIC | Penalty 最重 → 揀較細 model |
比較 penalty 嘅系數:AIC / 係 2,BIC 係 (natural log)。當 ,即 ,BIC 就重過 AIC。實際 data 幾乎一定 ,例如 :,差唔多係 AIC 嘅兩倍;:。
- 依 slide 嘅定義,。如果所有 models 用同一個 ,AIC 同 會揀出同一個 model。
- 三個都係 lower is better。唔好同 (higher is better)撈亂。
- 數 predictors 時要包埋 intercept。
2.3 Worked example
,用 (全部 models 共用)。比較兩個 models:
| Model | (含 intercept) | |
|---|---|---|
| A(2 個 predictors) | 3 | 650 |
| B(4 個 predictors) | 5 | 600 |
B 嘅 RSS 細啲(意料之內,因為 model 大啲)。但計埋 penalty:
兩個 criteria 都係 A 較低 → 揀 A。B 多咗 2 個 predictors,RSS 只跌咗 50,唔夠抵銷 penalty。留意 BIC 下 A 贏得更多,因為 BIC penalty 更重。
Slide 6:呢啲定義背後嚴格嘅數學 rationale 涉及更高深嘅統計知識,屬 Out-of-syllabus。
3. Method 2:Cross Validation(slides 7–12)
Crucial idea 一樣係 big model is not necessarily good model,但 Method 2 直接問:個 model 喺 unseen data 上係咪真係 work?方法係比較大細 models 嘅 prediction abilities。Underlying principle:Train-test split。
3.1 Train-test split(slides 8–9)
- 將 full data split 做 training data 同 testing data。
- 用 training data 做
statsmodels.api.OLS()。 - 扮唔知 test data 嘅 Y,用
predict()。 - 比較 actual value 同 predicted value,用 bias 同 mean squared error 量度 prediction accuracy。
( = test data 數目。)Slide 9 嘅圖:data 分成 Training data 同 Validation/Test data 兩段。
簡單 split 有個弱點:結果視乎邊啲 data 啱啱好分咗落 test set,換一個 split 可能得出唔同 MSE。改良版本喺實際好常用:K-fold CV 同 Leave-one-out。
3.2 K-fold cross validation(slide 10)
Slide 10 嘅圖(5-fold CV,取自 ISLR Figure 5.5):將 n 個 observations randomly 分成 5 個 non-overlapping groups。每一份輪流做 validation set(test data),其餘 4 份做 training set。Test error 用 5 個 MSE 嘅平均估計。
- 將 data 隨機分成 K 份(folds)。
- For :用第 k 份做 test,其餘 K−1 份 train model,計 。
- CV error:
每個 observation 都會剛好做一次 test data;model 要 fit K 次。
3.3 Leave-one-out(slides 11–12)
- 每次只留 1 個 observation 做 test,用其餘 個 train。
- Leave-one-out is the same as n-fold CV(n = sample size)。
- Computationally expensive:500 個 data instances 就要 run 500 次。
| 方法 | Fit 幾多次 | 特點 |
|---|---|---|
| Train-test split | 1 | 最快;結果受 split 方式影響 |
| K-fold CV(常用 K = 5 / 10) | K | 平衡準確度同計算量 |
| LOOCV | n | = n-fold CV;最貴 |
COM6004 Classification (II)(Ch 4b)講 overfitting 同 model evaluation,都用 holdout、cross-validation 呢套諗法。分別只係 classification 用 error rate / accuracy,呢度 regression 用 MSE。Module 5 嘅 logistic regression 用 misclassification rate,亦係同一個框架。
4. Best subset selection(slides 13–17)
- Best subset selection:揀 AIC / BIC / 最細,或者 CV 表現最好嘅 sub-model。
- BIC chosen model usually contains less predictors than chosen model.
- 如果你偏好 parsimonious(節儉)model,又唔介意 deselect 一啲 relevant 但影響力較細嘅 predictors,就用 BIC。
(Slide 14 只係一張 savings jar 嘅圖,引入下面嘅 savings dataset。)
4.1 有幾多個 models?(slide 15)
例子:Y = sr(savings rate),4 個 predictors:pop15、pop75、dpi、ddpi。可能嘅 linear models 例如 sr ~ 1、sr ~ pop15+dpi、sr ~ pop75+dpi+ddpi……
每個 predictor 只有「入」或「唔入」兩個選擇,所以 p 個 predictors 有 個 models(包括 null model sr ~ 1)。Best subset selection means try them all.
4.2 Python:ExhaustiveFeatureSelector + CV(slide 16)
import pandas as pd
import numpy as np
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
from mlxtend.feature_selection import ExhaustiveFeatureSelector as EFS
savings = pd.read_csv("savings.csv")
X = savings[['pop15', 'pop75', 'dpi', 'ddpi']]
X = sm.add_constant(X) # 加一個全 1 嘅 column 代表 constant term(column 0)
y = savings['sr']
efs = EFS(LinearRegression(),
min_features=1,
max_features=4,
fixed_features=(0,), # column 0(const)一定要包括
scoring='neg_mean_squared_error', # higher is better,所以用負 MSE
cv=5) # 5-fold CV
efs = efs.fit(X, y)
print('Best subset:', efs.best_feature_names_)
efs.subsets_ # 每個 subset 嘅詳細結果
# Something wrong, why cannot cover all 16 possible choices?
| Argument | 意思 |
|---|---|
min_features / max_features | Subset 最少 / 最多有幾多個 columns(const 都計一個) |
fixed_features=(0,) | 第 0 個 column(const)每個 subset 都包括 |
scoring='neg_mean_squared_error' | mlxtend / sklearn 嘅 score 係 higher is better,所以將 MSE 變負數 |
cv=5 | 用 5-fold CV 計每個 subset 嘅 score |
sm.add_constant 之後 X 有 5 個 columns(const + 4 predictors),而 const 已 fixed。max_features=4 計埋 const,即係最多只可以有 3 個真 predictors,所以 full model(const + 4 個 predictors = 5 columns)冇咗,只得 1 + 4 + 6 + 4 = 15 個 subsets。解決方法:設 max_features=5(slide 17 正係咁做)。
LinearRegression() 本身已經 fit intercept(fit_intercept=True),所以 const column 其實係多餘,佢嘅 coefficient 會係 0,唔影響結果。Slide 加佢入去,係為咗令 "const only" 對應 null model sr ~ 1,數 models 時同 statsmodels 嘅寫法一致。
4.3 Python:用 BIC 做 subset selection(slide 17)
# 1. 自定 BIC scorer
def bic_scorer(estimator, X, y):
n_samples = X.shape[0]
n_features = X.shape[1]
y_pred = estimator.predict(X)
rss = np.sum((y - y_pred) ** 2) # Residual Sum of Squares
if rss < 1e-10: # 避免 log(0)
return -np.inf
bic = n_samples * np.log(rss / n_samples) + n_features * np.log(n_samples)
return -bic # mlxtend 係 maximize score,所以回傳負 BIC
# 2. Base estimator
lr = LinearRegression()
# 3. ExhaustiveFeatureSelector
efs = EFS(estimator=lr,
min_features=1,
max_features=5, # const + 4 個 predictors,16 個 models 齊晒
fixed_features=(0,),
scoring=bic_scorer, # 直接傳 function
cv=0, # 0 = 用成個 training set 評估,唔做 CV
print_progress=True)
efs = efs.fit(X, y)
print('Best subset:', efs.best_feature_names_)
efs.subsets_
cv=0?
BIC 係 information criterion,設計上係用 full training set 嘅 RSS 加 penalty 嚟評估 model(Method 1),唔需要 split data。CV 係 Method 2,兩者係唔同方法,唔使疊埋一齊用。
Code 用 ,同 slide 5 嘅 寫法唔同。兩者都係「fit 嘅好壞 + model size」嘅 penalty 結構,前者係 normal errors 下由 likelihood 推出嘅常見版本。數值唔同,但用嚟排序同一批 models 時通常揀出相近嘅答案。推導屬 out-of-syllabus。
5. Forward and Backward Selection(slides 18–22)
Best subset 對大 p 唔實際(impractical for large p)。Slide 18 問:p = 20 時有幾多個 models?
如果再用 5-fold CV,就要 fit 超過 500 萬次。Forward 同 backward selection 係 sub-optimal but practical 嘅方法。
Method A:Forward selection
- 由 null model 開始。
- 逐個試餘下嘅 predictor,計新 RSS,揀改善 RSS 最多嗰個。
- 用 、AIC 或 BIC 比較新 model 同原本 model。如果冇改善,停;否則返去 Step 2。
Method B:Backward selection
同 forward 類似,但由 full model 開始,逐步 remove predictors。
Step 2 入面所有 candidate models 嘅 size 一樣(都係加一個 predictor),所以直接比 RSS 已經公平。Step 3 比較嘅係唔同 size 嘅 models,RSS 一定偏好大 model(Section 1),所以要用有 penalty 嘅 criterion。
Forward / backward selection 揀出嚟嘅 model 唔保證係 best subset,因為每步只做 greedy 決定,一旦加入(或刪除)就唔會再返轉頭。佢哋實用嘅原因係計算量即使 p 更大都負擔得起。
計算量比較(p = 20):forward selection 第 1 步試 20 個、第 2 步 19 個……最多 個 models,遠少過 1,048,576。
5.1 Python:SequentialFeatureSelector(slides 20–22)
用 mlxtend.feature_selection.SequentialFeatureSelector,以 forward=True / forward=False 切換。
from mlxtend.feature_selection import SequentialFeatureSelector as SFS
sfs = SFS(LinearRegression(),
k_features="best", # 自動揀 score 最好嘅 subset size
fixed_features=(0,),
forward=True, # Forward selection;False = Backward
scoring='neg_mean_squared_error',
cv=5)
sfs = sfs.fit(X, y)
print('Best MSE score:', -sfs.k_score_) # 負負得正,變返 MSE
print('Best subset:', sfs.k_feature_names_)
sfs.subsets_
Slide 21(forward)同 slide 22(backward)嘅 code 唯一分別係 forward=True / forward=False。留意呢度用嘅係 CV MSE 做準則,唔係 /AIC/BIC。
6. Retrieve the optimal model:Pipeline(slide 23)
from sklearn.pipeline import Pipeline
from sklearn.metrics import mean_squared_error
estimator = LinearRegression()
pipeline = Pipeline([('feature_selection', sfs),
('regression', estimator)])
pipeline.fit(X_train, y_train) # 喺 training data 上做 feature selection + fit
pre_val = pipeline.predict(X_test) # 直接畀未揀 features 嘅 test data,pipeline 自己揀返 columns
act_val = y_test
bias = np.mean(pre_val - act_val)
rmse = np.sqrt(mean_squared_error(act_val, pre_val))
print(f'Out-of-sample RMSE: {rmse}')
Pipeline將「feature selection」同「regression」串成一個 model:fit時先揀 features 再 fit regression;predict時自動只用揀咗嘅 columns。- Feature selection 只喺 training data 做,最後用 test data(out-of-sample) 計 bias 同 RMSE,咁先係公平評估。
如果用全部 data(包括 test)去揀 features,再用 test data 評估,test data 嘅資訊已經「漏」咗入 model selection,out-of-sample RMSE 會過分樂觀。Pipeline 嘅寫法可以避免呢個問題。
Module 7 會講 feature extraction(PCA),同呢講嘅 feature selection 對比:selection 係保留部分原有 predictors,extraction 係將 predictors transform 做新 variables。COM6004 Ch 2 嘅 data preprocessing 亦有提 feature subset selection。
自我測驗 Self-test
Q1. Model A 有 3 個 predictors,Model B 喺 A 嘅基礎上多加 2 個。邊個 training RSS 較細?係咪代表 B 較好?
B 嘅 RSS 一定 ≤ A(bigger model, smaller RSS)。但唔代表 B 較好:small RSS 只係 in-sample fit 好,唔保證 out-of-sample prediction 好,B 可能 overfit。要用 /AIC/BIC 或 CV 比較。
Q2. 寫出 Mallows' ,指出 penalty term,並解釋 嘅意思。
。Penalty term 係 。 係 sub-model 嘅 predictors 數目(包括 intercept)。Lower is better。
Q3. ,。Model A:,RSS = 380;Model B:,RSS = 350。用 同 BIC 揀 model。
; → 揀 B。
。; → BIC 揀 A。
呢個正好示範 BIC penalty 較重,揀較細 model。
Q4. 幾時 BIC 嘅 penalty 會重過 AIC?
BIC 每個 predictor 嘅系數係 ,AIC 係 2。,即 時 BIC 已經較重。
Q5. 描述 5-fold CV,並寫出 CV error。
將 data 隨機分 5 份;每次用 1 份做 test、4 份做 training,計 MSE;重複 5 次令每份都做過 test;。
Q6. 有 500 個 data instances,LOOCV 要 fit 幾多次 model?佢同 K-fold CV 有咩關係?
500 次。LOOCV = n-fold CV(K = n),每次留 1 個做 test,所以 computationally expensive。
Q7. 有 6 個 predictors,best subset selection 要考慮幾多個 models?p = 20 呢?
(包括 null model)。,所以大 p 時要用 forward / backward selection。
Q8. Slide 16 嘅 EFS 用 max_features=4,點解唔夠 16 個 models?點改?
X 加咗 const 之後有 5 個 columns,const 係 fixed 而且會計入 feature 數目。max_features=4 即最多 3 個真 predictors,full model 被排除,只得 15 個。改做 max_features=5。
Q9. 簡述 forward selection 三個步驟。佢一定搵到 best subset 嗎?
(1) 由 null model 開始;(2) 試每個餘下 predictor,揀改善 RSS 最多嘅加入;(3) 用 /AIC/BIC 比較新舊 model,冇改善就停,否則返 Step 2。唔保證搵到 best subset(greedy、sub-optimal),但計算量細好多。
Q10. 點解 scoring='neg_mean_squared_error' 要用負數?BIC scorer 點解 return -bic?
mlxtend / sklearn 嘅 selector 永遠 maximize score(higher is better)。MSE 同 BIC 都係 lower is better,加負號之後「最大」就等於原本「最細」。
Q11. Slide 23 點解要用 Pipeline?
將 feature selection 同 regression 串埋:只用 training data 揀 features 同 fit model;predict 時直接畀原始 test data,pipeline 自動揀返同一批 columns。咁 out-of-sample RMSE 先係公平嘅評估,避免 test data 資訊漏入 selection。
一頁總結 Cheat sheet
- Big model ≠ good model。Model 越大 RSS 越細,但 prediction 係針對 out-of-sample(unseen)data。
- Method 1 Penalty(lower is better, 含 intercept):;;。
- BIC penalty 最重( when )→ 揀較少 predictors → parsimonious(節儉)model。
- Method 2 CV:Train-test split → K-fold(平均 K 個 MSE)→ LOOCV = n-fold(n 次,expensive)。用 bias、MSE / RMSE 量度。
- Best subset = 試晒 個 models(p = 4 → 16;p = 20 → 1,048,576);
ExhaustiveFeatureSelector,fixed_features=(0,)保留 const,max_features要計埋 const。 - BIC scorer 用
cv=0(information criterion 用 full training set);scorer 要 return 負值,因為 selector maximize score。 - Forward:null model → 逐個加(RSS 最好)→ /AIC/BIC 冇改善就停。Backward:full model → 逐個刪。唔保證 best subset,但平。
SequentialFeatureSelector(..., k_features="best", forward=True/False, scoring='neg_mean_squared_error', cv=5);Pipeline([('feature_selection', sfs), ('regression', LinearRegression())])→ test data 計 out-of-sample RMSE。