【特征选择】包裹式特征选择法
原创博文,转载请注明出处!
包裹式特征选择法的特征选择过程与学习器相关,使用学习器的性能作为特征选择的评价准则,选择最有利于学习器性能的特征子集。常用的包裹式特征选择法有递归特征消除法RFE。
# 递归特征消除法
- 递归特征消除法RFE
递归特征消除法的英文全名为recursive feature elimination,简称RFE。首先设定n_features_to_select( 经过特征选择后,特征集中剩余的特征个数),然后使用一个基模型来进行多轮训练,每轮训练后移除若干权值系数的特征,再基于新的特征集进行下一轮训练,直至特征个数为n_features_to_select。sklearn在feature_selection模块中封装了RFE。sklearn中RFE的主要参数为:
* estimator -- 基学习器
* n_features_to_select -- 经过特征选择后,特征集中剩余的特征个数
* step -- 默认1,即每次迭代移除一个特征
* verbose -- 默认0,不显示中间过程
- 结合交叉验证的递归特征消除法RFECV
RFE设定n_features_to_select时存在一定的盲目性,可能使得模型性能变差。比如,n_features_to_select过小时,相关特征可能被移除特征集,信息丢失;n_features_to_select过大时,无关特征没有被移除特征集,信息冗余。在工程实践中,RFE通过CV寻找最优的n_features_to_select,sklearn封装了结合CV的RFE,即RFECV。在RFECV中,如果减少特征会造成性能损失,那么将不会去除任何特征。RFECV适合选取单模型特征,但是计算量较大。sklearn中RFECV的主要参数为:
* estimator -- 基学习器
* step -- 默认1,即每次迭代移除一个特征
* cv – 默认2,即二折交叉验证的方式进行特征选择
* scoring -- 根据学习目标设定的模型评分标准
* verbose -- 默认0,即不显示中间过程
* n_jobs -- 默认1,即不使用并行计算,单核计算
# 递归特征消除法的工程实践
下面程序中,分别使用原始特征集、经过RFE特征选择后的特征集、经过RFECV特征选择后的特征集,训练线性支持向量机,结果显示使用RFECV处理后的特征集训练线性支持向量机模型效果最好。
# -*- coding: utf-8 -*- """ # author: wanglei5205 # blog:http://cnblogs.com/wanglei5205 # github:http://github.com/wanglei5205 """ ### 生成数据 from sklearn.datasets import make_classification X, y = make_classification(n_samples=1000, # 样本个数 n_features=25, # 特征个数 n_informative=3, # 有效特征个数 n_redundant=2, # 冗余特征个数(有效特征的随机组合) n_repeated=0, # 重复特征个数(有效特征和冗余特征的随机组合) n_classes=8, # 样本类别 n_clusters_per_class=1, # 簇的个数 random_state=0) ### 特征选择 # RFE from sklearn.svm import SVC svc = SVC(kernel="linear") from sklearn.feature_selection import RFE rfe = RFE(estimator = svc, # 基分类器 n_features_to_select = 2, # 选择特征个数 step = 1, # 每次迭代移除的特征个数 verbose = 1 # 显示中间过程 ).fit(X,y) X_RFE = rfe.transform(X) print("RFE特征选择结果——————————————————————————————————————————————————") print("有效特征个数 : %d" % rfe.n_features_) print("全部特征等级 : %s" % list(rfe.ranking_)) """ 有效特征个数 : 2 全部特征等级 : [6, 1, 13, 20, 16, 7, 18, 2, 3, 22, 24, 12, 17, 11, 14, 23, 9, 15, 1, 21, 8, 10, 4, 5, 19] """ # RFECV from sklearn.svm import SVC svc = SVC(kernel="linear") from sklearn.model_selection import StratifiedKFold from sklearn.feature_selection import RFECV rfecv = RFECV(estimator=svc, # 学习器 step=1, # 移除特征个数 cv=StratifiedKFold(2), # 交叉验证次数 scoring='accuracy', # 学习器的评价标准 verbose = 1, n_jobs = 1 ).fit(X, y) X_RFECV = rfecv.transform(X) print("RFECV特征选择结果——————————————————————————————————————————————————") print("有效特征个数 : %d" % rfecv.n_features_) print("全部特征等级 : %s" % list(rfecv.ranking_)) """ 有效特征个数 : 3 全部特征等级 : [5, 1, 12, 19, 15, 6, 17, 1, 2, 21, 23, 11, 16, 10, 13, 22, 8, 14, 1, 20, 7, 9, 3, 4, 18] """ ### 数据拆分 from sklearn.model_selection import train_test_split x_a_train,x_a_test,y_a_train,y_a_test = train_test_split(X,y,random_state = 33,test_size = 0.25) x_b_train,x_b_test,y_b_train,y_b_test = train_test_split(X_RFE,y,random_state = 33,test_size = 0.25) x_c_train,x_c_test,y_c_train,y_c_test = train_test_split(X_RFECV,y,random_state = 33,test_size = 0.25) ### 效果比较 svc_a = SVC(kernel="linear").fit(x_a_train,y_a_train) svc_b = SVC(kernel="linear").fit(x_b_train,y_b_train) svc_c = SVC(kernel="linear").fit(x_c_train,y_c_train) print("效果比较————————————————————————————————————————————————————————") print("no feature select",svc_a.score(x_a_test,y_a_test)) print("RFE feature select",svc_b.score(x_b_test,y_b_test)) print("RFECV feature select",svc_c.score(x_c_test,y_c_test)) """ no feature select 0.74 RFE feature select 0.448 RFECV feature select 0.84 """