Scikit-learn thực sự không hỗ trợ hồi quy từng bước. Đó là bởi vì cái thường được gọi là 'hồi quy từng bước' là một thuật toán dựa trên giá trị p của các hệ số của hồi quy tuyến tính, và scikit-learn cố tình tránh cách tiếp cận suy luận để học mô hình (kiểm tra ý nghĩa, v.v.). Hơn nữa, OLS thuần túy chỉ là một trong vô số thuật toán hồi quy, và theo quan điểm học scikit, nó không quan trọng lắm, cũng không phải là một trong những thuật toán tốt nhất.
Tuy nhiên, có một số lời khuyên cho những người vẫn cần một cách tốt để lựa chọn tính năng với các mô hình tuyến tính:
- Sử dụng các mô hình thưa thớt như
ElasticNet
hoặc Lasso
.
- Bình thường hóa các tính năng của bạn với
StandardScaler
, và sau đó đặt hàng các tính năng của bạn chỉ bằng cách model.coef_
. Đối với các hiệp phương thức hoàn toàn độc lập, nó tương đương với việc sắp xếp theo giá trị p. Lớp học sklearn.feature_selection.RFE
sẽ làm điều đó cho bạn, và RFECV
thậm chí sẽ đánh giá số lượng tính năng tối ưu.
- R2
statsmodels
- Thực hiện lựa chọn chuyển tiếp hoặc lùi để tối đa hóa số liệu yêu thích của bạn khi xác thực chéo (có thể mất khoảng thời gian bậc hai về số lượng hiệp phương sai).
mlxtend
Gói tương thích scikit-learn hỗ trợ phương pháp này cho bất kỳ công cụ ước tính và bất kỳ số liệu nào.
- Nếu bạn vẫn muốn hồi quy từng bước vanilla, thì việc căn cứ vào nó sẽ dễ dàng hơn
statsmodels
, vì gói này tính toán giá trị p cho bạn. Một lựa chọn tiến lùi cơ bản có thể trông như thế này:
`` `
from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
import statsmodels.api as sm
data = load_boston()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
def stepwise_selection(X, y,
initial_list=[],
threshold_in=0.01,
threshold_out = 0.05,
verbose=True):
""" Perform a forward-backward feature selection
based on p-value from statsmodels.api.OLS
Arguments:
X - pandas.DataFrame with candidate features
y - list-like with the target
initial_list - list of features to start with (column names of X)
threshold_in - include a feature if its p-value < threshold_in
threshold_out - exclude a feature if its p-value > threshold_out
verbose - whether to print the sequence of inclusions and exclusions
Returns: list of selected features
Always set threshold_in < threshold_out to avoid infinite looping.
See https://en.wikipedia.org/wiki/Stepwise_regression for the details
"""
included = list(initial_list)
while True:
changed=False
# forward step
excluded = list(set(X.columns)-set(included))
new_pval = pd.Series(index=excluded)
for new_column in excluded:
model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included+[new_column]]))).fit()
new_pval[new_column] = model.pvalues[new_column]
best_pval = new_pval.min()
if best_pval < threshold_in:
best_feature = new_pval.argmin()
included.append(best_feature)
changed=True
if verbose:
print('Add {:30} with p-value {:.6}'.format(best_feature, best_pval))
# backward step
model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included]))).fit()
# use all coefs except intercept
pvalues = model.pvalues.iloc[1:]
worst_pval = pvalues.max() # null if pvalues is empty
if worst_pval > threshold_out:
changed=True
worst_feature = pvalues.argmax()
included.remove(worst_feature)
if verbose:
print('Drop {:30} with p-value {:.6}'.format(worst_feature, worst_pval))
if not changed:
break
return included
result = stepwise_selection(X, y)
print('resulting features:')
print(result)
Ví dụ này sẽ in đầu ra sau:
Add LSTAT with p-value 5.0811e-88
Add RM with p-value 3.47226e-27
Add PTRATIO with p-value 1.64466e-14
Add DIS with p-value 1.66847e-05
Add NOX with p-value 5.48815e-08
Add CHAS with p-value 0.000265473
Add B with p-value 0.000771946
Add ZN with p-value 0.00465162
resulting features:
['LSTAT', 'RM', 'PTRATIO', 'DIS', 'NOX', 'CHAS', 'B', 'ZN']