逐步回归是一种强大的技术,用于在回归模型中选择最相关的预测变量。通过基于统计显著性迭代添加或删除变量,它有助于构建简洁易懂且不易过拟合的模型。本文探讨了使用流行的库(如`statsmodels`、`scikit-learn`(`sklearn`)和`mlxtend`)在Python中执行逐步回归的各种方法。
目录
前向选择
前向选择从一个空模型开始,迭代地添加最显著地改善模型拟合的预测变量。这种改进通常使用F统计量、AIC(赤池信息准则)或BIC(贝叶斯信息准则)等指标进行评估。这个过程持续进行,直到添加另一个变量不再提供统计上显著的改进。
后向消除
后向消除采用相反的方法。它从包含所有预测变量的模型开始,迭代地删除最不显著的变量。在每一步中,都删除p值最高(或F统计量最低)的变量,前提是其删除不会显著恶化模型拟合。这个过程持续进行,直到删除任何剩余变量都会显著降低模型的性能。
逐步选择(双向)
逐步选择结合了前向选择和后向选择的优点。它从空模型(如前向选择)或完整模型(如后向消除)开始,并根据变量的显著性迭代地添加或删除变量。这允许更灵活且可能更优的预测变量子集。
使用statsmodels
进行逐步回归
statsmodels
没有内置的逐步回归函数,但我们可以使用其`OLS`(普通最小二乘法)模型手动实现前向选择:
import pandas as pd
import numpy as np
import statsmodels.api as sm
from statsmodels.formula.api import ols
# 样本数据
data = {'y': [10, 12, 15, 18, 20, 22, 25, 28, 30, 32],
'x1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'x2': [2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
'x3': [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]}
df = pd.DataFrame(data)
def forward_selection(data, target, significance_level=0.05):
included = []
while True:
changed=False
excluded = list(set(data.columns)-set(included)-{target})
best_pvalue = 1.0
best_feature = None
for new_column in excluded:
model = sm.OLS(target, sm.add_constant(data[included+[new_column]])).fit()
pvalue = model.pvalues[new_column]
if pvalue < best_pvalue:
best_pvalue = pvalue
best_feature = new_column
if best_pvalue < significance_level:
included.append(best_feature)
changed=True
if not changed: break
return included
selected_features = forward_selection(df, df['y'])
print(f"选择的特征: {selected_features}")
final_model = sm.OLS(df['y'], sm.add_constant(df[selected_features])).fit()
print(final_model.summary())
使用sklearn
进行逐步回归
sklearn
使用递归特征消除(RFE)进行特征选择。RFE根据基础模型(如线性回归)的重要性分数迭代地删除特征:
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import RFE
from sklearn.model_selection import train_test_split
X = df.drop('y', axis=1)
y = df['y']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = LinearRegression()
rfe = RFE(model, n_features_to_select=2) # 根据需要调整
rfe = rfe.fit(X_train, y_train)
print(f"选择的特征: {X.columns[rfe.support_]}")
final_model = LinearRegression().fit(X_train[X.columns[rfe.support_]], y_train)
print(f"测试集上的R方: {final_model.score(X_test[X.columns[rfe.support_]], y_test)}")
使用mlxtend
进行逐步回归
mlxtend
的`SequentialFeatureSelector`提供了一种方便的方法来执行前向、后向或逐步选择:
from mlxtend.feature_selection import SequentialFeatureSelector as SFS
from sklearn.linear_model import LinearRegression
model = LinearRegression()
sfs = SFS(model, k_features='best', forward=True, floating=False, scoring='r2', cv=5) # 前向选择
sfs = sfs.fit(X, y)
print(f"选择的特征: {list(sfs.k_feature_idx_)}")
final_model = LinearRegression().fit(X[X.columns[list(sfs.k_feature_idx_)]], y)
选择合适的方法和注意事项
逐步回归方法(前向、后向或逐步)和所用库的选择取决于特定的数据集和目标。请记住考虑:
- 数据大小:对于大量的预测变量,后向消除可能计算成本很高。
- 多重共线性:逐步方法可能难以处理高度相关的预测变量。
- 可解释性与预测精度:更简单的模型(更少的变量)可能更容易解释,即使其精度略低。
- 交叉验证:始终使用k折交叉验证等技术验证您的模型,以确保其泛化能力。
应谨慎使用逐步回归。它可能导致不稳定的模型,这些模型难以很好地推广到新数据。请考虑探索其他特征选择方法,例如LASSO或Ridge回归,它们结合了正则化来处理过拟合。