Chương 2·Bài 2.2

Regularization

Quay lại bài toán định giá căn hộ ở bài 2.1. Lần này bảng dữ liệu rộng hơn: ngoài diện tích và khoảng cách tới trung tâm còn 30 cột khác, kiểu như số chữ cái trong tên chủ nhà hay ngày trong tuần lúc đăng tin, không cột nào liên quan tới giá. Trong khi đó chỉ có 40 căn để học. Linear regression khớp 40 căn này gần như hoàn hảo, nhưng đoán căn mới thì sai nhiều: nó học thuộc 40 căn chứ không học được cách định giá. Regularization sửa việc này bằng cách phạt trọng số lớn: model vẫn phải khớp dữ liệu, nhưng trọng số càng lớn thì loss càng tăng.

Khi mô hình học thuộc

Dữ liệu sinh theo đúng công thức của bài 2.1, chỉ thêm 30 cột ngẫu nhiên không liên quan gì đến giá. 40 căn đầu dùng để học, 60 căn còn lại để kiểm tra. Đặc trưng được chuẩn hóa bằng trung bình và độ lệch chuẩn của tập train, như bài 2.1 đã dặn.

Python
import numpy as np

rng = np.random.default_rng(1)
n, k = 100, 30
area = rng.uniform(30, 120, n)
dist = rng.uniform(1, 15, n)
junk = rng.normal(size=(n, k))                       # 30 cột không liên quan đến giá
y = 0.05 * area - 0.15 * dist + 1.0 + rng.normal(0, 0.4, n)

X = np.column_stack([area, dist, junk])              # (100, 32)
X_tr, X_te, y_tr, y_te = X[:40], X[40:], y[:40], y[40:]
mu, sigma = X_tr.mean(axis=0), X_tr.std(axis=0)
A_tr, A_te = (X_tr - mu) / sigma, (X_te - mu) / sigma
print(A_tr.shape, A_te.shape)

Dùng R2R^2 của bài 2.1 để chấm, và giải least squares như cũ:

Python
def r2(y_hat, y):
    return 1 - np.mean((y_hat - y) ** 2) / np.var(y)

def fit_ols(A, y):
    Ab = np.column_stack([A, np.ones(len(A))])
    theta = np.linalg.lstsq(Ab, y, rcond=None)[0]
    return theta[:-1], theta[-1]

w, b = fit_ols(A_tr, y_tr)
print("R2 train:", round(r2(A_tr @ w + b, y_tr), 3), " R2 test:", round(r2(A_te @ w + b, y_te), 3))
print("2 hệ số thật:", w[:2].round(2), " |hệ số rác| lớn nhất:", np.abs(w[2:]).max().round(2))

Điểm train 0.9850.985, điểm test 0.3490.349. Khoảng cách lớn như vậy là dấu hiệu kinh điển của overfitting (bài 1.2). Nhìn vào hệ số sẽ thấy vì sao: những cột rác, vốn phải có hệ số 0, lại nhận trọng số tới 0.440.44, cỡ một nửa hệ số của khoảng cách. Với 33 tham số và chỉ 40 căn, mô hình luôn tìm được cách dùng các cột rác để khớp nốt phần nhiễu của tập train. Những khớp đó hoàn toàn ngẫu nhiên, nên sang tập test thì chúng gây hại.

Hệ số least squares trên 40 căn: cột rác cũng nhận trọng số đáng kể.-101diện tíchkhoảng cách0.4430 cột rác: lẽ ra hệ số bằng 0
Hệ số least squares trên 40 căn: cột rác cũng nhận trọng số đáng kể.

Hỏi nhanh

Giữ nguyên 40 căn train, nhưng tăng số cột rác từ 30 lên 37. Khi đó có 39 hệ số cộng thêm bias, tức là 40 ẩn cho 40 căn. Không cần chạy code, R2R^2 trên train của least squares sẽ là bao nhiêu?

Phạt độ lớn trọng số

Ý tưởng: thay vì chỉ cực tiểu lỗi, ta cực tiểu lỗi cộng thêm một khoản phạt cho trọng số lớn:

J(w,b)=∑i=1n(w⊤xi+b−yi)2⏟khớp dữ liệu+λ Ω(w)⏟phạt độ lớn.J(\mathbf{w}, b) = \underbrace{\sum_{i=1}^{n}\left(\mathbf{w}^\top\mathbf{x}_i + b - y_i\right)^2}_{\text{khớp dữ liệu}} + \underbrace{\lambda\,\Omega(\mathbf{w})}_{\text{phạt độ lớn}}.

Vì sao trọng số lớn đáng bị phạt? Khi các đặc trưng cùng thang đo, trọng số lớn nghĩa là dự đoán thay đổi mạnh khi đặc trưng thay đổi một chút. Một mô hình như vậy rất nhạy với những dao động ngẫu nhiên trong dữ liệu, tức variance cao. Khoản phạt buộc mô hình chỉ dùng trọng số lớn khi việc đó giảm lỗi đủ nhiều để bù lại. Điều kiện “cùng thang đo” không phải chi tiết phụ; mục chuẩn hóa ở cuối bài sẽ cho thấy bỏ qua nó thì chuyện gì xảy ra.

Hệ số λ≥0\lambda \ge 0 là núm vặn. λ=0\lambda = 0 trả về least squares thường. λ\lambda rất lớn thì mọi trọng số bị ép về 0 và mô hình chỉ còn đoán giá trị trung bình. Ở giữa là điểm cân bằng giữa bias và variance mà ta sẽ tìm bằng validation. Phạt quá tay thì cả train lẫn validation cùng tụt: mô hình chưa khớp. Với cùng dữ liệu, giá trị nhỏ nhất của lỗi cộng phạt không thể giảm khi λ\lambda tăng, vì với mọi w\mathbf w khoản phạt chỉ lớn thêm.

Hai lựa chọn phổ biến nhất cho Ω\Omega:

Ridge (L2) Lasso (L1)
Khoản phạt ∥w∥22=∑jwj2\lVert\mathbf{w}\rVert_2^2 = \sum_j w_j^2 ∥w∥1=∑j∣wj∣\lVert\mathbf{w}\rVert_1 = \sum_j \lvert w_j\rvert
Tác dụng Co mọi trọng số về gần 0 Đưa nhiều trọng số về đúng 0
Hợp khi Nhiều đặc trưng cùng có ích, có tương quan Chỉ ít đặc trưng thật sự quan trọng

Bias bb không bị phạt. Nó chỉ dời toàn bộ dự đoán lên hoặc xuống cho khớp mức giá trung bình; phạt bb sẽ kéo mọi dự đoán về 0 dù dữ liệu nói gì.

Hỏi nhanh

Ridge có intercept không bị phạt. Giữ nguyên dữ liệu train và tăng mức phạt λ\lambda lên rất lớn. Dự đoán sẽ tiến dần về giá trị nào?

Ridge

Với khoản phạt L2, đạo hàm của λ∥w∥2\lambda\lVert\mathbf{w}\rVert^2 là 2λw2\lambda\mathbf{w}, nên nghiệm đóng chỉ thêm đúng một số hạng so với bài 2.1. Để không phạt bb, ta trừ trung bình khỏi các cột của XX và khỏi y\mathbf{y} trước (gọi là XcX_c, yc\mathbf{y}_c), giải w\mathbf{w}, rồi lấy b=yˉ−xˉ⊤wb = \bar y - \bar{\mathbf{x}}^\top\mathbf{w}:

wridge∗=(Xc⊤Xc+λI)−1Xc⊤yc.\mathbf{w}^\ast_{\text{ridge}} = \left(X_c^\top X_c + \lambda I\right)^{-1} X_c^\top \mathbf{y}_c.

Số hạng λI\lambda I cộng λ\lambda vào mọi trị riêng của Xc⊤XcX_c^\top X_c, nên ma trận luôn khả nghịch khi λ>0\lambda > 0. Ridge vì vậy chữa luôn chuyện đa cộng tuyến ở bài 2.1: khi hai đặc trưng gần như trùng nhau, least squares có thể cho +500+500 và −499-499, còn Ridge chia đều thành kiểu 0.50.5 và 0.50.5.

Hai đặc trưng gần trùng nhau: Ridge chọn điểm gần gốc nhất trên rãnh.w₁least squaresRidge (0.5, 0.5)w₁ + w₂ ≈ 1
Hai đặc trưng gần trùng nhau: Ridge chọn điểm gần gốc nhất trên rãnh.
Python
def fit_ridge(A, y, lam):
    a_mean, y_mean = A.mean(axis=0), y.mean()
    Ac, yc = A - a_mean, y - y_mean
    w = np.linalg.solve(Ac.T @ Ac + lam * np.eye(A.shape[1]), Ac.T @ yc)
    return w, y_mean - a_mean @ w

from sklearn.linear_model import Ridge
w, b = fit_ridge(A_tr, y_tr, 3.0)
model = Ridge(alpha=3.0).fit(A_tr, y_tr)
print(np.allclose(w, model.coef_), np.allclose(b, model.intercept_))

Hàm mất mát của Ridge trong scikit-learn đúng bằng JJ ở trên, với alpha chính là λ\lambda, nên hai kết quả trùng nhau.

Hỏi nhanh

Lấy nghiệm Ridge với λ=3\lambda = 3 làm điểm xuất phát, rồi chạy gradient descent của bài 2.1 trên tổng bình phương lỗi không có khoản phạt, với bước nhỏ và chạy đủ lâu. Trọng số sẽ đi về đâu?

Phỏng theoMIT 6.036 · Final, Spring 2022 · Q4(a), (d)

Giờ thử nhiều mức phạt:

Python
for lam in [0, 0.1, 1, 3, 10, 30, 100]:
    w, b = fit_ridge(A_tr, y_tr, lam)
    print(f"lambda = {lam:>5}: R2 train = {r2(A_tr @ w + b, y_tr):.3f}   R2 test = {r2(A_te @ w + b, y_te):.3f}")

Đây là bias–variance trên một bảng số. Tăng λ\lambda thì điểm train luôn giảm, vì mô hình bị trói tay. Điểm test thì tăng rồi giảm: lúc đầu khoản phạt dập tắt các hệ số rác (giảm variance), về sau nó dập luôn cả hai hệ số thật (tăng bias). Đỉnh nằm quanh λ\lambda từ 1 đến 3, nâng R2R^2 test từ 0.3490.349 lên 0.8390.839.

Tăng λ thì R² train giảm đều; R² test lên đỉnh ở khoảng giữa rồi giảm.00.250.50.751λ10⁻²10⁻¹10⁰10¹10²10³traintestλ ≈ 1.8học thuộctrói tay
Tăng λ thì R² train giảm đều; R² test lên đỉnh ở khoảng giữa rồi giảm.

Hỏi nhanh

Ở dòng λ=100\lambda = 100 của bảng, R2R^2 trên train là 0.5470.547, trên test là 0.3560.356. Mô hình đang gặp vấn đề gì?

Lasso

Ridge co mọi hệ số về phía 0 nhưng gần như không bao giờ đưa hệ số nào về đúng 0. Lasso dùng khoản phạt ∥w∥1\lVert\mathbf{w}\rVert_1 thì làm được. Mấu chốt nằm ở góc nhọn của ∣w∣\lvert w\rvert tại 0; cũng vì góc nhọn đó mà Lasso không có nghiệm đóng.

Có hai cách nhìn vì sao. Cách thứ nhất là hình học: bài toán có phạt tương đương với cực tiểu lỗi trong một vùng ràng buộc Ω(w)≤t\Omega(\mathbf{w}) \le t. Vùng L2 là hình tròn, vùng L1 là hình thoi có góc nằm trên các trục. Các đường đồng mức của lỗi là những elip lan dần ra từ nghiệm least squares, và lần đầu chạm hình thoi thường là ở một góc, nơi có một tọa độ bằng 0.

Đường đồng mức chạm hình thoi ở góc, nơi w₁ = 0.w₁least squaresRidge · L2w₁least squaresLasso · L1w₁ = 0
Đường đồng mức chạm hình thoi ở góc, nơi w₁ = 0.

Cách thứ hai là tính thẳng trong trường hợp đơn giản nhất: các cột của XX trực chuẩn (X⊤X=IX^\top X = I), và zj=xj⊤yz_j = \mathbf{x}_j^\top \mathbf{y} là hệ số least squares. Từ đây đến hết bài, Lasso được viết với hệ số 12\tfrac12 trước phần lỗi, 12∑iri2+λ∥w∥1\tfrac12\sum_i r_i^2 + \lambda\lVert\mathbf{w}\rVert_1, để công thức gọn; Ridge vẫn dùng JJ như trên. Khi đó mỗi trọng số được tính riêng:

wjridge=zj1+λ,wjlasso=sign⁡(zj) max⁡ ⁣(∣zj∣−λ, 0).w_j^{\text{ridge}} = \frac{z_j}{1 + \lambda}, \qquad w_j^{\text{lasso}} = \operatorname{sign}(z_j)\,\max\!\left(\lvert z_j\rvert - \lambda,\ 0\right).

Ridge co mọi hệ số theo cùng một tỉ lệ. Lasso trừ đi một lượng cố định λ\lambda rồi cắt về 0; phép biến đổi này gọi là soft-thresholding. Hệ số nào có độ lớn dưới λ\lambda biến mất hoàn toàn.

Với λ = 1, Ridge chia đôi mọi hệ số; Lasso trừ 1 rồi cắt về 0 khi |z| ≤ 1.-202-3-2-10123z (hệ số least squares)không phạtRidge: z/2Lasso: z − 1về đúng 0
Với λ = 1, Ridge chia đôi mọi hệ số; Lasso trừ 1 rồi cắt về 0 khi |z| ≤ 1.

Lấy z=(3, 0.5, −1.2)\mathbf{z} = (3,\ 0.5,\ -1.2) và λ=1\lambda = 1. Ridge cho w=(1.5, 0.25, −0.6)\mathbf{w} = (1.5,\ 0.25,\ -0.6): mọi hệ số giảm một nửa, không hệ số nào về 0. Lasso cho w=(2, 0, −0.2)\mathbf{w} = (2,\ 0,\ -0.2): đặc trưng thứ hai bị loại, hai đặc trưng còn lại mỗi cái mất đúng 1 đơn vị độ lớn.

Vòng rỗng là z, chấm đặc là hệ số sau khi phạt.-101231.50.25−0.6Ridge: chia đôi-1012320−0.2Lasso: bớt 1, cắt ở 0
Vòng rỗng là z, chấm đặc là hệ số sau khi phạt.

Hỏi nhanh

Lasso dùng hàm 12∥y−Xw∥2+λ∥w∥1\frac12\|y-Xw\|^2+\lambda\|w\|_1, với X⊤X=IX^\top X=I. Một hệ số least squares bằng z=0.8z = 0.8, và λ=1\lambda = 1. Hệ số Lasso tương ứng bằng bao nhiêu?

Hỏi nhanh

Vẫn z=(3, 0.5, −1.2)\mathbf{z} = (3,\ 0.5,\ -1.2), các cột trực chuẩn. Với Lasso, λ\lambda nhỏ nhất bằng bao nhiêu thì cả ba hệ số đều bằng 0?

Khi các cột không trực chuẩn, Lasso được giải bằng coordinate descent: lần lượt tối ưu từng wjw_j trong khi giữ các trọng số khác cố định. Mỗi bước con chính là một phép soft-thresholding như trên. Với dữ liệu đã trừ trung bình, cài đặt chỉ khoảng mười dòng:

Python
def soft(z, t):
    return np.sign(z) * np.maximum(np.abs(z) - t, 0)

def fit_lasso(A, y, lam, sweeps=500):
    a_mean, y_mean = A.mean(axis=0), y.mean()
    Ac, yc = A - a_mean, y - y_mean
    w = np.zeros(A.shape[1])
    col_sq = (Ac ** 2).sum(axis=0)
    for _ in range(sweeps):
        for j in range(len(w)):
            r_j = yc - Ac @ w + Ac[:, j] * w[j]       # phần dư khi bỏ đặc trưng j
            w[j] = soft(Ac[:, j] @ r_j, lam) / col_sq[j]
    return w, y_mean - a_mean @ w

w, b = fit_lasso(A_tr, y_tr, 8.0)
print("giữ lại các cột:", np.nonzero(w)[0], " hệ số:", w[w != 0].round(3))
print("R2 test:", round(r2(A_te @ w + b, y_te), 3))

Với λ=8\lambda = 8, Lasso giữ lại đúng hai cột đầu là diện tích và khoảng cách, loại cả 30 cột rác. Không ai nói cho nó biết cột nào là rác. Lasso vừa ước lượng vừa chọn đặc trưng (feature selection) trong cùng một bước.

Lasso của scikit-learn dùng hàm mất mát 12n∑iri2+α∥w∥1\tfrac{1}{2n}\sum_i r_i^2 + \alpha\lVert\mathbf{w}\rVert_1, tức chia hàm của ta cho nn. Nghiệm không đổi nếu alpha =λ/n= \lambda / n:

Python
from sklearn.linear_model import Lasso
model = Lasso(alpha=8.0 / 40, tol=1e-10, max_iter=100000).fit(A_tr, y_tr)
print(np.allclose(w, model.coef_, atol=1e-6), np.allclose(b, model.intercept_, atol=1e-6))

Chọn λ bằng cross-validation

Ở mục Ridge, ta đã chọn λ\lambda bằng cách nhìn thẳng vào R2R^2 test. Làm vậy để quan sát bias–variance thì được, nhưng con số 0.8390.839 đó không còn là ước lượng khách quan: chính tập test đã được dùng để chọn. λ\lambda là siêu tham số (hyperparameter). Nó không học được từ tập train, vì trên tập train thì λ=0\lambda = 0 luôn thắng, nên phải chọn bằng cross-validation (bài 1.3) trên một lưới thang log, ví dụ 10−3,10−2,…,10310^{-3}, 10^{-2}, \dots, 10^{3}. Tập test chỉ được dùng một lần, ở cuối.

Bước chuẩn hóa cũng học từ dữ liệu (trung bình và độ lệch chuẩn), nên phải được fit lại bên trong từng fold. Cách gọn nhất là gói StandardScaler và mô hình vào một Pipeline, rồi để GridSearchCV dò alpha:

Python
from sklearn.linear_model import Lasso, Ridge
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

alpha_grid = np.logspace(-3, 3, 13)
for name, estimator in [("Ridge", Ridge()), ("Lasso", Lasso(max_iter=10000))]:
    pipeline = make_pipeline(StandardScaler(), estimator)
    step_name = name.lower()
    search = GridSearchCV(pipeline, {step_name + "__alpha": alpha_grid}, cv=5)
    search.fit(X_tr, y_tr)
    alpha = search.best_params_[step_name + "__alpha"]
    coef = search.best_estimator_[-1].coef_
    print(f"{name}: alpha = {alpha:.4g}  R2 test = {search.score(X_te, y_te):.3f}  "
          f"số hệ số khác 0 = {np.count_nonzero(coef)}")
    print(f"       2 hệ số thật = {coef[:2].round(3)}  |hệ số rác| lớn nhất = {np.abs(coef[2:]).max():.3f}")

Ridge chọn alpha ≈3.16\approx 3.16, rơi đúng vào vùng λ\lambda từ 1 đến 3 đã thấy ở bảng trước, nhưng lần này không cần nhìn tập test. Lasso đạt R2R^2 test 0.9250.925, cao hơn cả mức 0.8910.891 của Lasso với λ=8\lambda = 8, dù vẫn giữ 12 cột rác. So hai dòng hệ số là thấy lý do. Với λ=8\lambda = 8, Lasso loại sạch rác nhưng co luôn hai hệ số thật xuống 1.0371.037 và −0.408-0.408. Mức phạt nhỏ hơn do CV chọn giữ hai hệ số thật ở 1.2341.234 và −0.527-0.527, còn các cột rác sống sót chỉ có hệ số nhỏ hơn 0.10.1 và gây hại không đáng kể. Cross-validation tối ưu điểm dự đoán; nó không cam kết tìm đúng tập đặc trưng thật.

Hỏi nhanh

Lasso với λ=8\lambda = 8 loại sạch 30 cột rác, còn Lasso do cross-validation chọn vẫn giữ 12 cột rác. Vậy mà bản thứ hai lại dự đoán tốt hơn trên test, 0.9250.925 so với 0.8910.891. Vì sao?

Vẽ các hệ số theo λ\lambda (regularization path) sẽ thấy rõ quá trình chọn lọc: khi phạt tăng, các cột rác rơi về 0 trước, hai cột thật trụ lại lâu nhất.

Phạt càng mạnh, cột rác về 0 trước, hai cột thật về 0 sau cùng.-1-0.500.511.5alpha (phạt tăng →)10⁻³10⁻²10⁻¹10⁰CV chọndiện tíchkhoảng cách30 cột rác
Phạt càng mạnh, cột rác về 0 trước, hai cột thật về 0 sau cùng.
Hệ số của Ridge và Lasso khi λ tăng (cam: diện tích, xanh: khoảng cách, xám: 30 cột rác): Ridge co đều, Lasso đưa từng hệ số về đúng 0.

Chuẩn hóa trước khi phạt

Khoản phạt tính trên độ lớn trọng số, mà độ lớn trọng số phụ thuộc đơn vị đo. Đổi khoảng cách từ km sang m (nhân 1000) thì hệ số của nó nhỏ đi 1000 lần để giữ nguyên dự đoán, và khoản phạt w2w^2 nhỏ đi 10610^6 lần. Cùng một λ\lambda, đặc trưng đó gần như không còn bị phạt. Thử với Ridge trên hai đặc trưng thật, chưa chuẩn hóa:

Python
B = X_tr[:, :2]                                     # diện tích (m²), khoảng cách (km)
for unit, scale in [("km", 1), ("m", 1000)]:
    M = B * np.array([1, scale])                     # khoảng cách đo bằng km hoặc bằng m
    m = Ridge(alpha=1000).fit(M, y_tr)
    print(f"khoảng cách theo {unit:>2}: hệ số quy về mỗi km = {m.coef_[1] * scale:.3f}")

Cùng dữ liệu, cùng λ\lambda, chỉ đổi đơn vị. Tính theo km thì hệ số khoảng cách bị ép mạnh về phía 0; tính theo m thì nó gần như không bị phạt, cho đúng hệ số của linear regression không phạt trên 40 căn này (−0.175-0.175). Mức phạt mà mỗi đặc trưng phải chịu phụ thuộc vào đơn vị của nó, không phụ thuộc vào việc nó quan trọng đến đâu. Chuẩn hóa đưa mọi đặc trưng về cùng thang đo để khoản phạt công bằng.

Cùng Ridge, chỉ đổi km sang m: hệ số gần như không còn bị phạt.khoảng cách theo km−0.058khoảng cách theo m−0.175không phạt: −0.1750
Cùng Ridge, chỉ đổi km sang m: hệ số gần như không còn bị phạt.

Hỏi nhanh

Đổi một feature từ km sang m mà vẫn giữ nguyên dự đoán, thì hệ số của feature ấy giảm 1000 lần. Nếu giữ nguyên λ\lambda, khoản phạt L2 trên riêng hệ số này thay đổi thế nào?

Elastic Net

Khi nhiều đặc trưng tương quan mạnh với nhau, Lasso có xu hướng giữ một cái và bỏ các cái còn lại, khá tùy ý. Elastic Net trộn hai khoản phạt, λ(ρ∥w∥1+1−ρ2∥w∥22)\lambda\left(\rho\lVert\mathbf{w}\rVert_1 + \tfrac{1-\rho}{2}\lVert\mathbf{w}\rVert_2^2\right) với ρ∈[0,1]\rho \in [0, 1], nên vẫn thưa nhưng giữ được cả nhóm đặc trưng tương quan. ρ=1\rho = 1 là Lasso, ρ=0\rho = 0 là Ridge. Trong scikit-learn, ρ\rho là l1_ratio.

Elastic Net có góc như Lasso, cạnh cong như Ridge.RidgeLassoElastic Net
Elastic Net có góc như Lasso, cạnh cong như Ridge.

Hỏi nhanh

Có ba cột gần trùng nhau, cùng đo một thứ và cùng có ích, cộng thêm vài cột nhiễu. Elastic Net với l1_ratio=0.5 thường làm gì với ba cột ấy?

Regularization ở khắp nơi

Ý tưởng “lỗi cộng phạt” xuất hiện trong gần như mọi mô hình của khóa học:

  • C trong logistic regression (bài 2.3) và SVM (bài 2.8).
  • Độ sâu tối đa và số mẫu tối thiểu ở lá của decision tree (bài 2.5).
  • Phạt L1, L2 trên giá trị lá trong XGBoost và LightGBM (bài 2.7).
  • Weight decay, dropout, early stopping trong mạng neural (bài 3.6).

Hỏi nhanh

So LogisticRegression(C=0.01) với LogisticRegression(C=100). Khác nhau thế nào?

Khi đi thi

  • Dò alpha hoặc C trên thang log: 0.01, 0.1, 1, 10.
  • Đặt chuẩn hóa và model trong cùng Pipeline để cross-validation chuẩn hóa đúng trên từng fold.
  • Nghi có nhiều cột rác thì chạy Lasso xem cột nào còn lại.

Tóm tắt

  • Regularization cực tiểu lỗi cộng phạt độ lớn trọng số; λ\lambda điều khiển cân bằng bias–variance. Bias bb không bị phạt.
  • Ridge (L2) có nghiệm đóng (Xc⊤Xc+λI)−1Xc⊤yc(X_c^\top X_c + \lambda I)^{-1}X_c^\top\mathbf{y}_c, co mọi hệ số về phía 0 và giữ nghiệm ổn định khi đặc trưng tương quan.
  • Lasso (L1) cắt hệ số nhỏ về đúng 0 bằng soft-thresholding, nên chọn được đặc trưng; cái giá là hệ số thật cũng bị co.
  • Chuẩn hóa trước khi phạt; chọn λ\lambda bằng cross-validation trên lưới log, không bằng tập test; để ý thang đo của alpha và chiều ngược của C.

Kiểm tra cuối bài

Mười câu dưới đây bao quát cả bài. Làm hết rồi xem điểm; câu nào sai thì đọc lại mục tương ứng.

Câu 1

Ridge cho R2R^2 train 0.990.99 nhưng R2R^2 validation chỉ 0.350.35. Ta nghi mô hình đang overfit. Thí nghiệm nào kiểm điều đó hợp lý nhất?

Phỏng theoCMU 10-601 · Practice Problems, Exam 2 · Q3.4

Câu 2

Xét Ridge với J(w)=12∥y−Xw∥2+λ2∥w∥2J(w)=\frac12\|y-Xw\|^2+\frac\lambda2\|w\|^2, X⊤X=IX^\top X=I và X⊤y=zX^\top y=z. Một tọa độ của zz bằng 4, và λ=1\lambda = 1. Hệ số tương ứng bằng bao nhiêu?

Câu 3

Với Lasso J(w)=12∥y−Xw∥2+λ∥w∥1J(w)=\frac12\|y-Xw\|^2+\lambda\|w\|_1, X⊤X=IX^\top X=I, tọa độ zj=(X⊤y)j=−2.5z_j=(X^\top y)_j=-2.5 và λ=1\lambda=1. Hệ số tối ưu bằng bao nhiêu?

Câu 4

Trên cùng một bộ dữ liệu, ta học hai mô hình hồi quy tuyến tính với cùng mức phạt λ>0\lambda > 0. Mô hình A phạt L1, mô hình B phạt L2. Điều gì nhiều khả năng xảy ra nhất?

Đề thiUSA-NA-AIO 2026 · Vòng 1 · Part 1.2

Câu 5

Một bộ dữ liệu y khoa có 50 bệnh nhân, mỗi người đo 100 chỉ số. Một mô hình phân loại tuyến tính đúng 98% trên train, tức 49/50, nhưng chỉ đúng 62% trên validation, và gần như mọi trọng số đều khác 0. Đâu là chẩn đoán đúng nhất?

Đề thiNOAI 2026 Singapore · Vòng sơ loại · Câu 269

Câu 6

Hai feature gần như trùng nhau. Linear regression thường cho hai hệ số kiểu +500+500 và −499-499. Ridge thì thường cho kết quả nào?

Câu 7

Một bạn học Ridge, thử λ\lambda = 0.01, 0.1, 1, 10, so lỗi trên train, validation và test, rồi chọn λ=0.01\lambda = 0.01 vì lỗi test thấp nhất. Thấy lỗi test tăng dần từ λ=0.01\lambda = 0.01 đến 10, bạn ấy định thử thêm λ\lambda = 0.0001 và 0.001 để tìm mô hình tốt hơn. Nhận xét nào đúng nhất?

Phỏng theoCMU 10-601 · Practice Problems, Exam 2 · Q3.3

Câu 8

Ta dùng hàm mất mát 12∑ri2+λ∥w∥1\tfrac12\sum r_i^2 + \lambda\lVert\mathbf{w}\rVert_1 với n=40n = 40 mẫu và λ=8\lambda = 8. Muốn Lasso của scikit-learn cho cùng kết quả, phải đặt alpha bằng bao nhiêu?

Câu 9

Một đội đã giải nhiều bài cùng dạng và thấy trọng số tốt nhất thường nằm gần w0=(1,1,…,1)\mathbf{w}_0 = (1, 1, \dots, 1). Bài mới chỉ có rất ít dữ liệu. Hàm mục tiêu nào tận dụng kinh nghiệm ấy hợp lý nhất?

Phỏng theoMIT 6.036 · Final, Spring 2022 · Q4(e)

Câu 10

Khi nào nên chọn Elastic Net thay cho Lasso?

Đọc thêm