【数据处理系列】深入理解递归特征消除法(RFE):基于Python的应用

嘻嘻哈哈每天开心 2024-08-23 10:05:02 阅读 62

目录

一、递归特征消除法介绍

二、方法介绍

三、导入数据并选择模型

(一)导入数据

(二) 递归特征消除需要选择模型吗

四、RFE方法进行递归特征消除法

五、RFECV方法进行递归特征消除法(建议使用这种方法) 

       即交叉验证递归特征消除法

(一)参数介绍

(二)python使用RFECV方法

(三) 输出最优特征数

 (四)输出最优特征名称

 (五)以布尔形式输出最优特征

(六) 输出特征重要性排序

 (七)输出选择特征的索引

(八)交叉验证得分随特征数量的变化

(九)曲线图查看特征选择的结果


一、递归特征消除法介绍

递归特征消除是一种常用的特征选择方法,它可以用于回归和分类问题。RFE的基本思想是在不断迭代中递归地删除特征,直到达到预设的特征数量为止。

工作原理如下:

首先,使用所有特征训练一个模型,并计算每个特征的权重或系数。然后,排序这些特征的权重或系数,并删除权重或系数最小的特征。重复步骤1和步骤2,直到特征数量达到预设的值

二、方法介绍

想要用python实现递归特征消除法,有两种通用的方法,本篇博文会逐一介绍。在这里先简单介绍一下两种方法的区别。

分别是:

①from sklearn.feature_selection import RFE

②from sklearn.feature_selection import RFECV

`RFECV`和`RFE`都是用于特征选择的工具,但它们之间有一些区别。

①`RFE`(递归特征消除)是一种基于模型预测性能的特征选择方法。它通过递归地移除特征并重新训练模型来评估每个特征的重要性。在每次迭代中,它都会移除最不重要的特征,并重新训练模型。这个过程会一直持续到达到指定的特征数量或没有更多的特征可以移除为止。

②`RFECV`(递归特征消除与交叉验证)是`RFE`的扩展,它使用交叉验证来评估特征的重要性。在每次迭代中,它都会使用交叉验证来评估模型的性能,并选择最佳的特征数量。这个过程会一直持续到找到最佳的特征数量为止。

因此,`RFECV`比`RFE`更可靠,因为它使用交叉验证来评估特征的重要性,从而减少了过拟合的风险。此外,`RFECV`还可以自动确定最佳的特征数量,而`RFE`需要手动指定。

总的来说,如果你需要更可靠的特征选择方法,并且希望自动确定最佳的特征数量,那么你应该使用`RFECV`。如果你只需要简单的特征选择方法,并且可以手动指定特征数量,那么你可以使用`RFE`。

三、导入数据并选择模型

(一)导入数据

本次选取的是python内置的鸢尾花数据,是有标签的数据,一共150个样本,四个特征。

<code># 导入所需的库

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from sklearn import tree

from sklearn.datasets import load_iris

from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score

from sklearn.tree import DecisionTreeClassifier

# 导入鸢尾花数据集

iris = load_iris()

X = iris.data # 特征

y = iris.target # 类别

feature_names = iris.feature_names # 特征名称

class_names = iris.target_names # 类别名称

(二) 递归特征消除需要选择模型吗

是的,递归特征消除需要选择一个模型作为其基础。这个模型被称为“基模型”或“估计器”,它用于评估特征的重要性。使用这个基模型来构建模型,并根据模型的性能来选择或排除特征。

基模型的选择对结果有重要影响,因为不同的模型可能会以不同的方式评估特征的重要性。例如,决策树模型可能会根据特征对决策树的分割贡献来评估特征的重要性,而线性模型可能会根据特征的系数大小来评估。

在选择基模型时,应考虑以下因素:

模型的解释性:选择一个能够提供特征重要性评分的模型,这样RFE就可以根据这些评分来选择特征。

模型的稳定性:选择一个在特征选择过程中表现稳定的模型,以减少随机性对特征选择结果的影响。

模型的复杂度:选择一个复杂度适当的模型,以避免在特征选择过程中过度拟合或欠拟合。

数据集的特点:根据数据集的类型和特点选择合适的模型。例如,如果数据集是线性的,那么线性模型可能是一个好的选择;如果数据集是非线性的,那么决策树或支持向量机等非线性模型可能更合适。

在实际应用中,通常需要尝试不同的基模型,并评估它们在特征选择和最终模型性能上的表现,以确定最佳的基模型。在scikit-learn库中,几乎所有的监督学习模型都可以用作RFE的基模型,包括但不限于线性回归、逻辑回归、决策树、随机森林、支持向量机等。

本次选择的模型是分类决策树

#实例化

clf = DecisionTreeClassifier()

四、RFE方法进行递归特征消除法

from sklearn.feature_selection import RFE

from sklearn.model_selection import cross_val_score

#递归特征消除法

selector1 = RFE(clf, n_features_to_select=3, step=1).fit(X, y)

# n_features_to_select表示筛选最终特征数量,step表示每次排除一个特征

selector1.support_.sum()

#计算在 RFE 过程中被选中的特征数量,即布尔数组中值为 True 的个数,也就是最终选择的特征数量。

print(selector1.ranking_)

#这个属性返回的是特征的排名,从1开始,表示每个特征在所有特征中的重要性排名,1为最重要的特征。

print(selector1.n_features_)

#这是RFE在执行完所有递归步骤后最终选择的特征数量。

X_wrapper1 = selector1.transform(X)

#通过transform方法,selector1只保留了被选中的特征,生成新的特征矩阵X_wrapper1。

score =cross_val_score(clf, X_wrapper1, y, cv=9).mean()

#使用cross_val_score进行9折交叉验证,评估clf模型在选择特征后的表现。mean()函数计算所有验证分数的平均值,作为模型性能的估计。

print(score)

结果如上,表明选择了三个特征,分别是原始数据中的第一个、第三个、第四个特征。

五、RFECV方法进行递归特征消除法(建议使用这种方法) 

       即交叉验证递归特征消除法

(一)参数介绍

交叉验证递归特征消除法(Recursive Feature Elimination with Cross-Validation, RFECV)是一种基于特征重要性的特征选择方法。它结合了递归特征消除法和交叉验证。该方法通过训练模型,不断剔除最不重要的特征,并评估模型的性能,直到达到预设的特征数量或性能指标。在这个过程中,RFECV使用交叉验证来评估模型性能,并选择最优的特征子集。最后,RFECV输出被选择的特征子集。

<code>from sklearn.feature_selection import RFECV

rfecv=RFECV(estimator, step=1,min_features_to_select=1, cv=None,scoring=None, verbose=0, n_jobs=None, importance_getter='auto')code>

 当你使用`RFECV`时,你可以使用以下参数来配置该工具:

1. estimator:用于评估特征重要性的估计器对象。这可以是一个分类器或回归器,具体取决于你的用例。

2. step:在递归过程中每次迭代移除的特征数量。默认值为1,表示每次迭代移除一个特征。若step为小数,如step=0.1,说明每次删除10%的特征变量。

3. min_features_to_select:在递归过程中至少保留的特征数量。默认值为1,表示在任何情况下都保留至少一个特征。

4. cv:用于评估估计器性能的交叉验证生成器。默认值为`None`。

5. scoring:用于评估估计器性能的评分函数。默认值为`None`。

6. verbose:输出信息的详细程度。默认值为0,表示不输出任何信息。

7. n_jobs:用于并行化的工作进程数。默认值为`None`,表示使用默认的值。

8. importance_getter:用于获取特征重要性的函数。默认值为`'auto'`,表示自动选择。如果`estimator`是一个分类器或回归器,则使用`feature_importances_`属性。如果`estimator`是一个集成学习器,则使用`feature_importances_`或`coef_`属性。如果`estimator`没有这些属性,则使用`n_features_`作为特征重要性。

(二)python使用RFECV方法

#交叉验证递归特征消除法

from sklearn.model_selection import cross_val_score

import matplotlib.pyplot as plt

from sklearn.feature_selection import RFECV

clf = DecisionTreeClassifier()

selector = RFECV(clf, step=1, cv=5,min_features_to_select=1)

#使用RFECV进行特征选择。selector = RFECV(clf, step=1, cv=10)表示使用决策树分类器作为基模型,每次迭代移除一个特征,共进行10次交叉验证。

#在RFECV中,迭代次数是由特征数量和步长决定的。在这个例子中,步长为1,表示每次迭代移除一个特征。因此,迭代次数等于特征数量减去1。

# 假设有n个特征,那么迭代次数为n - 1

selector = selector.fit(X, y)

#使用训练数据拟合特征选择器:selector = selector.fit(X_train, y_train)

X_wrapper = selector.transform(X)

#将训练数据转换为经过特征选择后的数据:X_wrapper = selector.transform(X_train)。

score =cross_val_score(clf , X_wrapper, y, cv=5).mean()

#使用交叉验证计算模型在经过特征选择后的训练数据上的得分

print(score)

在上面的代码中,我们使用了sklearn中的RFECV类进行特征选择。其中clf是一个决策树分类器,step参数指定每次迭代移除一个特征,cv参数指定进行交叉验证的次数。selector = selector.fit(X, y)表示使用训练数据进行特征选择。X_wrapper = selector.transform(X)将原始数据转换为经过特征选择后的数据。score =cross_val_score(clf , X_wrapper, y, cv=5).mean()用选择后的特征子集进行交叉验证,并计算模型的平均性能得分。 

(三) 输出最优特征数

indx_n=-1

op_feature_list=[]

for i in selector.ranking_:

indx_n=indx_n+1

if i == 1:

op_feature_list.append(iris.feature_names[indx_n])

#最终选择的特征数量

print("最优特征数 : %d" % selector.n_features_)

 (四)输出最优特征名称

<code>print ('最优特征为:',op_feature_list)

 (五)以布尔形式输出最优特征

<code>#True表示保留特征,False表示剔除特征

print('被选择的特征为Ture :',selector.support_)

(六) 输出特征重要性排序

<code>print('特征重要性排序 = :',selector.ranking_) #数值越小越重要

 (七)输出选择特征的索引

<code>selected_features = [i for i in range(len(selector.support_)) if selector.support_[i]]

print("选择的特征索引:", selected_features)

(八)交叉验证得分随特征数量的变化

<code>print ('5折交叉验证得分随特征数量的变化:', selector.grid_scores_)

在selector.grid_scores_中,每个元素对应于对应特征数量下模型在交叉验证中的得分。通常情况下,selector.grid_scores_的长度等于特征数量的范围,每个元素的值代表在对应特征数量下的平均得分。

是一个列表,其中一共有四个元素,列表中的每个元素表示不同数量的特征被选中时模型的平均性能得分。列表中的第一个元素表示只选择一个最重要的特征时模型的性能得分,第二个元素表示选择两个最重要的特征时模型的性能得分,以此类推。

(九)曲线图查看特征选择的结果

<code>import matplotlib.pyplot as plt

plt.figure()

plt.xlabel("Number of features selected")

plt.ylabel("Cross validation score")

plt.plot(range(1,5),selector.grid_scores_)

# 设置x轴刻度

plt.xticks(range(1, 5))

plt.show()



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。