2.2.10. Feature selection#
Để xây dựng mô hình chúng ta sẽ rất cần đến dữ liệu lớn. Nhưng dữ liệu quá lớn cũng không thực sự tốt. Những hệ thống của các tập đoàn công nghệ lớn có thể có số lượng trường dữ liệu lên tới hàng trăm ngàn. Đây là một con số khổng lồ và sẽ gây ra những hạn chế đó là:
Tăng chi phí tính toán.
Quá nhiều biến giải thích có thể dẫn tới quá khớp (overfiting). Tức hiện tượng mô hình hoạt động tốt trên tập huấn luyện nhưng kém trên tập kiểm tra.
Trong số các biến sẽ có những biến gây nhiễu và làm giảm chất lượng mô hình.
Rối loạn thông tin do không thể kiểm soát và hiểu hết các biến.
Chính vì thế chúng ta cần phải có những phương pháp như giảm chiều dữ liệu hoặc lựa chọn biến quan trọng. Về phương pháp giảm chiều dữ liệu sẽ được trình bày ở một chương khác. Trong chương này này chúng ta sẽ làm quen với một số kĩ thuật lựa chọn biến thông dụng.
Bên dưới là những thuật toán quan trọng được sử dụng để lựa chọn các biến.
2.2.10.1. Phương pháp thống kê#
Một phương pháp quan trọng trong các phương pháp thống kê nhằm giảm số lượng biến là lựa chọn dựa trên phương sai. Dựa trên phân tích các biến không biến động thì không có tác dụng gì trong việc phân loại hoặc dự báo bởi chúng ta dường như đã biết được giá trị của chúng cho tất cả các quan sát. Do đó ý tưởng chính của phương pháp này là thông qua độ lớn phương sai của toàn bộ các biến numeric để loại bỏ những biến nếu nó nhỏ hơn một ngưỡi nhất định.
Trong sklearn chúng ta có thể sử dụng VarianceThreshold để lọc bỏ biến theo phương sai.
from sklearn.feature_selection import VarianceThreshold
from sklearn.datasets import make_classification
# Khởi toạo dữ liệu example
X, y = make_classification(n_samples=500, n_features=50, random_state=123)
print('X shape:', X.shape)
print('y shape:', y.shape)
# Lọc bỏ các biến có phương sai nhỏ hơn 0.8
print('Total features with thres=0.8: {}'.format(VarianceThreshold(0.8).fit_transform(X).shape))
# Lọc bỏ các biến có phương sai nhỏ hơn 1.0
X_kvar = VarianceThreshold(0.9).fit_transform(X)
print('Total features with thres=1.0: {}'.format(X_kvar.shape))
Ngoài phương pháp phương sai, chúng ta có thể áp dụng kiểm định thống kê đơn biến. Phương pháp này sẽ đánh giá sự độc lập tuyến tính giữa hai biến ngẫu nhiên dựa trên phân phối chi-squared và Fisher để lựa chọn ra \(k\) biến tốt nhất. Để hình dung kĩ hơn về hai phương pháp thống kê nêu trên, tiếp theo chúng ta cùng thực hành lựa chọn biến và đánh giá hiệu quả mô hình.
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
# Lựa chọn biến dựa trên phương pháp Fisher
X_kbest = SelectKBest(f_classif, k = 5).fit_transform(X, y)
print('X shape after applying statistical selection: ',X_kbest.shape)
Chúng ta sẽ cùng đánh giá hiệu quả mô hình bằng cross-validation trước và sau lựa chọn biến với KFold = 5.
# Hồi qui logistic
logit = LogisticRegression(solver='lbfgs', random_state=1)
# Cross validation cho:
# 1.dữ liệu gốc
acc_org = cross_val_score(logit, X, y, scoring = 'accuracy', cv = 5).mean()
# 2. Áp dụng phương sai
acc_var = cross_val_score(logit, X_kvar, y, scoring = 'accuracy', cv = 5).mean()
# 3. Áp dụng phương pháp thống kê
acc_stat = cross_val_score(logit, X_kbest, y, scoring = 'accuracy', cv = 5).mean()
print('Accuracy trên dữ liệu gốc:', acc_org)
print('Accuracy áp dụng phương sai:', acc_var)
print('Accuracy dụng pp thống kê:', acc_stat)
Như vậy ta thấy sau khi áp dụng feature selection đã cải thiện được độ chính xác của mô hình dự báo.
2.2.10.2. Sử dụng mô hình#
Đây là phương pháp rất thường xuyên được áp dụng trong các cuộc thi phân tích dữ liệu. Chúng ta sẽ dựa trên một số mô hình cơ sở để đánh giá mức độ quan trọng của các biến. Có hai lớp mô hình thường được sử dụng để đánh biến đó là Random Forest và Linear Regression. Ưu điểm của các phương pháp này là kết quả đánh giá rất chuẩn xác, tuy nhiên nhược điểm của chúng là phải xây dựng mô hình hồi qui rồi mới xác định được biến quan trọng. Điều này dường như đi trái lại với thực tế phải lựa chọn biến trước khi huấn luyện mô hình. Để áp dụng phương pháp này chúng ta thực hiện như sau:
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import LinearSVC
from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline
# Hồi qui theo RandomForest
rdFrt = RandomForestClassifier(n_estimators = 20, random_state = 1)
# Hồi qui theo LinearSVC
lnSVC = LinearSVC(C=0.01, penalty="l1", dual=False)
# Hồi qui theo Lasso
lassoReg = Lasso(alpha = 1.0)
# Tạo một pipeline thực hiện lựa chọn biến từ RandomForest model và hồi qui theo logit
pipe1 = make_pipeline(StandardScaler(), SelectFromModel(estimator = rdFrt), logit)
# Tạo một pipeline thực hiện lựa chọn biến từ Linear SVC model và hồi qui theo logit
pipe2 = make_pipeline(StandardScaler(), SelectFromModel(estimator = lnSVC), logit)
# Cross validate đối với
# 1. Mô hình logit
acc_log = cross_val_score(logit, X, y, scoring = 'accuracy', cv = 5).mean()
# 2. Mô hình RandomForest
acc_rdf = cross_val_score(rdFrt, X, y, scoring = 'accuracy', cv = 5).mean()
# 3. Mô hình pipe1
acc_pip1 = cross_val_score(pipe1, X, y, scoring = 'accuracy', cv = 5).mean()
# 3. Mô hình pipe2
acc_pip2 = cross_val_score(pipe2, X, y, scoring = 'accuracy', cv = 5).mean()
print('Accuracy theo logit:', acc_log)
print('Accuracy theo random forest:', acc_rdf)
print('Accuracy theo pipeline 1:', acc_pip1)
print('Accuracy theo pipeline 2:', acc_pip2)
Như vậy select dựa trên mô hình Random Forest và Linear SVC đã có hiệu quả trong việc cải thiện độ chính xác của mô hình. Bên cạnh việc thực hiện lựa chọn biến dựa trên model, chúng ta còn có thể lựa chọn biến theo grid search.
2.2.10.3. Sử dụng Search#
Exhaustive Search
Ý tưởng chính của phương pháp này là tìm ra một tập con các đặc trưng tốt nhất trong số các đặc trưng đầu vào dựa trên một thước đo mô hình cụ thể (chẳng hạn như accuracy). Ví dụ, khi bạn có tổng cộng \(n\) đặc trưng thì bạn cần huấn luyện mô hình trên tất cả các kết hợp từ \(1, 2, 3, ..., n\) đặc trưng. Tổng số lượng các kết hợp có thể sẽ là:
Đây là số lượng không hề nhỏ nếu bộ dữ liệu của bạn có số lượng đặc trưng lớn. Chính vì thế phương pháp này được coi là Exhaustive và chỉ phù hợp với những bộ dữ liệu có số lượng đặc trưng nhỏ. Ưu điểm của phương pháp này mang lại đó là giúp tìm ra được tập con đặc trưng tốt nhất trực tiếp thông qua đánh giá accuracy.
Sequential Feature Selection
Nếu như chúng ta tìm kiếm trên toàn bộ các bộ kết hợp đặc trưng đầu vào của mô hình sẽ rất lâu. Do đó việc đầu tiên ta cần thực hiện là giới hạn không gian tìm kiếm. Tuỳ theo hướng tìm kiếm là tăng biến hoặc giảm biến mà phương pháp này bao gồm hai hai lựa chọn là: forward hoặc backward tương ứng. Theo lựa chọn forward thì ban đầu ta xuất phát từ lựa chọn \(1\) đặc trưng đầu vào mà mô hình có kết quả tốt nhất. Ở các bước tiếp theo ta sẽ tìm ra một đặc trưng phù hợp nhất để thêm vào mô hình sao cho thước đo đánh giá mô hình là lớn nhất. Quá trình này tiếp tục cho đến khi số lượng các đặc trưng được thêm vào đạt mức tối đa k_features
hoặc tới khi hàm loss fuction mô hình không giảm nữa. Theo chiều ngược lại, bắt đầu từ toàn bộ các đặc trưng và loại dần đặc trưng thì sẽ là backward.
So với phương pháp Exhaustive Search thì Sequential Feature Selection ít tốn kém hơn về chi phí nhưng không đảm bảo chắc chắn rằng tập hợp đặc trưng tìm được là tối ưu. Hướng di chuyển tìm kiếm theo forward và backward cũng hoàn toàn là lựa chọn may rủi.
Bên dưới ta sẽ tiến hành áp dụng phương pháp Sequential Feature Selection để tìm kiếm đặc trưng theo backward với số biến cần lựa chọn là k_features=3
.
%%script echo skipping
!pip install mlxtend
from mlxtend.feature_selection import SequentialFeatureSelector
selector = SequentialFeatureSelector(logit, scoring = 'accuracy',
verbose = 2,
k_features = 3,
forward = False,
n_jobs = -1)
selector.fit(X, y)
Ta có thể thấy mô hình xuất phát từ 50 biến ban đầu và sau mỗi một quá trình sẽ loại dần các biến cho đến khi số lượng biến tối thiểu đạt được là 3. Sau mỗi quá trình mức độ accuracy sẽ tăng dần.