Giới thiệu
Trong quá trình phát triển mô hình máy học, việc lựa chọn feature (tính năng) là một trong những bước quan trọng nhất. Thông thường, nhiều người sử dụng phương pháp "SelectFromModel" trong Scikit-learn mà không biết rằng có thể còn nhiều cách tiếp cận hiệu quả hơn. Trong bài viết này, chúng ta sẽ cùng nhau khám phá quy trình lựa chọn feature và kiểm nghiệm hiệu quả của nó.
Quy Trình Lựa Chọn Feature
Để thực hiện lựa chọn feature, chúng ta thường làm theo các bước sau:
- Chọn Mô Hình Dự Đoán: Chọn mô hình phù hợp, chẳng hạn như
WhatevBoost
. - Fit Model: Huấn luyện mô hình với tất cả các feature.
- Trích Xuất Feature Quan Trọng: Lấy các feature có độ quan trọng cao từ mô hình đã huấn luyện.
- Loại Bỏ Feature Thấp: Loại bỏ những feature có độ quan trọng thấp hơn ngưỡng đã đặt và giữ lại những feature còn lại.
Điều này nghe có vẻ hợp lý, nhưng sự thật có thể sẽ khiến bạn ngạc nhiên.
Mô Phỏng Dữ Liệu
Chúng ta sẽ tiến hành sử dụng dữ liệu mô phỏng để kiểm tra phương pháp chọn lựa feature. Chúng ta sẽ tạo một tập dữ liệu gồm 16 feature, trong đó có 6 feature liên quan đến biến mục tiêu y
và 10 feature còn lại là nhiễu (noise).
Dưới đây là danh sách các feature:
'linear'
(1)'nonlinear_square'
(2)'nonlinear_sin'
(3)'interaction_1'
(4)'interaction_2'
(5)'interaction_3'
(6)'noise_1'
(7)'noise_2'
(8)'noise_3'
(9)'noise_4'
(10)'noise_5'
(11)'noise_6'
(12)'noise_7'
(13)'noise_8'
(14)'noise_9'
(15)'noise_10'
(16)
Hàm Tính Toán Biến Mục Tiêu y
Hàm mà chúng ta sử dụng để tính toán biến mục tiêu y
có dạng phức tạp, bao gồm các tương tác và mối quan hệ phi tuyến tính giữa các feature. Dưới đây là cách chúng ta xây dựng hàm này:
python
import numpy as np
def X2y(X, with_error=True):
y_star = X['linear'] + X['nonlinear_square'] ** 2 + np.sin(3 * X['nonlinear_sin']) + (X['interaction_1'] * X['interaction_2'] * X['interaction_3'])
if with_error:
np.random.seed(0)
epsilon = np.random.normal(0, .1, len(y_star))
return y_star + epsilon
return y_star
Tạo Tập Dữ Liệu
Tiếp theo, chúng ta sẽ tạo tập dữ liệu X
và y
, sau đó chia nó thành tập huấn luyện và tập kiểm tra:
python
import pandas as pd
from sklearn.model_selection import train_test_split
np.random.seed(0)
X = pd.DataFrame(np.random.normal(size=(20000, len(feature_names))), columns=feature_names)
y = X2y(X, with_error=True)
X_trn, X_tst, y_trn, y_tst = train_test_split(X, y, test_size=0.5, random_state=0)
Sử Dụng SelectFromModel
Khi đã có dữ liệu, chúng ta sẽ thử nghiệm với một số mô hình dự đoán. Dưới đây là danh sách 8 mô hình mà chúng ta sẽ sử dụng:
DummyRegressor
LinearRegression
KNeighborsRegressor
SupportVectorRegressor
RandomForestRegressor
XGBRegressor
LGBMRegressor
UnbeatableRegressor
Khám Phá Mô Hình Hoàn Hảo
UnbeatableRegressor
là một mô hình lý tưởng, áp dụng công thức đúng cho hàm y
mà chúng ta đã xây dựng. Đây sẽ là chỉ số tham khảo cho hiệu suất của các mô hình khác.
python
class UnbeatableRegressor():
def __init__(self):
pass
def fit(self, X, y):
pass
def predict(self, X):
return np.array(X2y(X, with_error=False))
def score(self, X, y):
return mean_absolute_error(y, self.predict(X))
Đánh Giá Hiệu Suất Các Mô Hình
Bằng cách chạy từng mô hình và đánh giá lỗi tuyệt đối trung bình (MAE), chúng ta có thể so sánh hiệu suất các mô hình:
python
from sklearn.metrics import mean_absolute_error
from eli5.sklearn import PermutationImportance
mae = pd.DataFrame(columns=['train', 'test'])
fi = pd.DataFrame(columns=feature_names)
for model_name in list(models.keys()):
models[model_name].fit(X_trn, y_trn)
mae.loc[model_name,:] = [mean_absolute_error(y_trn, models[model_name].predict(X_trn)), mean_absolute_error(y_tst, models[model_name].predict(X_tst))]
try:
feature_importances_ = models[model_name].feature_importances_
except:
feature_importances_ = PermutationImportance(models[model_name], cv='prefit', n_iter=3).fit(X_trn, y_trn).feature_importances_
fi.loc[model_name, :] = feature_importances_ / feature_importances_.sum()
fi.fillna(0, inplace=True)
Kết quả cho thấy rằng mô hình như XGBoost
và LightGBM
có hiệu suất tốt hơn nhưng vẫn chưa đạt đến ngưỡng lý tưởng của UnbeatableRegressor
.
Thêm Về Tầm Quan Trọng Của Feature
Trong học máy, việc đánh giá tầm quan trọng của feature còn khá khó khăn. Feature có tầm quan trọng 0% không có ảnh hưởng đến dự đoán và có thể loại bỏ, trong khi feature có tầm quan trọng 100% là duy nhất ảnh hưởng đến dự đoán. Với dữ liệu của chúng ta, kỳ vọng là 10 feature nhiễu có tầm quan trọng bằng 0, trong khi 6 feature có ý nghĩa chia sẻ độ quan trọng với nhau.
Chúng ta quy định ngưỡng tầm quan trọng là 1% để giữ những feature có tầm quan trọng đủ cao.
Sử Dụng Thuật Toán Boruta
Boruta là một công cụ mạnh mẽ cho việc lựa chọn feature. Được phát triển vào năm 2010, Boruta sử dụng mô hình Random Forest để xác định mức độ quan trọng của từng feature,
python
!pip install Boruta
from boruta import BorutaPy
forest = RandomForestRegressor(n_jobs=-1, max_depth=5)
boruta_selector = BorutaPy(forest, n_estimators='auto', random_state=0)
boruta_selector.fit(np.array(X_trn), np.array(y_trn))
boruta_ranking = boruta_selector.ranking_
selected_features = np.array(feature_names)[boruta_ranking <= 2]
Từ đầu ra Boruta, chúng ta có thể phân loại các feature thành ba nhóm: Confirmed (được xác nhận), Tentative (tạm thời), và Rejected (bị từ chối). Điều này giúp chúng ta bảo toàn các feature có ý nghĩa và loại bỏ nhiễu.
Kết Luận
Bài viết này đã chứng minh rằng ngay cả những mô hình phức tạp như XGBoost
hoặc LightGBM
có thể không phải là lựa chọn tốt nhất cho việc lựa chọn feature. Thay vào đó, thuật toán Boruta đã chứng minh được hiệu quả vượt trội trong việc xác định feature quan trọng. Nếu bạn muốn tìm hiểu sâu hơn về cách Boruta hoạt động, hãy theo dõi các bài viết tiếp theo của chúng tôi!
source: viblo