Sklearn机器学习递归特征消除(RFE)强大特征选择

特征选择是机器学习中的一个至关重要的过程。选择数据集最相关的特征可以提高机器学习算法的效率,使其占用更少的内存空间和运行时间。递归特征消除(Recursive Feature Elimination,RFE)是一种强大特征选择算法。
递归特征消除(RFE)工作原理
RFE 在训练数据集中搜索特征的子集,从所有特征开始,逐步去除不重要的特征,直到剩下所需数量的特征为止。它根据特征的重要性对特征进行排序,去除最不重要的特征,并重新拟合模型。这个过程是递归进行的,直到得到最优的特征数量。
要执行 RFE,我们首先需要一个估计器,例如线性模型或基于树的估计器。估计器应该具有 fit
方法,用于提供特征重要性的信息,例如 coef_
或 feature_importances_
。
使用 Sklearn 进行机器学习
Scikit-learn Python 库通过 sklearn.feature_selection.RFE
类帮助我们实现 RFE。我们将为该类指定以下参数:
-
estimator:在此案例中,我们将使用 RandomForestClassifier
作为估计器。 -
n_features_to_select:选择的特征数量。
我们将通过调用 fit()
方法将该类拟合到数据集,从而获得以下属性:
-
support_:提供每个输入变量的 True 或 False。True 表示特征被选中,而 False 表示特征未被选中。 -
ranking_:特征的排名。 -
n_features_:选中的特征数量。
接下来,让我们将这一概念应用到红酒质量数据集上。使用 Kaggle 上的红酒质量数据集,该数据集包含 12 个特征。我们的目标是通过递归特征消除(RFE)找到最佳参数,以预测红酒质量。

将质量(quality)列预处理成一个更理想的格式:
import pandas as pd
df = pd.read_csv('winequality-red.csv',sep=';')
bins = (2, 5, 8) # 2-5 = bad quality, 5-8=good quality
groups = ['bad', 'good']
df['quality'] = pd.cut(df['quality'], bins = bins, labels = groups)
df.head(8)

现在提取 X 和 y 特征,即分别为自变量(独立特征)和因变量(依赖特征)。下面代码将数据集 X
和 y
划分为训练集和测试集,其中 70% 的数据用于训练,30% 用于测试。
X = df.drop('quality', axis=1) # 所有特征列(除去 'quality' 列)
y = df['quality'] # 目标变量:红酒的质量
from sklearn.model_selection import train_test_split
# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.30, # 30% 数据作为测试集
random_state=42 # 固定随机种子,确保结果可复现
)

应用递归特征消除(RFE)
在评估机器学习算法在特定数据集上的表现时,使用 k-fold 交叉验证是非常必要的。通过使用交叉验证,我们可以避免数据泄漏,并确保在数据转换(如 RFE)时,将其作为流水线的一部分来处理。因此,
首先,我们通过以下步骤创建一个流水线:
- 创建一个 RFE 类的实例,在其中指定估计器和希望选择的特征数量。这里我们选择了 8 个特征。
- 实例化
RandomForestClassifier
模型。 - 使用
Pipeline
对数据进行转换,并将 RFE 和模型结合起来。 - 接下来,我们使用
RepeatedStratifiedKFold
,并指定交叉验证器的折数(splits)和重复次数(repeats)。KFold
会确保每一折中各类样本的数量平衡。我们可以使用cross_val_score
来评估模型的表现。
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_validate
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.feature_selection import RFE
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
rfe = RFE(estimator=RandomForestClassifier(), n_features_to_select=8)
model = RandomForestClassifier() # instantiate a model
pipeline = Pipeline(steps=[('Feature Selection', rfe), ('Model', model)])
# evaluate the model
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=5, random_state=1)
results = cross_validate(pipeline, X, y, scoring='accuracy', cv=cv, return_estimator=True)
n_scores = cross_validate(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=1)
print('Accuracy: %.2f (%.2f)'% (np.mean(n_scores['test_score']), np.std(n_scores['test_score'])))

当选择 8 个特征时,模型的得分为 82%。
检查每次迭代中选择的列、未选择的列及其排名。

自动特征选择:使用递归特征消除与交叉验证(RFECV)
在上述示例中,我们已经配置了希望选择的特征。然而,如果我们能够自动选择它们,那就更好了。Scikit-learn 提供了 sklearn.feature_selection.RFECV
类,可以通过交叉验证自动调优所选特征的数量。
RFECV
的配置方式与 RFE
类似,但我们需要向类中提供以下参数:
-
estimator:估计器(例如模型)。 -
min_features_to_select:选择的最小特征数量。 -
cv:决定交叉验证的拆分策略。
我们导入该类并创建其实例。在使用 RFECV
时,我们需要创建一个流水线。实例化的 RFECV
传递给流水线。
from sklearn.feature_selection import RFECV
rfecv = RFECV(estimator=RandomForestClassifier())
pipeline = Pipeline(steps=[('Feature Selection',rfecv),('Model',model)])
# evaluate model
cv_rfecv = RepeatedStratifiedKFold(n_splits=10, n_repeats=5, random_state=1)
n_scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv_rfecv, n_jobs=-1)
print('Accuracy: %.2f (%.2f)'% (np.mean(n_scores), np.std(n_scores)))

让我们拟合流水线并通过 n_features
属性获取最优特征数量。
pipeline.fit(X_train, y_train)
print('Optimal number of features: %d' % rfecv.n_features_)

递归特征消除(RFE)是一种强大的特征选择技术,它可以帮助您识别模型中最重要的特征,可以与任何具有特征重要性模型的机器学习算法一起使用。
来源:新语数据故事汇