2.2.2. Hồi qui Ridge¶
2.2.2.1. Tính tổng quát của mô hình¶
Một mục tiêu tiên quyết để có thể áp dụng được mô hình vào thực tiến đó là chúng ta cần giảm thiểu hiện tượng quá khớp. Để thực hiện được mục tiêu đó, mô hình được huấn luyện được kì vọng sẽ nắm bắt được qui luật tổng quát từ tập huấn luyện (train dataset) mà qui luật đó phải đúng trên những dữ liệu mới mà nó chưa được học. Thông thường tập dữ liệu mới đó được gọi là tập kiểm tra (test dataset). Đây là một tập dữ liệu độc lập được sử dụng để đánh giá mô hình.
2.2.2.2. Bài toán hồi qui tuyến tính¶
Giả định dữ liệu đầu vào bao gồm \(N\) quan sát là những cặp các biến đầu vào và biến mục tiêu \((\mathbf{x}_1, y_1), (\mathbf{x}_2, y_2), \dots, (\mathbf{x}_N, y_N)\). Quá trình hồi qui mô hình sẽ tìm kiếm một véc tơ hệ số ước lượng \(\mathbf{w} = [w_0, w_1, \dots, w_p]\) sao cho tối thiểu hoá hàm mất mát dạng MSE:
Nhắc lại một chút về khái niệm hàm mất mát. Trong các mô hình học có giám sát của machine learning, từ dữ liệu đầu vào, thông qua phương pháp học tập (learning algorithm), chúng ta sẽ đặt ra một hàm giả thuyết \(h\) (hypothesis function) mô tả mối quan hệ dữ liệu giữa biến đầu vào và biến mục tiêu.
Hình 1: Source: Andrew Ng - Linear Regression With One Variable. Từ một quan sát đầu vào \(\mathbf{x}_i\), sau khi đưa vào hàm gỉa thuyết \(h\) chúng ta thu được giá trị dự báo \(\hat{y}\) ở đầu ra. Chữ \(h\) của tên hàm thể hiện cho từ hypothesis có nghĩa là giả thuyết, đây là một khái niệm đã tồn tại lâu năm trong thống kê. Để mô hình càng chuẩn xác thì sai số giữa giá trị dự báo \(\hat{y}\) và ground truth \(y\) càng phải nhỏ. Vậy làm thế nào để đo lường được mức độ nhỏ của sai số giữa \(\hat{y}\) và \(y\)? Các thuật toán học có giám sát trong machine learning sẽ sử dụng hàm mất mát để lượng hoá sai số này.
Hàm mất mát cũng chính là mục tiêu tối ưu khi huấn luyện mô hình. Dữ liệu đầu vào \(\mathbf{X}\) và \(y\) được xem như là cố định và biến số của bài toán tối ưu chính là các giá trị trong véc tơ \(\mathbf{w}\).
Giá trị hàm mất mát MSE chính là trung bình của tổng bình phương phần dư. Phần dư chính là chênh lệch giữa giá trị thực tế và giá trị dự báo. Tối thiểu hoá hàm mất mát nhằm mục đích làm cho giá trị dự báo ít chênh lệch so với giá trị thực tế, giá trị thực tế còn được gọi là ground truth. Trước khi huấn luyện mô hình chúng ta chưa thực sự biết véc tơ hệ số \(\mathbf{w}\) là gì. Chúng ta chỉ có thể đặt ra một giả thuyết về dạng hàm dự báo (trong trường hợp này là phương trình dạng tuyến tính) và các hệ số hồi qui tương ứng. Chính vì vậy mục đích của tối thiểu hoá hàm mất mát là để tìm ra tham số \(\mathbf{w}\) phù hợp nhất mô tả một cách khái quát quan hệ dữ liệu giữa biến đầu vào \(\mathbf{X}\) với biến mục tiêu \(\mathbf{y}\) trên tập huấn luyện.
Tuy nhiên mối quan hệ này nhiều khi không mô tả được qui luật khái quát của dữ liệu nên dẫn tới hiện tượng quá khớp. Một trong những nguyên nhân dẫn tới sự không khái quát của mô hình đó là do mô hình quá phức tạp. Mức độ phức tạp càng cao khi độ lớn của các hệ số trong mô hình hồi qui ở những bậc cao có xu hướng lớn như phân tích trong hình bên dưới:
Hình 2: Hình thể hiện mức độ phức tạp của mô hình theo sự thay đổi của bậc. Phương trình có độ phức tạp lớn nhất là phương trình bậc 3: \(y = w_0 + w_1 x + w_2 x^2 + w_3 x^3\). Trong chương trình THPT chúng ta biết rằng phương trình bậc 3 thông thường sẽ có 2 điểm uốn và độ phức tạp lớn hơn bậc hai chỉ có 1 điểm uốn. Khi \(w_3 \rightarrow 0\) thì phương trình bậc 3 hội tụ về phương trình bậc 2: \(y = w_0 + w_1 x + w_2 x^2\), lúc này phương trình là một đường cong dạng parbol và có độ phức tạp giảm. Tiếp tục kiểm soát độ lớn để \(w_2 \rightarrow 0\) trong phương trình bậc 2 ta sẽ thu được một đường thẳng tuyến tính dạng \(y = w_0 + w_1 x\) có độ phức tạp thấp nhất.
Như vậy kiểm soát độ lớn của hệ số ước lượng, đặc biệt là với bậc cao, sẽ giúp giảm bớt mức độ phức tạp của mô hình và thông qua đó khắc phục hiện tượng quá khớp. Vậy làm cách nào để kiểm soát chúng, cùng tìm hiểu chương bên dưới.
2.2.2.3. Sự thay đổi của hàm mất mát trong hồi qui Ridge¶
Hàm mất mát trong hồi qui Ridge sẽ có sự thay đổi so với hồi qui tuyến tính đó là thành phần điều chuẩn (regularization term) được cộng thêm vào hàm mất mát như sau:
Trong phương trình trên thì \(\alpha \geq 0\). \(\frac{1}{N}||\bar{\mathbf{X}}\mathbf{w} - \mathbf{y}||_{2}^{2}\) chính là tổng bình phương phần dư và \(\alpha ||\mathbf{w}||_2^2\) đại diện cho thành phần điều chuẩn.
Bài toán tối ưu hàm mất mát của hồi qui Ridge về bản chất là tối ưu song song hai thành phần bao gồm tổng bình phương phần dư và thành phần điều chuẩn. Hệ số \(\alpha\) có tác dụng điều chỉnh độ lớn của thành phần điều chuẩn tác động lên hàm mất mát.
Trường hợp \(\alpha = 0\), thành phần điều chuẩn bị tiêu giảm và chúng ta quay trở về bài toán hồi qui tuyến tính.
Trường hợp \(\alpha\) nhỏ thì vai trò của thành phần điều chuẩn trở nên ít quan trọng. Mức độ kiểm soát quá khớp của mô hình sẽ trở nên kém hơn.
Trường hợp \(\alpha\) lớn chúng ta muốn gia tăng mức độ kiểm soát lên độ lớn của các hệ số ước lượng và qua đó giảm bớt hiện tượng qúa khớp.
Khi tăng dần hệ số \(\alpha\) thì hồi qui Ridge sẽ có xu hướng thu hẹp hệ số ước lượng từ mô hình. Chúng ta sẽ thấy rõ thông qua ví dụ mẫu bên dưới.
Import thư viện và đọc dữ liệu đầu vào
Bộ dữ liệu đầu vào được sử dụng cho ví dụ này là diabetes. Thông tin về bộ dữ liệu này bạn đọc có thể tham khảo tại sklearn diabetes dataset.
Mục tiêu của mô hình là từ 10 biến đầu vào là những thông tin liên quan tới người bệnh bao gồm age, sex, body mass index, average blood pressure
và 6 chỉ số blood serum
. Chúng ta sẽ dự báo biến mục tiêu là một thước đo định lượng sự tiến triển của bệnh sau 1 năm điều trị.
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.linear_model import Ridge
from sklearn.datasets import load_diabetes
X,y = load_diabetes(return_X_y=True)
features = load_diabetes()['feature_names']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
import numpy as np
import matplotlib.pyplot as plt
# Thay đổi alphas từ 1 --> 100
n_alphas = 200
alphas = 1/np.logspace(1, -2, n_alphas)
coefs = []
# Huấn luyện model khi alpha thay đổi.
for a in alphas:
ridge = Ridge(alpha=a, fit_intercept=False)
ridge.fit(X_train, y_train)
coefs.append(ridge.coef_)
# Hiển thị kết quả mô hình cho các hệ số alpha
plt.figure(figsize= (12, 8))
ax = plt.gca()
ax.plot(alphas, coefs)
ax.set_xscale('log')
ax.set_xlim(ax.get_xlim())
plt.xlabel('alpha', fontsize=16)
plt.ylabel('coefficient of features', fontsize=16)
plt.legend(features)
plt.title('Ridge coefficients khi thay đổi hệ số alpha', fontsize=16)
plt.axis('tight')
plt.show()
Hình 3: Sự thay đổi của độ lớn các hệ số ước lượng (coefficient of features) theo hệ số điều chuẩn \(\alpha\). Khi tăng dần độ lớn của \(\alpha\) thì độ lớn của hệ số ước lượng giảm dần.
Việc lựa chọn \(\alpha\) như thế nào để phù hợp là một vấn đề sẽ được bàn luận kĩ hơn ở chương bên dưới.
Ngoài ra bài toán tối ưu đối với hàm hồi qui Ridge tương đương với bài toán tối ưu với điều kiện ràng buộc về độ lớn của hàm mục tiêu:
Thật vậy, để giải bài toán trên thì chúng ta có thể giải bài toán đối ngẫu trên hàm đối ngẫu Lagrange:
Trong đó \(\alpha > 0\).
Như vậy bài toán đối ngẫu quay trở về tối thiểu hoá hàm mất mát trong hồi qui Ridge.
Điều kiện ràng buộc \(\| \mathbf{w} \|_2^2 < C\) cho thấy nghiệm tối ưu sẽ bị hạn chế về độ lớn. Trong không gian đa chiều thì điều kiện ràng buộc có miền xác định là một khối cầu có tâm là gốc toạ độ và bán kính \(\sqrt{C}\). Đây chính là một cơ chế kiểm soát mà thành phần điều chuẩn đã áp đặt lên các biến đầu vào.
2.2.2.4. Nghiệm tối ưu của hồi qui Ridge¶
Giải bài toán tối ưu hàm mục tiêu của hồi qui Ridge theo đạo hàm bậc nhất của véc tơ \(\mathbf{w}\):
Thật vậy, từ dòng 1 suy ra dòng 2 là vì theo công thức product-rule trong matrix caculus thì:
Khi \(f=g\) thì đạo hàm trở thành:
Nếu thay \(f(\mathbf{w}) = g(\mathbf{w})= \bar{\mathbf{X}} \mathbf{w}-\mathbf{y}\) ta suy ra:
Tương tự ta cũng có:
Như vậy ta nhận thấy dòng 1 suy ra dòng 2 là hoàn toàn đúng.
Ở dòng thứ 3 chúng ta áp dụng thêm một tính chất \(\mathbf{I}\mathbf{w} = \mathbf{w}\) trong đó \(\mathbf{I}\) là ma trận đơn vị.
Sau cùng nghiệm của đạo hàm bậc nhất trở thành:
Thành phần \(N\alpha \mathbf{I}\) được thêm vào trong \((\mathbf{\bar{X}}^{\intercal}\mathbf{\bar{X}} + N\alpha \mathbf{I})^{-1}\) đóng vai trò như một thành phần kiểm soát để giá trị của \(\mathbf{w}\) nhỏ hơn so với ban đầu. Trên thực tế thành phần này chỉ tác động lên những phần tử thuộc đường chéo chính của ma trận và làm cho độ lớn của nghiệm giảm.
Ngoài ra ta còn chứng minh được rằng ma trận \(\mathbf{\bar{X}}^{\intercal}\mathbf{\bar{X}} + N\alpha \mathbf{I}\) là một ma trận không suy biến nếu \(\alpha > 0\). Điều đó đảm bảo rằng mô hình hồi qui Ridge luôn tìm được nghiệm. Bạn đọc quan tâm tới toán có thể thấy chứng minh này ở mục bên dưới.
2.2.2.5. Sự đảm bảo lời giải của hồi qui Ridge¶
Trước tiên hãy cùng ôn lại một số khái niệm liên quan tới ma trận.
Định nghĩa bán xác định dương: Ma trận số thực đối xứng \(\mathbf{A}\) là bán xác định dương (positive semi-definite) nếu với mọi véc tơ \(\mathbf{x} \in \mathbb{R}^{d}\) thì \(\mathbf{x}^{\intercal}\mathbf{A}\mathbf{x} \geq 0\).
Một tính chất thú vị đó là nếu một ma trận bán xác định dương thì mọi trị riêng của chúng là những số không âm. Thật vậy, theo định nghĩa thì \(\lambda\) là trị riêng (eigen-value) của ma trận \(\mathbf{A}\) tương ứng với một véc tơ riêng (eigen-vector) \(\mathbf{x}\) nếu thỏa mãn:
Mặc khác vế trái không âm do \(\mathbf{A}\) là ma trận bán xác định dương. Do đó vế phải \(\lambda ||\mathbf{x}||_2^2 \geq 0\), từ đó suy ra \(\lambda \geq 0\) do \(||\mathbf{x}||_2^2 \geq 0\).
Để chứng minh hồi qui Ridge luôn tồn tại nghiệm chúng ta dựa vào ba tính chất lý.
1.- Ma trận \(\mathbf{A} = \bar{\mathbf{X}}^{\intercal}\bar{\mathbf{X}}\) là một ma trận thực đối xứng bán xác định dương (positive semi-definite). Thật vậy:
Từ đó suy ra \(\mathbf{A}\) là ma trận bán xác định dương. Như vậy các trị riêng (eigenvalues) của nó là \(\mu_1, \dots, \mu_N\) không âm.
2.- Nếu \(\mu\) là trị riêng của ma trận \(\mathbf{A}\) vuông thì \(\mu+\beta\) là trị riêng của ma trận \(\mathbf{A}+\beta\mathbf{I}\).
Để chứng minh ta dựa vào khai triển:
Dòng cuối cùng suy ra \(\mu+\beta\) chính là trị riêng của ma trận \(\mathbf{A} + \beta \mathbf{I}\).
3.- Định thức của ma trận \(\mathbf{A}\) bằng tích các trị riêng của \(\mathbf{A}\).
Giả sử \(\lambda_1, \dots, \lambda_d\) là các trị riêng của ma trận \(\mathbf{A}\). Khi đó định thức:
là một đa thức bậc \(d\) của \(\lambda\).
Mặc khác với mỗi trị riêng \(\lambda_i\) của ma trận \(\mathbf{A}\) thì tồn tại véc tơ riêng \(\mathbf{x}\) khác 0 thỏa mãn:
Như vậy các dòng của ma trận \(\mathbf{A}-\lambda_i \mathbf{I}\) phụ thuộc tuyến tính theo véc tơ \(\mathbf{x}\) nên \(P_d(\lambda_i) = \det(\mathbf{A} - \lambda_i \mathbf{I}) = 0\). Từ đó suy ra \(P_d(\lambda)\) có \(d\) nghiệm là các trị riêng của ma trận \(\mathbf{A}\). Kết hợp với hệ số của bậc cao nhất \(\lambda^d\) là \((-1)^d\) ta suy ra:
Do đó:
Quay trở lại bài toán chứng minh \((\mathbf{\bar{X}}^{\intercal}\mathbf{\bar{X}} + N\alpha \mathbf{I})\) là một ma trận không suy biến.
Giả định \(\mu\) là véc tơ trị riêng của ma trận \(\mathbf{\bar{X}}^{\intercal}\mathbf{\bar{X}}\). Như vậy từ tính chất 2 suy ra trị riêng của ma trận \(\mathbf{\bar{X}}^{\intercal}\mathbf{\bar{X}} + N\alpha \mathbf{I}\) là \(\lambda = \mu + N\alpha\).
Mặt khác theo tính chất 1 thì \(\mu \geq 0\) do \(\bar{\mathbf{X}}^{\intercal}\bar{\mathbf{X}}\) bán xác định dương. Từ đó suy ra \(\lambda \geq N\alpha > 0\). Như vậy ma trận \((\mathbf{\bar{X}}^{\intercal}\mathbf{\bar{X}} + N\alpha \mathbf{I})\) có khác trị riêng khác 0. Theo tính chất 3 ta suy ra \(\det{(\mathbf{A})} \neq 0\) do các trị riêng đều khác 0. Như vậy \((\mathbf{\bar{X}}^{\intercal}\mathbf{\bar{X}} + N\alpha \mathbf{I})\) là một ma trận không suy biến và hồi qui Ridge đảm bảo tồn tại nghiệm.
2.2.2.6. Huấn luyện hồi qui Ridge¶
Để huấn luyện mô hình hồi qui Ridge trên sklearn chúng ta sử dụng module sklearn.linear_model.Ridge
như bên dưới. Đối số cần lưu ý chính là alpha
tương ứng với hệ số \(\alpha\) của thành phần điều chuẩn.
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.linear_model import Ridge
reg_ridge = Ridge(alpha = 1.0)
reg_ridge.fit(X_train, y_train)
# Sai số huấn luyện của mô hình trên tập train
print(reg_ridge.score(X_train, y_train))
# Hệ số hồi qui và hệ số chặn
print(reg_ridge.coef_)
print(reg_ridge.intercept_)
0.4062765748571143
[ 40.22939469 -61.6891284 273.28923195 197.33160511 -1.61665406
-19.12583524 -142.98129661 107.3757613 195.22498998 84.3326197 ]
150.9272009480016
Tối ưu hệ số \(\alpha\) như thế nào sẽ được bàn luận ở chương 2.2.6.
2.2.2.7. Điều chuẩn Tikhokov¶
Khi xây dựng mô hình trên những bộ dữ liệu có số lượng lớn các biến đầu vào thì thường xuất hiện hiện tượng đa cộng tuyến khiến ước lượng từ mô hình bị chệch. Chúng ta có thể khắc phục hiện tượng này thông qua áp dụng thành phần điều chuẩn Tikhonov:
Trong đó \(\Gamma\) là một ma trận vuông, thông thường được lựa chọn là một ma trận đường chéo.
Nếu giải bài toán tối ưu theo đạo hàm bậc nhất thì ta thu được nghiệm khi sử dụng điều chuẩn Tikhokov:
Nghiệm tối ưu:
Nếu tính tế chúng ta sẽ nhận thấy hồi qui Ridge chính là một trường hợp đặc biểu của điều chuẩn Tikhokov khi lựa chọn \(\Gamma = \alpha\mathbf{I}\) trong đó \(\mathbf{I}\) là ma trận đơn vị.
Trong mô hình hồi qui không phải khi nào thì vai trò của các biến đầu vào cũng đều quan trọng như nhau. Khi lựa chọn \(\Gamma\) là một ma trận đường chéo chúng ta thu được một phiên bản weighted l2 regularization. Độ lớn của các phần tử trên đường chéo sẽ ảnh hưởng tới mức độ kiểm soát được áp đặt lên biến. Nếu biến đầu vào \(w_i\) là nguyên nhân dẫn tới hiện tượng overfitting thì có thể thiết lập \(\alpha_i\) một giá trị lớn hơn so với những thành phần khác nằm trên đường chéo chính. Ngoài ra trong những phương trình hồi qui sử dụng đặc trưng đa thức (polynomial feature) thì chúng ta thường sẽ gán giá trị cao hơn cho trọng số của những biến bậc cao trong thành phần điều chuẩn để giảm thiểu quá khớp.
2.2.3. Hồi qui Lasso¶
2.2.3.1. Bài toán hồi qui Lasso¶
Trong hồi qui Lasso, thay vì sử dụng thành phần điều chuẩn là norm chuẩn bậc hai thì chúng ta sử dụng norm chuẩn bậc 1.
Nếu bạn chưa biết về norm chuẩn bậc 1 thì có thể xem lại khái niệm norm chuẩn.
Khi tiến hành hồi qui mô hình Lasso trên một bộ dữ liệu mà có các biến đầu vào đa cộng tuyến (multicollinear) thì mô hình hồi qui Lasso sẽ có xu hướng lựa chọn ra một biến trong nhóm các biến đa cộng tuyến và bỏ qua những biến còn lại. Trong khi ở mô hình hồi qui tuyến tính thông thường và hồi qui Ridge thì có xu hướng sử dụng tất cả các biến đầu vào. Điều này sẽ được làm rõ hơn ở mục 2.2.4.
Bài toán tối ưu đối với hàm hồi qui Lasso tương đương với bài toán tối ưu với điều kiện ràng buộc về độ lớn của hàm mục tiêu:
Thành phần điều chuẩn norm bậc 1 cũng có tác dụng như một sự kiểm soát áp đặt lên hệ số ước lượng. Khi muốn gia tăng sự kiểm soát, chúng ta sẽ gia tăng hệ số \(\alpha\) để mô hình trở nên bớt phức tạp hơn. Cũng tương tự như hồi qui Ridge chúng ta cùng phân tích tác động của \(\alpha\):
Trường hợp \(\alpha = 0\), thành phần điều chuẩn bị tiêu giảm và chúng ta quay trở về bài toán hồi qui tuyến tính.
Trường hợp \(\alpha\) nhỏ thì vai trò của thành phần điều chuẩn trở nên ít quan trọng. Mức độ kiểm soát quá khớp của mô hình sẽ trở nên kém hơn.
Trường hợp \(\alpha\) lớn chúng ta muốn gia tăng mức độ kiểm soát lên độ lớn của các hệ số ước lượng.
2.2.3.2. Huấn luyện mô hình Lasso¶
Để huấn luyện mô hình hồi qui Lasso trên sklearn chúng ta sử dụng module sklearn.linear_model.Lasso
. Chúng ta cần quan tâm tới thiết lập hệ số nhân \(\alpha\) của thành phần điều chuẩn.
from sklearn.linear_model import Lasso
reg_lasso = Lasso(alpha = 1.0)
reg_lasso.fit(X_train, y_train)
# Sai số huấn luyện trên tập train
print(reg_lasso.score(X_train, y_train))
# Hệ số hồi qui và hệ số chặn
print(reg_lasso.coef_)
print(reg_lasso.intercept_)
0.34247555718513434
[ 0. -0. 425.89461957 69.18843585 0.
0. -0. 0. 177.77583411 0. ]
150.97739174702443
Nếu muốn tuning hệ số \(\alpha\) phù hợp nhất cho mô hình hồi qui Lasso, sklearn cung cấp một module hỗ trợ ta làm công việc này. Đó chính là sklearn.linear_model.LassoCV
from sklearn.linear_model import LassoCV
from sklearn.datasets import make_regression
X, y = make_regression(noise=4, random_state=0)
reg_lasso_cv = LassoCV(cv=5, random_state=0).fit(X, y)
print(reg_lasso_cv.coef_)
print(reg_lasso_cv.intercept_)
[-4.21242132e-01 -0.00000000e+00 8.74020196e+00 0.00000000e+00
-0.00000000e+00 0.00000000e+00 5.04074761e-02 7.46065852e+00
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
-0.00000000e+00 -1.72366886e-01 0.00000000e+00 -0.00000000e+00
-0.00000000e+00 0.00000000e+00 -0.00000000e+00 -4.29663159e-01
1.43615035e-01 0.00000000e+00 -1.79948525e-01 0.00000000e+00
-0.00000000e+00 7.30847374e+01 -3.43884703e-01 0.00000000e+00
0.00000000e+00 0.00000000e+00 1.13286030e-01 -0.00000000e+00
0.00000000e+00 -0.00000000e+00 0.00000000e+00 -0.00000000e+00
-0.00000000e+00 0.00000000e+00 0.00000000e+00 -0.00000000e+00
-0.00000000e+00 3.94405369e+01 -0.00000000e+00 -0.00000000e+00
5.23718682e+01 8.32674366e-01 4.35584487e+01 -0.00000000e+00
0.00000000e+00 1.55124290e-01 2.58648431e-01 -0.00000000e+00
0.00000000e+00 0.00000000e+00 -0.00000000e+00 0.00000000e+00
3.22013861e+01 0.00000000e+00 -0.00000000e+00 -0.00000000e+00
-0.00000000e+00 1.55887672e-01 6.21088556e+01 0.00000000e+00
0.00000000e+00 -0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 -3.97202098e-01 -0.00000000e+00 -0.00000000e+00
-0.00000000e+00 -1.67818199e-02 0.00000000e+00 -0.00000000e+00
0.00000000e+00 5.24373378e-01 -0.00000000e+00 0.00000000e+00
-0.00000000e+00 8.74408670e-02 -0.00000000e+00 0.00000000e+00
6.87409944e+01 -0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00 0.00000000e+00 -0.00000000e+00 -0.00000000e+00
-0.00000000e+00 -0.00000000e+00 0.00000000e+00 1.14377992e-01
-2.37058452e-01 1.28608607e+01 0.00000000e+00 -0.00000000e+00]
0.37606756329527613
Để ý thấy rằng trong hồi qui Lasso thì véc tơ hệ số ước lượng là một véc tơ thưa (sparse vector). Tức là trong các thành phần của nó có số lượng biến khác 0 lớn. Chính nhờ việc giữ lại những biến quan trọng và loại bỏ ảnh hưởng của những biến không quan trọng thông qua triệt tiêu hệ số ước lượng về 0 mà hồi qui Lasso còn là một kĩ thuật quan trọng để lựa chọn biến (feature selection).
2.2.4. Vì sao hồi qui Lasso lại là hồi qui lựa chọn biến¶
Như vậy chúng ta đã tìm hiểu sơ lược về hồi qui Ridge và hồi qui Lasso. Bây giờ chúng ta sẽ tìm cách giải thích tại sao hồi qui Lasso có thể trả về kết quả là một véc tơ thưa trong khi hồi qui Ridge chỉ tìm cách giảm các hệ số của mô hình chứ không hoàn toàn tiến về 0. Một mô tả được thể hiện thông qua hình bên dưới sẽ giúp ta hiểu rõ hơn.
Giả định rằng tập huấn luyện của chúng ta chỉ có hai đặc trưng. Hình bên dưới sẽ biểu diễn hàm mục tiêu và miền xác định của hai mô hình hồi qui Ridge và Lasso trong không gian hai chiều.
Source: Ridge and Lasso Regression
Hình 4: Miền xác định của hồi qui Lasso là \(|\beta_1|+|\beta_2| \leq t\), trên đồ thị thì miền xác định này là một vùng hình thoi màu xám nằm bên trái. Hình bên phải là hồi qui Ridge có miền xác định được thể hiện bởi một hình tròn màu vàng \(\beta_1^2 + \beta_2^2 \leq C\). Đồ thị của hàm mục tiêu \(\mathcal{L}(\mathbf{w})\) được thể hiện qua một tập hợp các đường đồng mức hình ellipse. Mỗi một đường đồng mức sẽ trả về cùng một giá trị hàm mục tiêu. Các đường đồng mức ở gần tâm \(\hat{\beta}\) thì càng có giá trị nhỏ hơn. Khi mở rộng dần đường đồng mức cho tới khi tiệm cận miền xác định chúng ta sẽ thu được nghiệm của bài toán.
Đối với hồi qui Lasso thì thông thường điểm tiếp xúc giữa đường đồng mức của hàm mục tiêu và tập nghiệm thường chạm đỉnh của hình thoi. Đây là những điểm tương ứng với một chiều bằng 0. Trong khi đó, trong hồi qui Ridge thì miền xác định là một hình tròn nên tiểm tiếp xúc sẽ thường có toạ độ khác 0.
2.2.5. Elastic Net¶
Hồi qui Elastic Net là một mô hình hồi qui cho phép chúng ta kết hợp đồng thời cả hai thành phần điều chuẩn là norm chuẩn bậc 1 và norm chuẩn bậc 2 theo một kết hợp tuyến tính lồi.
Trong phương trình trên thì \(\alpha\) chính là hệ số nhân của thành phần điều chuẩn. \(\lambda\) chính là hệ số nhân của norm chuẩn bậc 1 trong thành phần điều chuẩn. Giá trị của \(0 \leq \lambda \leq 1\), nếu như \(\lambda = 0\) thì thành phần điều chuẩn hoàn toàn trở thành norm chuẩn bậc 2 và với \(\lambda = 1\) thì bài toán trở thành chuẩn bậc 1. Không có một qui ước cụ thể cho sự lựa chọn tối ưu giữa \(\alpha\) và \(\lambda\) mà chúng ta chỉ có thể đánh giá thông qua tuning.
Để huấn luyện hồi qui Elastic Net trong sklearn chúng ta có thể sử dụng from sklearn.linear_model.ElasticNet
. Các hệ số \(\alpha\) và \(\lambda\) lần lượt tương ứng với alpha
và l1_ratio
bên dưới:
from sklearn.linear_model import ElasticNet
from sklearn.datasets import make_regression
regr = ElasticNet(alpha = 1.0, l1_ratio=0.5, random_state=0)
regr.fit(X_train, y_train)
print(regr.coef_)
print(regr.intercept_)
[ 0.23525939 0. 3.36451151 2.31509402 0.24049305 0.0182577
-1.8341374 1.96160287 2.73396095 1.47473885]
151.96891766544942
Khi huấn luyện mô hình hồi qui Elastic Net thì làm sao để lựa chọn được cặp hệ số \((\alpha_1, \alpha_2)\) phù hợp? Chúng ta sẽ cùng tìm hiểu về cách thức tuning hệ số \(\alpha\) bên dưới.
2.2.6. Tuning hệ số cho mô hình hồi qui Ridge, Lasso và Elastic Net¶
Để tìm ra hệ số \(\alpha\) phù hợp nhất ứng với thành phần điều chuẩn thì chúng ta sẽ thực hiện grid search trên không gian tham số \(\alpha\). Tiêu chuẩn lựa chọn mô hình sẽ là metric của sai số được đo lường trên tập kiểm tra là nhỏ nhất, thông thường metric này được lựa chọn là MSE. Đồng thời chúng ta cũng cần đối chiếu sai số trên tập kiểm tra với tập huấn luyện để phòng tránh hiện tượng quá khớp.
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import PredefinedSplit
from sklearn.model_selection import train_test_split, KFold
from sklearn.linear_model import Lasso
from sklearn.datasets import load_diabetes
X,y = load_diabetes(return_X_y=True)
features = load_diabetes()['feature_names']
idx = np.arange(X.shape[0])
X_train, X_test, y_train, y_test, idx_train, idx_test = train_test_split(X, y, idx, test_size=0.33, random_state=42)
# Khởi tạo phân chia tập train/test cho mô hình. Đánh dấu các giá trị thuộc tập train là -1 và tập test là 0
split_index = [-1 if i in idx_train else 0 for i in idx]
ps = PredefinedSplit(test_fold=split_index)
# Khởi tạo pipeline gồm 2 bước, 'scaler' để chuẩn hoá đầu vào và 'model' là bước huấn luyện
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', Lasso())
])
# GridSearch mô hình trên không gian tham số alpha
search = GridSearchCV(pipeline,
{'model__alpha':np.arange(1, 10, 1)}, # Tham số alpha từ 1->10 huấn luyện mô hình
cv = ps, # validation trên tập kiểm tra
scoring="neg_mean_squared_error", # trung bình tổng bình phương phần dư
verbose=3
)
search.fit(X, y)
print(search.best_estimator_)
print('Best core: ', search.best_score_)
Fitting 1 folds for each of 9 candidates, totalling 9 fits
[CV 1/1] END ................model__alpha=1;, score=-2814.224 total time= 0.0s
[CV 1/1] END ................model__alpha=2;, score=-2814.381 total time= 0.0s
[CV 1/1] END ................model__alpha=3;, score=-2833.032 total time= 0.0s
[CV 1/1] END ................model__alpha=4;, score=-2857.475 total time= 0.0s
[CV 1/1] END ................model__alpha=5;, score=-2886.649 total time= 0.0s
[CV 1/1] END ................model__alpha=6;, score=-2923.552 total time= 0.0s
[CV 1/1] END ................model__alpha=7;, score=-2961.456 total time= 0.0s
[CV 1/1] END ................model__alpha=8;, score=-2985.537 total time= 0.0s
[CV 1/1] END ................model__alpha=9;, score=-3014.196 total time= 0.0s
Pipeline(steps=[('scaler', StandardScaler()), ('model', Lasso(alpha=1))])
Best core: -2814.2239327473367
Chúng ta cũng có thể huấn luyện cho nhiều dạng mô hình khác nhau như Ridge, Lasso, ElasticNet
.
Đối với mô hình hồi qui Ridge:
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', Ridge())
])
# GridSearch mô hình trên không gian tham số alpha
search = GridSearchCV(pipeline,
{'model__alpha':np.arange(1,10,1)}, # Tham số alpha từ 1->10 huấn luyện mô hình
cv = ps, # validation trên tập kiểm tra
scoring="neg_mean_squared_error", # trung bình tổng bình phương phần dư
verbose=3
)
search.fit(X, y)
print(search.best_estimator_)
print('Best core: ', search.best_score_)
Fitting 1 folds for each of 9 candidates, totalling 9 fits
[CV 1/1] END ................model__alpha=1;, score=-2823.056 total time= 0.0s
[CV 1/1] END ................model__alpha=2;, score=-2826.215 total time= 0.0s
[CV 1/1] END ................model__alpha=3;, score=-2828.033 total time= 0.0s
[CV 1/1] END ................model__alpha=4;, score=-2828.995 total time= 0.0s
[CV 1/1] END ................model__alpha=5;, score=-2829.393 total time= 0.0s
[CV 1/1] END ................model__alpha=6;, score=-2829.410 total time= 0.0s
[CV 1/1] END ................model__alpha=7;, score=-2829.162 total time= 0.0s
[CV 1/1] END ................model__alpha=8;, score=-2828.727 total time= 0.0s
[CV 1/1] END ................model__alpha=9;, score=-2828.161 total time= 0.0s
Pipeline(steps=[('scaler', StandardScaler()), ('model', Ridge(alpha=1))])
Best core: -2823.0556639233228
Đối với mô hình hồi qui ElasticNet:
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', ElasticNet())
])
# GridSearch mô hình trên không gian tham số alpha
search = GridSearchCV(pipeline,
{
'model__alpha': np.arange(1,10,1), # Tham số alpha
'model__l1_ratio': [0.2, 0.5, 0.8] # Tham số l1_ratio
}, # Tham số alpha từ 1->10 huấn luyện mô hình
cv = ps, # validation trên tập kiểm tra
scoring="neg_mean_squared_error", # trung bình tổng bình phương phần dư
verbose=3
)
search.fit(X, y)
print(search.best_estimator_)
print('Best core: ', search.best_score_)
Fitting 1 folds for each of 27 candidates, totalling 27 fits
[CV 1/1] END model__alpha=1, model__l1_ratio=0.2;, score=-2962.491 total time= 0.0s
[CV 1/1] END model__alpha=1, model__l1_ratio=0.5;, score=-2872.231 total time= 0.0s
[CV 1/1] END model__alpha=1, model__l1_ratio=0.8;, score=-2813.629 total time= 0.0s
[CV 1/1] END model__alpha=2, model__l1_ratio=0.2;, score=-3250.469 total time= 0.0s
[CV 1/1] END model__alpha=2, model__l1_ratio=0.5;, score=-3064.105 total time= 0.0s
[CV 1/1] END model__alpha=2, model__l1_ratio=0.8;, score=-2874.841 total time= 0.0s
[CV 1/1] END model__alpha=3, model__l1_ratio=0.2;, score=-3503.891 total time= 0.0s
[CV 1/1] END model__alpha=3, model__l1_ratio=0.5;, score=-3265.543 total time= 0.0s
[CV 1/1] END model__alpha=3, model__l1_ratio=0.8;, score=-2974.274 total time= 0.0s
[CV 1/1] END model__alpha=4, model__l1_ratio=0.2;, score=-3716.835 total time= 0.0s
[CV 1/1] END model__alpha=4, model__l1_ratio=0.5;, score=-3450.564 total time= 0.0s
[CV 1/1] END model__alpha=4, model__l1_ratio=0.8;, score=-3085.846 total time= 0.0s
[CV 1/1] END model__alpha=5, model__l1_ratio=0.2;, score=-3897.105 total time= 0.0s
[CV 1/1] END model__alpha=5, model__l1_ratio=0.5;, score=-3619.386 total time= 0.0s
[CV 1/1] END model__alpha=5, model__l1_ratio=0.8;, score=-3200.407 total time= 0.0s
[CV 1/1] END model__alpha=6, model__l1_ratio=0.2;, score=-4050.721 total time= 0.0s
[CV 1/1] END model__alpha=6, model__l1_ratio=0.5;, score=-3770.874 total time= 0.0s
[CV 1/1] END model__alpha=6, model__l1_ratio=0.8;, score=-3316.347 total time= 0.0s
[CV 1/1] END model__alpha=7, model__l1_ratio=0.2;, score=-4182.935 total time= 0.0s
[CV 1/1] END model__alpha=7, model__l1_ratio=0.5;, score=-3907.760 total time= 0.0s
[CV 1/1] END model__alpha=7, model__l1_ratio=0.8;, score=-3430.296 total time= 0.0s
[CV 1/1] END model__alpha=8, model__l1_ratio=0.2;, score=-4297.805 total time= 0.0s
[CV 1/1] END model__alpha=8, model__l1_ratio=0.5;, score=-4030.974 total time= 0.0s
[CV 1/1] END model__alpha=8, model__l1_ratio=0.8;, score=-3536.286 total time= 0.0s
[CV 1/1] END model__alpha=9, model__l1_ratio=0.2;, score=-4398.464 total time= 0.0s
[CV 1/1] END model__alpha=9, model__l1_ratio=0.5;, score=-4142.572 total time= 0.0s
[CV 1/1] END model__alpha=9, model__l1_ratio=0.8;, score=-3640.652 total time= 0.0s
Pipeline(steps=[('scaler', StandardScaler()),
('model', ElasticNet(alpha=1, l1_ratio=0.8))])
Best core: -2813.6285948414907
2.2.7. Tổng kết¶
Như vậy qua bài này chúng ta đã được làm quen với lớp các mô hình hồi qui với thành phần điều chuẩn bao gồm Ridge Regression, Lasso
và Elastic Net
. Tổng kết lại bài này chúng ta đã biết được rằng:
Khi huấn luyện mô hình hồi qui trên bộ dữ liệu có nhiều biến đầu vào (dữ liệu cao chiều) và những biến này có sự tương quan lần nhau thì ước lượng từ mô hình hồi qui tuyến tính thường có phương sai cao dẫn tới hiện tượng quá khớp.
Để giảm thiểu hiện tượng quá khớp, thông thường sẽ cộng thêm thành phần điều chuẩn vào mô hình hồi qui.
Có ba kĩ thuật chính để giảm thiểu các hệ số ước lượng từ mô hình hồi qui đó là: Ridge, Lasso và Elastic Net. Trong đó Elastict Net là một kết hợp tuyến tính giữa hồi qui Lasso và Ridge.
Thành phần điều chuẩn của hồi qui Ridge chính là một trường hợp đặc biệt của điều chuẩn Tikhokov.
Hồi qui Ridge thì có thành phần điều chuẩn là \(L_2\) trong khi Lasso sử dụng \(L_1\).
Phương pháp tuning hệ số \(\alpha\) của các thành phần điều chuẩn thông qua cross-validation để tìm ra mô hình phù hợp nhất.
2.2.8. Bài tập¶
Trong hồi qui Ridge chúng ta sẽ kiểm soát hàm mất mát bằng cách nào?
Vì sao hồi qui Ridge luôn đảm bảo tìm được giá trị ước lượng cho bài toán tối ưu.
Theo phương pháp điều chuẩn Tikhokov thì ma trận \(\Gamma\) của thành phần điều chuẩn thường là một ma trận như thế nào?
Nghiệm của hồi qui Lasso có xu hướng là một véc tơ thưa vì sao?
Trong hồi qui Elastic Net thì các thành phần điều chuẩn có dạng như thế nào?
Sử dụng bộ dữ liệu boston’s house price hãy phân chia tập train/test theo tỷ lệ 80:20. Xây dựng mô hình hồi qui hồi qui tuyến tính dự báo giá nhà trên tập train và đánh giá trên tập test.
Mô hình có gặp hiện tượng quá khớp hay không? Tìm cách khắc phục hiện tượng quá khớp bằng cách huấn luyện các mô hình hồi qui Ridge, Lasso, ElasticNet với thành phần điều chuẩn.
Tuning hệ số \(\alpha\) cho từng mô hình để tìm ra mô hình phù hợp nhất trên tập kiểm tra.
2.2.9. Tài liệu tham khảo¶
https://www.datacamp.com/community/tutorials/tutorial-ridge-lasso-elastic-net
https://machinelearningmastery.com/ridge-regression-with-python/
https://towardsdatascience.com/ridge-regression-for-better-usage-2f19b3a202db
http://www.cs.cmu.edu/~ggordon/10725-F12/slides/08-general-gd.pdf