递归特征消除(RFE)
递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,移除若干权值系数的特征,再基于新的特征集进行下一轮训练。
sklearn官方解释:对特征含有权重的预测模型(例如,线性模型对应参数coefficients),RFE通过递归减少考察的特征集规模来选择特征。首先,预测模型在原始特征上训练,每个特征指定一个权重。之后,那些拥有最小绝对值权重的特征被踢出特征集。如此往复递归,直至剩余的特征数量达到所需的特征数量。
RFE 通过交叉验证的方式执行RFE,以此来选择最佳数量的特征:对于一个数量为d的feature的集合,他的所有的子集的个数是2的d次方减1(包含空集)。指定一个外部的学习算法,比如SVM之类的。通过该算法计算所有子集的validation error。选择error最小的那个子集作为所挑选的特征。
"""
使用RFE进行特征选择:RFE是常见的特征选择方法,也叫递归特征消除。它的工作原理是递归删除特征,
并在剩余的特征上构建模型。它使用模型准确率来判断哪些特征(或特征组合)对预测结果贡献较大。
""" from sklearn import datasets from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression model = LogisticRegression() rfe = RFE(model, 3) rfe = rfe.fit(X, y) print(X.columns[rfe.support_]) print(rfe.support_) print(rfe.ranking_)
RFE的稳定性很大程度上取决于迭代时,底层用的哪种模型。比如RFE采用的是普通的回归(LR),没有经过正则化的回归是不稳定的,那么RFE就是不稳定的。假如采用的Lasso/Ridge,正则化的回归是稳定的,那么RFE就是稳定的。
皮尔逊系数(相关系数)
皮尔逊相关也称为积差相关(或者积矩相关)。我们假设有两个变量X,Y,那么两变量间的皮尔逊相关系数计算如下:
# 查看其他指标和income的相关性,并对其相关性系数排序 # 正相关与负相关,越接近1说明该变量值越大目标标签的值越容易分类为1 df.corr()[["n23"]].sort_values(by="n23",ascending=False) # 可以根据相关性的值进行取值带入模型(特征选取与筛选)第一次选取 corr=df.corr()[["n23"]].sort_values(by="n23",ascending=False).iloc[1:10].index.values.astype("U") corr_name=corr.tolist() corr_name
利用该方法还可以绘制热力图:sns.clustermap(df.corr())
Pearson相关系数的一个明显缺陷是,作为特征排序机制,他只对线性关系敏感。如果关系是非线性的,即便两个变量具有一一对应的关系,Pearson相关性也可能会接近0。
基于树模型的特征选择
一般基于模型所做出的特征选择,效果比单变量的要好,但是不管是所有的特征选取的方法都需要结合实际的经验,来辨别特征的有效性。
轻量级的高效梯度树
from sklearn.model_selection import train_test_split,cross_val_score #拆分训练集和测试集 import lightgbm as lgbm #轻量级的高效梯度提升树 X_name=df.corr()[["n23"]].sort_values(by="n23",ascending=False).iloc[1:].index.values.astype("U") X=df.loc[:,X_name.tolist()] y=df.loc[:,['n23']] X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,stratify=y,random_state=1) lgbm_reg = lgbm.LGBMRegressor(objective='regression',max_depth=6,num_leaves=25,learning_rate=0.005,n_estimators=1000,min_child_samples=80, subsample=0.8,colsample_bytree=1,reg_alpha=0,reg_lambda=0) lgbm_reg.fit(X_train, y_train) #选择最重要的20个特征,绘制他们的重要性排序图 lgbm.plot_importance(lgbm_reg, max_num_features=20) ##也可以不使用自带的plot_importance函数,手动获取特征重要性和特征名,然后绘图 feature_weight = lgbm_reg.feature_importances_ feature_name = lgbm_reg.feature_name_ feature_sort = pd.Series(data = feature_weight ,index = feature_name) feature_sort = feature_sort.sort_values(ascending = False) # plt.figure(figsize=(10,8)) # sns.barplot(feature_sort.values,feature_sort.index, orient='h') lgbm_name=feature_sort.index[:15].tolist() lgbm_name
随机森林
from sklearn import metrics import warnings warnings.filterwarnings("ignore") from sklearn.ensemble import RandomForestClassifier import matplotlib.pyplot as plt selected_feat_names=set() for i in range(10): #这里我们进行十次循环取交集 tmp = set() rfc = RandomForestClassifier(n_jobs=-1) rfc.fit(X, y) #print("training finished") importances = rfc.feature_importances_ indices = np.argsort(importances)[::-1] # 降序排列 S={} for f in range(X.shape[1]): if importances[indices[f]] >=0.0001: tmp.add(X.columns[indices[f]]) S[X.columns[indices[f]]]=importances[indices[f]] #print("%2d) %-*s %f" % (f + 1, 30, X.columns[indices[f]], importances[indices[f]])) selected_feat_names |= tmp imp_fea=pd.Series(S) plt.figure(figsize=(10,8)) sns.barplot(imp_fea.values,imp_fea.index, orient='h') print(imp_fea) print(len(selected_feat_names), "features are selected")
其实还有很多,比如在回归问题中,基于惩罚项的特征选取;L1、L2模型也是可以的
迭代选择
在迭代特征选择中,将会构建一系列模型,每个模型都使用不同数量的特征。有两种基本方法:开始时没有特征,然后逐个添加特征,直到满足某个终止条件;或者从所有特征开始,然后逐个删除特征,直到满足某个终止条件。由于构建了一系列模型,所以这些方法的计算成本要比前面讨论过的方法更高。
其中一种特殊方法是递归特征消除(recursive feature elimination, RFE),在前面也介绍了,它从所有特征开始构建模型,并根据模型舍弃最不重要的特征,然后使用除被舍弃特征之外的所有特征来构建一个新模型,如此继续,直到仅剩下预设数量的特征。为了让这种方法能够运行,用于选择的模型需要提供某种确定特征重要性的方法,正如基于模型的选择所做的那样。