Mục lục
- Vì sao cần regularization
- Ý tưởng — phạt coefficient lớn
- Ridge Regression (L2)
- Lasso Regression (L1)
- ElasticNet — combine L1 và L2
- Geometric intuition của L1 vs L2
- Ridge, Lasso, ElasticNet trong sklearn
- Bắt buộc StandardScaler trước khi regularize
- Chọn alpha bằng cross-validation
- Khi nào dùng Ridge, khi nào Lasso, khi nào ElasticNet
- Regularization trong Logistic Regression — preview
- Pitfall thường gặp
- Code Python đầy đủ
- Bài tập thực hành
- Bài tiếp theo
Vì sao cần regularization
Linear Regression OLS (Bài 15) minimize MSE trên train set, không có ràng buộc nào lên độ lớn của coefficient. Bốn tình huống thường gặp khiến OLS overfit:
- Nhiều feature (high-dimensional) — số feature \( d \) gần bằng hoặc lớn hơn số sample \( n \). Khi \( d \geq n \), ma trận \( X^T X \) singular, OLS không có nghiệm duy nhất; ngay cả khi \( d \) hơi nhỏ hơn \( n \), variance của coefficient cũng rất cao.
- Multicollinearity (Bài 19) — vài feature tương quan mạnh khiến \( X^T X \) gần singular. Coefficient lớn về độ lớn, dấu có thể đảo ngẫu nhiên giữa các lần resample.
- Polynomial degree cao (Bài 20) — \( \binom{n+d}{d} \) feature mở rộng, model dao động dữ dội ở vùng ít data.
- Dataset nhỏ — vài chục sample, vài chục feature, OLS gần như chắc chắn nhớ noise.
Triệu chứng chung: train error rất thấp, test error cao; coefficient có magnitude bất thường (vd \( 10^6 \)); model nhạy cảm với thay đổi nhỏ ở train set.
Regularization là kỹ thuật chuẩn để xử lý nhóm vấn đề này — thêm một số hạng vào loss để phạt coefficient lớn.
Ý tưởng — phạt coefficient lớn
Loss OLS gốc chỉ quan tâm fit:
\[ L_{\text{OLS}}(\mathbf{w}) = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \]Regularization thêm một penalty term \( P(\mathbf{w}) \) phụ thuộc độ lớn coefficient:
\[ L(\mathbf{w}) = \underbrace{\frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2}_{\text{data fit}} + \alpha \cdot \underbrace{P(\mathbf{w})}_{\text{penalty}} \]Trong đó:
- \( \alpha \geq 0 \) (alpha) — hyperparameter điều khiển độ mạnh regularization. \( \alpha \) lớn = phạt nặng = coefficient bị kéo về gần 0.
- \( P(\mathbf{w}) \) — chọn dạng penalty: tổng bình phương (\( L_2 \)) hoặc tổng giá trị tuyệt đối (\( L_1 \)) hoặc combine.
Hai trường hợp giới hạn:
- \( \alpha = 0 \) → trở về OLS thuần.
- \( \alpha \to \infty \) → penalty áp đảo, mọi \( w_j \to 0 \) (model trở thành predict \( \bar{y} \)).
Sweet spot là một \( \alpha \) hữu hạn cân bằng được fit và simplicity. Lựa chọn dạng \( P \) sinh ra Ridge, Lasso, ElasticNet.
Quy ước: intercept \( w_0 \) (bias) thường không bị regularize — chỉ phạt các \( w_j \) với \( j \geq 1 \). Sklearn xử lý mặc định như vậy.
Ridge Regression (L2)
Ridge dùng penalty \( L_2 \) — tổng bình phương coefficient:
\[ L_{\text{ridge}}(\mathbf{w}) = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 + \alpha \sum_{j=1}^{d} w_j^2 \]Hay viết gọn dưới dạng norm: \( \alpha \| \mathbf{w} \|_2^2 \).
Closed-form solution — Ridge có nghiệm đóng tương tự OLS:
\[ \hat{\mathbf{w}}_{\text{ridge}} = (X^T X + \alpha I)^{-1} X^T \mathbf{y} \]So với OLS (\( \hat{\mathbf{w}} = (X^T X)^{-1} X^T \mathbf{y} \)), Ridge thêm \( \alpha I \) vào đường chéo của \( X^T X \). Hai hệ quả quan trọng:
- Luôn tồn tại nghịch đảo — kể cả khi \( X^T X \) singular (do multicollinearity hoặc \( d > n \)), cộng thêm \( \alpha I \) làm ma trận trở thành positive definite → invertible. Ridge giải được mọi tình huống mà OLS bí.
- Coefficient bị "co lại" về 0 — đường chéo lớn hơn → trong nghịch đảo, các component bị scale nhỏ lại. Ridge gọi là shrinkage estimator.
Đặc điểm coefficient Ridge:
- Tất cả \( w_j \) đều khác 0 (Ridge không tạo ra coefficient bằng 0 chính xác).
- Khi tăng \( \alpha \), mọi \( w_j \) cùng co dần về 0 nhưng giữ tỷ lệ tương đối.
- Khi hai feature tương quan, Ridge có xu hướng chia coefficient đều cho cả hai (thay vì gán hết cho một như OLS có thể làm).
Lasso Regression (L1)
Lasso (Least Absolute Shrinkage and Selection Operator, Tibshirani 1996) dùng penalty \( L_1 \) — tổng giá trị tuyệt đối:
\[ L_{\text{lasso}}(\mathbf{w}) = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 + \alpha \sum_{j=1}^{d} |w_j| \]Gọn lại: \( \alpha \| \mathbf{w} \|_1 \).
Khác biệt then chốt so với Ridge: Lasso có thể đẩy coefficient về 0 chính xác. Với \( \alpha \) đủ lớn, một phần \( w_j \) bằng đúng 0 — feature tương ứng bị loại khỏi model.
Điều này biến Lasso thành công cụ feature selection tự động:
- Train Lasso → đọc
coef_→ feature có \( w_j = 0 \) là không quan trọng. - Có thể rebuild model OLS chỉ trên subset feature non-zero.
- Đặc biệt hữu ích khi \( d \gg n \) và biết trước chỉ một phần nhỏ feature thực sự liên quan (sparse signal).
Không có closed-form — vì \( |w_j| \) không khả vi tại \( w_j = 0 \). Phải dùng thuật toán lặp; sklearn dùng coordinate descent: tối ưu từng \( w_j \) một, giữ các \( w_k \) còn lại cố định, lặp tới khi hội tụ. Mỗi step có công thức đóng (soft-thresholding), tổng thể chạy rất nhanh.
Có thể chứng minh: với một feature \( x_j \) đơn lẻ, update coordinate descent của Lasso là soft-thresholding giá trị OLS:
\[ w_j \leftarrow \operatorname{sign}(\tilde{w}_j) \cdot \max\bigl( |\tilde{w}_j| - \alpha, \; 0 \bigr) \]Khi \( |\tilde{w}_j| \leq \alpha \), update ra đúng 0 — nguồn gốc của sparsity.
ElasticNet — combine L1 và L2
ElasticNet (Zou & Hastie 2005) trộn hai penalty bằng một hệ số \( \rho \in [0, 1] \) (l1_ratio trong sklearn):
Trường hợp đặc biệt:
- \( \rho = 0 \) → Ridge thuần.
- \( \rho = 1 \) → Lasso thuần.
- \( 0 < \rho < 1 \) → trộn cả hai. Phổ biến: \( \rho = 0.5 \).
Use case chính: nhiều feature tương quan thành nhóm, muốn group selection. Lasso đơn thuần khi gặp nhóm feature tương quan có xu hướng chọn ngẫu nhiên 1 feature trong nhóm, bỏ những feature khác — kết quả không ổn định giữa các lần resample. ElasticNet với phần \( L_2 \) khuyến khích các feature tương quan có coefficient gần nhau, nên chọn hoặc loại bỏ cả nhóm cùng lúc.
Ví dụ kinh điển: gene expression data có nhiều gene cùng pathway tương quan mạnh — ElasticNet ổn định hơn Lasso để chọn pathway.
Sklearn cũng không có closed-form cho ElasticNet, dùng coordinate descent tương tự Lasso.
Geometric intuition của L1 vs L2
Vì sao Lasso ra coefficient sparse còn Ridge thì không? Cách trực quan nhất là nhìn dưới dạng constrained optimization.
Cả Ridge và Lasso đều tương đương với việc minimize MSE under constraint:
\[ \min_{\mathbf{w}} \; \frac{1}{n} \sum (y_i - \hat{y}_i)^2 \quad \text{với điều kiện} \quad \begin{cases} \sum w_j^2 \leq t & \text{(Ridge)} \\ \sum |w_j| \leq t & \text{(Lasso)} \end{cases} \](Có một ánh xạ 1–1 giữa \( \alpha \) và \( t \), không cần biết công thức cụ thể.)
Trong không gian 2D (\( d = 2 \), trục \( w_1, w_2 \)):
- Constraint Ridge \( w_1^2 + w_2^2 \leq t \) — hình tròn, biên trơn mọi nơi.
- Constraint Lasso \( |w_1| + |w_2| \leq t \) — hình thoi, biên có 4 đỉnh nhọn nằm đúng trên các trục \( w_1 = 0 \) và \( w_2 = 0 \).
Loss MSE trên không gian \( (w_1, w_2) \) có dạng paraboloid lồi → các level set (đường đồng mức MSE) là ellipse đồng tâm quanh nghiệm OLS \( \hat{\mathbf{w}}_{\text{OLS}} \).
Nghiệm regularization là điểm tiếp xúc giữa ellipse MSE và biên constraint:
- Với hình tròn (Ridge), ellipse có thể chạm biên ở bất kỳ điểm nào — nói chung tiếp xúc ở vị trí cả \( w_1, w_2 \) khác 0.
- Với hình thoi (Lasso), đỉnh nhọn nằm trên trục. Ellipse mở rộng dần từ tâm OLS — xác suất "chạm" được góc nhọn (nằm trên trục, tức \( w_j = 0 \)) cao, vì góc nhọn "đâm ra" xa hơn so với cạnh. Khi tiếp xúc tại góc, một coefficient bằng đúng 0.
Tổng quát trong \( d \) chiều: hình cầu \( L_2 \) trơn mọi nơi, hình đa diện \( L_1 \) có nhiều "góc" và "cạnh" nằm trên các subspace \( w_j = 0 \). Càng tăng số chiều, càng nhiều cạnh/đỉnh — Lasso càng dễ tạo sparsity.
Đây là cách hình học giải thích vì sao \( L_1 \) ra sparse, \( L_2 \) ra "shrink nhưng không zero".
Ridge, Lasso, ElasticNet trong sklearn
Cả ba estimator nằm trong sklearn.linear_model, API giống LinearRegression:
from sklearn.linear_model import Ridge, Lasso, ElasticNet
ridge = Ridge(alpha=1.0)
lasso = Lasso(alpha=0.1)
enet = ElasticNet(alpha=1.0, l1_ratio=0.5)
ridge.fit(X_train, y_train)
lasso.fit(X_train, y_train)
enet.fit(X_train, y_train)
print(ridge.coef_, ridge.intercept_)
print(lasso.coef_) # nhieu phan tu = 0 neu alpha du lon
Một vài tham số đáng chú ý:
alpha— hệ số regularization. Định nghĩa trong sklearn khác chút so với một số tài liệu: sklearn dùng tổng squared residual (không chia \( n \)) cho Ridge, và \( \frac{1}{2n} \) cho Lasso/ElasticNet. Hệ quả: cùng \( \alpha = 1 \), Ridge và Lasso không "mạnh ngang nhau". Luôn tune \( \alpha \) bằng CV cho từng estimator riêng.l1_ratio(chỉ ElasticNet) — \( \rho \in [0, 1] \), tỷ lệ phần L1. Mặc định 0.5.max_iter,tol— kiểm soát coordinate descent của Lasso/ElasticNet. Khi gặp warning "ConvergenceWarning: Objective did not converge", tăngmax_iterhoặc nớitol.fit_intercept— mặc địnhTrue, intercept không bị regularize.random_state— chỉ ảnh hưởng khiselection="random"trong Lasso/ElasticNet.
Bắt buộc StandardScaler trước khi regularize
Đây là quy tắc không thương lượng với Ridge/Lasso/ElasticNet: scale feature về cùng range trước khi fit.
Lý do: penalty áp đều lên mọi \( w_j \), không quan tâm scale của feature tương ứng. Coefficient của một feature có scale lớn (vd thu nhập trong VND) buộc phải nhỏ về số học để cùng "đóng góp" như feature scale nhỏ (vd số con cái) → bị penalty nhẹ; ngược lại coefficient của feature scale nhỏ buộc phải lớn → bị penalty nặng. Kết quả: regularization phân bổ không công bằng giữa các feature, model bias về feature scale lớn.
Ví dụ minh hoạ: data với 2 feature:
- \( x_1 \) = thu nhập VND (range \( 10^7 \)).
- \( x_2 \) = số người trong hộ (range \( 10^0 \)).
Nếu cả hai cùng quan trọng, coefficient OLS có dạng \( w_1 \sim 10^{-7} \), \( w_2 \sim 10^0 \). Penalty \( w_1^2 + w_2^2 \approx 0 + 1 = 1 \) — gần như chỉ phạt \( w_2 \). Lasso sẽ luôn zero-out \( w_2 \) trước khi đụng đến \( w_1 \) — feature selection vô nghĩa.
Cách xử lý chuẩn — pipeline:
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge
pipe = make_pipeline(
StandardScaler(),
Ridge(alpha=1.0),
)
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
StandardScaler đưa mọi feature về mean 0, std 1 — penalty mới fair giữa các \( w_j \). Sau scale, coefficient có ý nghĩa "thay đổi \( y \) khi feature tăng 1 độ lệch chuẩn", thuận tiện để so sánh importance.
Quên scale là pitfall phổ biến nhất khi dùng Ridge/Lasso lần đầu. Nếu kết quả Lasso "kỳ lạ" (luôn loại cùng vài feature bất kể \( \alpha \)), kiểm tra scale trước hết.
Chọn alpha bằng cross-validation
\( \alpha \) là hyperparameter — không có công thức đóng cho giá trị tối ưu, phải tune. Hai cách chính:
1. Grid search với cross-validation — chuẩn nhất.
from sklearn.model_selection import GridSearchCV
param_grid = {"ridge__alpha": [0.001, 0.01, 0.1, 1, 10, 100]}
grid = GridSearchCV(pipe, param_grid, cv=5, scoring="r2")
grid.fit(X_train, y_train)
print(grid.best_params_, grid.best_score_)
2. Built-in CV estimator — sklearn có sẵn RidgeCV, LassoCV, ElasticNetCV tối ưu hơn (re-use computation giữa các \( \alpha \)):
from sklearn.linear_model import RidgeCV, LassoCV, ElasticNetCV
ridge_cv = RidgeCV(alphas=[0.001, 0.01, 0.1, 1, 10, 100], cv=5)
ridge_cv.fit(X_train_scaled, y_train)
print(ridge_cv.alpha_) # alpha tot nhat
lasso_cv = LassoCV(cv=5, n_alphas=100, random_state=42)
lasso_cv.fit(X_train_scaled, y_train)
print(lasso_cv.alpha_) # tu sinh duong alpha
LassoCV và ElasticNetCV mặc định tự sinh dãy \( \alpha \) (geometric grid từ \( \alpha_{\max} \) — giá trị tối đa khiến tất cả coef = 0 — xuống thấp), không cần chỉ định tay. Đây thường là cách nhanh nhất để có baseline.
Validation curve — visualize ảnh hưởng \( \alpha \):
- Trục x: \( \alpha \) (thường thang log).
- Trục y: \( R^2 \) trên train và validation.
- \( \alpha \) nhỏ → train cao, validation thấp (overfit).
- \( \alpha \) lớn → cả train và validation cùng thấp (underfit).
- Giữa hai vùng là sweet spot — \( \alpha^* \) cho validation tốt nhất.
Code minh hoạ ở mục 13.
Khi nào dùng Ridge, khi nào Lasso, khi nào ElasticNet
Không có "best estimator" tuyệt đối, tuỳ assumption về cấu trúc data:
- Ridge — khi nhiều feature đều có đóng góp nhỏ, muốn giữ tất cả nhưng giảm magnitude để ổn định. Thường là default an toàn cho regularization. Tốt khi feature tương quan và không có lý do tin rằng có feature thực sự "vô dụng".
- Lasso — khi nghi ngờ chỉ một subset nhỏ feature thực sự liên quan (sparse signal). Đặc biệt phù hợp \( d \gg n \). Bonus: cho feature selection tự động, model gọn, dễ diễn giải.
- ElasticNet — khi có nhóm feature tương quan và muốn nhóm cùng được giữ hoặc cùng bị loại. Tránh được instability của Lasso khi gặp correlated feature.
- OLS thuần (không regularize) — khi \( n \gg d \), không có multicollinearity, không có polynomial bậc cao. Khi đó OLS đã unbiased, regularization chỉ thêm bias không cần thiết.
Trong thực hành, một workflow phổ biến: chạy nhanh Ridge, Lasso, ElasticNet (mỗi cái có CV tự tune \( \alpha \)) cùng OLS thuần trên cùng dataset, so sánh \( R^2 \) test → chọn estimator thắng. Cost computation thấp, có cái nhìn đầy đủ.
Regularization trong Logistic Regression — preview
Regularization không chỉ áp dụng cho regression. LogisticRegression trong sklearn mặc định đã bật L2:
from sklearn.linear_model import LogisticRegression
# Default: penalty="l2", C=1.0
clf = LogisticRegression(penalty="l2", C=1.0)
# Lasso-style cho classification
clf_l1 = LogisticRegression(penalty="l1", solver="liblinear", C=1.0)
# ElasticNet cho classification
clf_en = LogisticRegression(
penalty="elasticnet", solver="saga", l1_ratio=0.5, C=1.0,
)
Hai khác biệt notation đáng chú ý:
- Tham số tên
C, không phảialpha. Quan hệ: \( C = 1 / \alpha \) — nghịch đảo. \( C \) lớn = regularization yếu (gần OLS/MLE), \( C \) nhỏ = regularization mạnh. - Phải chọn
solvertương thích với penalty:lbfgs(default) chỉ hỗ trợ L2;liblinearhỗ trợ L1 và L2;sagahỗ trợ cả ElasticNet.
Lý do và toán chi tiết của Logistic Regression sẽ ở Bài 22. Riêng về regularization, các pattern giống hệt: scale trước, CV tune \( C \), L1 cho sparse, L2 cho shrinkage smooth.
Pitfall thường gặp
- Quên scale feature — như mục 8, penalty mất công bằng. Triệu chứng: Lasso luôn loại cùng vài feature bất kể \( \alpha \), Ridge coefficient lệch nhiều so với expected.
- \( \alpha \) quá lớn — model gần predict \( \bar{y} \), \( R^2 \) tệ trên cả train lẫn test. Underfit. Giảm \( \alpha \).
- \( \alpha \) quá nhỏ — model gần OLS, không hưởng lợi regularization. Triệu chứng: kết quả Ridge/Lasso/ElasticNet xấp xỉ OLS. Tăng \( \alpha \) hoặc thử thang \( \alpha \) rộng hơn.
- CV alpha sai cách — scale trên toàn bộ train set rồi mới CV → data leakage từ validation fold sang train fold của scaler. Cách đúng: scale trong pipeline để mỗi fold của CV tự fit scaler trên fold của nó:
# SAI: data leakage
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)
GridSearchCV(Ridge(), {"alpha": [...]}, cv=5).fit(X_scaled, y_train)
# DUNG: scaler trong pipeline
pipe = make_pipeline(StandardScaler(), Ridge())
GridSearchCV(pipe, {"ridge__alpha": [...]}, cv=5).fit(X_train, y_train)
- So sánh coefficient giữa Ridge và Lasso khi \( \alpha \) khác nhau — không nên. Mỗi estimator có scale \( \alpha \) riêng do định nghĩa loss khác nhau, không thể đọc coefficient mà không qua CV cho cả hai.
- ConvergenceWarning của Lasso/ElasticNet — coordinate descent chưa hội tụ. Tăng
max_iter(vd 10000), nớitol, hoặc kiểm tra lại scaling. - Diễn giải coefficient sau StandardScaler — coefficient trong không gian đã scale. Để diễn giải ngược lại theo đơn vị gốc, chia coef cho
scaler.scale_của feature tương ứng.
Code Python đầy đủ
So sánh LinearRegression, Ridge, Lasso, ElasticNet trên California housing:
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet
from sklearn.pipeline import make_pipeline
from sklearn.metrics import r2_score
data = fetch_california_housing()
X, y = data.data, data.target # 20640 sample, 8 feature
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
models = {
"OLS": LinearRegression(),
"Ridge": Ridge(alpha=1.0),
"Lasso": Lasso(alpha=0.1),
"ElasticNet": ElasticNet(alpha=0.1, l1_ratio=0.5),
}
for name, est in models.items():
pipe = make_pipeline(StandardScaler(), est)
pipe.fit(X_train, y_train)
coef = pipe.named_steps[type(est).__name__.lower()].coef_
n_zero = int(np.sum(np.isclose(coef, 0)))
r2 = r2_score(y_test, pipe.predict(X_test))
print(f"{name:12s} R2_test={r2:+.4f} n_zero_coef={n_zero}")
Output điển hình (con số tuỳ random_state):
OLS R2_test=+0.59 n_zero_coef=0
Ridge R2_test=+0.59 n_zero_coef=0
Lasso R2_test=+0.28 n_zero_coef=4
ElasticNet R2_test=+0.30 n_zero_coef=4
Quan sát: Lasso với \( \alpha = 0.1 \) quá mạnh trên dataset này — loại 4/8 feature, \( R^2 \) tụt mạnh. Đây là dấu hiệu cần CV tune \( \alpha \).
Validation curve cho Ridge — quét \( \alpha \) và plot \( R^2 \) test:
alphas = [0.001, 0.01, 0.1, 1, 10, 100, 1000]
results = []
for a in alphas:
pipe = make_pipeline(StandardScaler(), Ridge(alpha=a))
pipe.fit(X_train, y_train)
r2_tr = r2_score(y_train, pipe.predict(X_train))
r2_te = r2_score(y_test, pipe.predict(X_test))
results.append((a, r2_tr, r2_te))
for a, r_tr, r_te in results:
print(f"alpha={a:>7.3f} R2_train={r_tr:+.4f} R2_test={r_te:+.4f}")
Trên California housing, ảnh hưởng của \( \alpha \) lên Ridge khá nhẹ (vì \( n \gg d \), bài toán well-conditioned). Khi chuyển sang dataset \( d \gg n \), độ nhạy với \( \alpha \) sẽ rõ rệt hơn — xem Bài tập 3.
Tự động tune bằng RidgeCV:
from sklearn.linear_model import RidgeCV
pipe = make_pipeline(
StandardScaler(),
RidgeCV(alphas=np.logspace(-3, 3, 13), cv=5),
)
pipe.fit(X_train, y_train)
ridge_cv = pipe.named_steps["ridgecv"]
print("alpha tot nhat:", ridge_cv.alpha_)
print("R2 test:", r2_score(y_test, pipe.predict(X_test)))
Bài tập thực hành
Bài 1 — Lasso với \( \alpha \) khác nhau. Trên California housing (đã scale), train Lasso(alpha=0.01) và Lasso(alpha=1.0). So sánh: số coefficient bằng 0, \( R^2 \) test. Giá trị \( \alpha \) nào loại feature nhiều hơn? Có hợp lý không khi nhìn vào số coef = 0?
Bài 2 — RidgeCV tự động. Dùng RidgeCV(alphas=np.logspace(-3, 3, 50), cv=5) trong pipeline với StandardScaler, fit trên California housing. In alpha_ tốt nhất, so sánh \( R^2 \) test với Ridge(alpha=1.0) (default). RidgeCV có cải thiện đáng kể không? Nếu không, vì sao (gợi ý: nghĩ về \( n \) và \( d \) của dataset)?
Bài 3 — Dataset sparse high-dimensional. Sinh data 100 feature, 200 sample nhưng chỉ 5 feature đầu thực sự liên quan tới \( y \), 95 feature còn lại là nhiễu:
from sklearn.datasets import make_regression
X, y, true_coef = make_regression(
n_samples=200, n_features=100, n_informative=5,
noise=10, coef=True, random_state=42,
)
Train Lasso với CV tự tune \( \alpha \) (dùng LassoCV). Đếm số coef non-zero, so sánh với 5 feature thực sự informative theo true_coef. Lasso có chọn đúng các feature informative không? In top-10 feature có |coef| lớn nhất, so với top-10 theo |true_coef|.
Bài 4 — Diễn giải coef sau scale. Train Ridge(alpha=1.0) trên California housing với pipeline StandardScaler. Lấy coefficient trong không gian scaled. Chuyển ngược về đơn vị gốc bằng coef_orig = coef_scaled / scaler.scale_. Verify: dùng coefficient gốc + intercept gốc predict lại, kết quả có khớp pipe.predict(X_test) không (sai số dưới \( 10^{-10} \))?
Bài 5 — ElasticNet vs Lasso với feature tương quan. Sinh data có 3 nhóm feature mỗi nhóm 5 feature tương quan mạnh trong cùng nhóm (vd cộng cùng base + nhiễu nhỏ). Chỉ nhóm 1 thực sự liên quan tới \( y \). Train LassoCV và ElasticNetCV(l1_ratio=[0.1, 0.5, 0.9]). So sánh xem mỗi estimator chọn bao nhiêu feature từ nhóm 1, bao nhiêu từ nhóm 2 và 3. ElasticNet có chọn cả nhóm 1 ổn định hơn không?
Gợi ý đáp án Bài 3: Với LassoCV, số non-zero thường trong khoảng 5–20 (đúng 5 nếu \( \alpha \) đủ lớn, hơn 5 nếu \( \alpha \) nhỏ giữ thêm vài feature noise). Top-5 theo |coef| Lasso thường trùng phần lớn với top-5 theo |true_coef| — đây là khả năng support recovery của Lasso khi signal đủ mạnh và \( n \) đủ lớn.
Bài tiếp theo
Bài 22: Logistic Regression — chuyển sang bài toán classification. Logistic Regression dùng hàm sigmoid để chuyển linear combination \( \mathbf{w}^T \mathbf{x} \) thành xác suất, train bằng maximum likelihood; cũng hỗ trợ L1/L2/ElasticNet theo cùng nguyên lý regularization của bài này, chỉ khác tham số tên là \( C = 1/\alpha \). Đây cũng là module mới — Classification — của series.
Tài liệu tham khảo
- scikit-learn — Ridge regression and classification
- scikit-learn — Lasso
- scikit-learn — Elastic-Net
- scikit-learn — RidgeCV API reference
- scikit-learn — LassoCV API reference
- Tibshirani 1996 — Regression Shrinkage and Selection via the Lasso (JRSS-B)
- Zou & Hastie 2005 — Regularization and Variable Selection via the Elastic Net
- Gareth James et al. — An Introduction to Statistical Learning (Chương 6: Linear Model Selection and Regularization)
- Hastie, Tibshirani, Friedman — The Elements of Statistical Learning (Chương 3.4: Shrinkage Methods)
