特征选择_1
在数据预处理过程中,特征选择是一个重要的过程,选择出重要的特征可以加快模型训练速度。通常可以从以下两方面来选择特征:
1.特征是否发散(对于样本区分作用的大小)
2.特征与标签的相关性
特征选择的方法主要有3种:
1.Filter Method:先根据统计量设置阈值选择特征,之后再训练模型。
2.Wrapper Method:把最终将要使用的模型的性能作为特征子集的评价标准,多次训练模型选择有利于模型性能的特征子集。
3.Embedding Method:将特征选择过程与模型训练过程融为一体,在模型训练的过程中自动进行特征选择。
常用sklearn中的feature_selection库来进行特征选择。
1. Fliter 过滤法:
Fliter的优点在于只训练一次模型,速度快。但是选择与标签相关性最强的特征子集不一定是最佳特征,甚至可能对结果负优化。
1.1 方差选择法
计算各个特征的方差,设置阈值,选择方差大于阈值的特征。
1 2 3 |
from sklearn.feature_selection import VarianceThreshold #参数threshold为方差的阈值 VarianceThreshold(threshold=3).fit_transform(iris.data) |
1.2 Pearson相关系数法
计算各个特征对于标签的Pearson相关系数和p值,选择前k名的特征。
1 2 3 4 |
from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr #参数k为选择的特征个数 SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target) |
Pearson法的缺陷在于只对线性相关敏感,对非线性关系不敏感。
1.3 卡方检验\互信息法等方法
也是用来评价X与y的相关性,先构建评价函数,再选择前K名的特征。
1 2 3 4 5 6 7 8 9 10 11 12 |
#chi2 from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target) #MIC from minepy import MINE def mic(x, y): m = MINE() m.compute_score(x, y) return (m.mic(), 0.5) SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target) |
2. Wrapper 包装法:
Wrapper的优点在于能够识别模型最适宜的特征子集,缺点在于训练多次模型,算法复杂性高,且特征子集不一定是大多数解释变量。
Wrapper最具代表性的方法就是RFE递归消除特征法,即使用一个基模型来进行多轮训练,每轮训练都遍历所有特征,之后消除重要性(feature_importances_)低的特征,再基于新的特征集进行下一轮训练。
1 2 3 4 5 6 7 8 |
#RFE from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression rfe = RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target) #RFECV from sklearn.feature_selection import RFECV rfecv = RFECV(estimator=svc, step=1, cv=StratifiedKFold(2), scoring='roc_auc') |
3. Embedded 嵌入法
3.1 基于惩罚项的特征选择法
使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。由于L1正则化会产生稀疏权值矩阵,所以其自带特征选择的特性。
1 2 3 4 5 6 7 |
#L1正则 from sklearn.feature_selection import SelectFromModel from sklearn.linear_model import LogisticRegression SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(iris.data, iris.target) #L2正则 SelectFromModel(LogisticRegression(penalty="l2",threshold=0.5, C=0.1)).fit_transform(iris.data, iris.target) |
3.2 基于树模型的特征选择法
树模型中GBDT也可用来作为基模型进行特征选择。
1 2 3 |
from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import GradientBoostingClassifier SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target) |
4. 基于SHAP值的特征筛选
SHAP是由Shapley value启发的可加性解释模型。对于每条样本,每个特征都会对应一个SHAP value值体现其对结果的贡献。
1 2 3 4 5 6 7 8 |
import shap # 创建模型解释器 explainer_xgb = shap.TreeExplainer(model1) explainer_lgb = shap.TreeExplainer(model2) # 获取训练集每个样本每个特征特征的SHAP值,并对特征进行整体的可视化 shape_values = explainer_lgb.shap_values(data[cols]) shap.summary_plot(shape_values, data[cols], plot_type='bar') |
5. 基于对抗验证(Adversarial Validation)的特征筛选
常用于训练集与测试集相差非常大的情况。实现步骤:
1.将训练集和测试集合并,分别打上0和1的标签。
2.构建模型进行训练,逐个将特征输入模型,记录AUC。
3.最后将AUC高的特征删除(将测试和训练样本差别很大的特征删除),通过删掉这些特征实现模型效果提升。