避免无用的特征(avoid useless features)
避免冗余的特征(avoid redundant features)
使用易于理解的简单特征(good features should easy to understand)
有区分性(Informative)
特征之间相互独立(Independent)
简单易于理解(Simple)
sklearn中包含feature_select模块,基本都可以实现特征选择的功能。通常复杂模型有 feature_importances_ 参数用于获取特征的重要性;线性回归,SVM等方法特征的参数就代表了特征的重要性。
下面进入正题:(注:本文只做简单的概要整理,详细信息可去参考链接或自行查找)
特征选择常用方法过滤选择,包裹(包装)选择,嵌入选择。过滤和包装是与后续机器学习过程无关,嵌入则与机器学习过程相结合。
过滤式方法先对数据集进行特征选择,然后再训练学习器,特征选择过程与后续学习器无关,这相当于先用特征选择过程对初识特征进行“过滤”,然后再用过滤后的特征来训练模型。比如,Relief方法。
此方法有如下包含:
a、绘图判断
b、单特征
方差筛选:去掉方差为0或者小于某阈值的属性。如:
sklearn.feature_selection.VarianceThreshold(threshold=0.0)
c、数值特征与数值特征
协方差:判断两个特征关系,正相关或负相关
pearson系数:标准化后的协方差,因此更重要的特性来了,它消除了两个变量变化幅度的影响,而只是单纯反应两个变量每单位变化时的相似程度。(0.8-1.0 极强相关;0.6-0.8 强相关;0.4-0.6 中等程度相关;0.2-0.4 弱相关;0.0-0.2 极弱相关或无相关。)
距离相关系数:如果距离相关系数是0 ,那么我们就可以说这两个变量是独立的
d、类别特征与类别特征
卡方检验:先假设两个变量确实是独立的(“原假设”),然后观察实际值(观察值)与理论值(这个理论值是指“如果两者确实独立”的情况下应该有的值)的偏差程度。
Fisher得分:在同一个类别中的取值比较相似,而在不同类别之间的取值差异比较大;fisher得分越高,特征在不同类别中的差异性越大,在同一类别中的差异性越小,则特征越重要。
F检验: 用来判断特征与label的相关性的,F 检验只能表示线性相关关系
斯皮尔曼等级相关(分类,类别型与类别型)
Kendall(肯德尔等级)相关系数(分类)
互信息和最大互系数(非参数):互信息:估计特征与label之间的关系。最大信息系数。
距离相关系数
e、数值特征与类别特征
数值特征离散化:将数值特征离散化,然后,使用类别与类别变量相关性分析的方法来分析相关性
箱形图:使用画箱形图的方法,看类别变量取不同值,数值变量的均值与方差及取值分布情况。
Relief(Relevant Features):适用于二分类
Relief-F:适用于多分类
包裹式选择特征(包装法)不考虑后续学习器不同,包裹式特征选择直接把最终将要使用的学习器的性能作为特征子集的评价准则。换言之,包裹式特征选择的目的就是为给定学习器选择最有利于其性能,量身定做的特征子集。包裹式选择比过滤式特征选择更好,但是另一方面,计算开销却要大得多。比如LVW方法(Las Vegas Wrapper)。
此方法有如下包含:
a、前向搜索
b、后向搜索
c、递归特征消除法
这三种方法的核心思想都是逐个选取(增加、删除)特征,观察对训练结果影响是否达到阈值。
嵌入式特征选择是将特征选择过程与学习器训练过程融为一体,两者在同一个优化过程中优化,即在学习器训练过程中自动进行了特征选择。比如,L1正则化、决策树学习等。
此方法有如下包含:
a、正则化
L1/Lasso:L1正则方法具有稀疏解的特性,因此天然具备特征选择的特性
L2/Ridge
b、基于树模型的特征重要性
RF
ExtraTree
Adaboost
GBDT
XGboost:xgboost的基学习器可以是gbtree也可以是gbliner。当基学习器是gbtree时,可以计算特征重要性。
LightGBM
RF、Xgboost、ExtraTree每个选出topk特征,再进行融合:代码如下。
from sklearn import ensemble
from sklearn.model_selection import GridSearchCV
import xgboost as xgb
def get_top_k_feature(features,model,top_n_features):
feature_imp_sorted_rf = pd.DataFrame({'feature':features,'importance':model.best_estimator_.feature_importances_}).sort_values('importance',ascending='False')
features_top_n = feature_imp_sorted_rf.head(top_n_features)['feature']
return features_top_n
def ensemble_model_feature(X,Y,top_n_features):
features = list(X)
#随机森林
rf = ensemble.RandomForestRegressor()
rf_param_grid = {'n_estimators':[900],'random_state':[2,4,6,8]}
rf_grid = GridSearchCV(rf,rf_param_grid,cv=10,verbose=1,n_jobs=25)
rf_grid.fit(X,Y)
top_n_features_rf = get_top_k_feature(features=features,model=rf_grid,top_n_features=top_n_features)
print('RF 选择完毕')
#Adaboost
abr = ensemble.AdaBoostRegressor()
abr_grid = GridSearchCV(abr,rf_param_grid,cv=10,n_jobs=25)
abr_grid.fit(X,Y)
top_n_features_bgr = get_top_k_feature(features=features,model=abr_grid,top_n_features=top_n_features)
print('Adaboost选择完毕')
#ExtraTree
etr = ensemble.ExtraTreesRegressor()
etr_grid = GridSearchCV(etr,rf_param_grid,cv=10,n_jobs=25)
etr_grid.fit(X,Y)
top_n_features_etr = get_top_k_feature(features=features,model=etr_grid,top_n_features=top_n_features)
print('ExtraTree选择完毕')
#融合以上3个模型
features_top_n = pd.concat([top_n_features_rf,top_n_features_bgr,top_n_features_etr],ignore_index=True).drop_duplicates()
print(features_top_n)
print(len(features_top_n))
return features_top_n
1、通过方差筛选:sklearn中的VarianceThreshold类可以用来做方差选择
2、卡方检验:sklearn中的chi2类可以用来做卡方检验
3、互信息:sklearn中的mutual_info_classif(分类)和mutual_info_regression(回归)来计算各个输入特征和输出值之间的互信息
4、sklearn的SelectFromModel函数
5、sklearn有一个feature_select模块可以做特征选择。
6、 线性回归模型中的ANOVA方法。 来自sklearn里的
7、 RandomForestClassifier,自带 feature_importances_ 功能。返回特征向量的重要性。
可视化可以更直观的查看特征的重要性情况。简单实例如下:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.ensemble import ExtraTreesClassifier
# 生成测试数据
X,y = make_classification(n_samples=1000, n_features=10, n_informative=3, n_classes=2)
# 选取学习器
forest = ExtraTreesClassifier(n_estimators=250, random_state=0)
forest.fit(X,y)
# 输出特征重要性
importances = forest.feature_importances_
std = np.std([tree.feature_importances_ for tree in forest.estimators_], axis=0)
indices = np.argsort(importances)[::-1]
# 打印
print("Feature ranking:")
for f in range(X.shape[1]):
print("%d. feature %d (%f)" % (f+1, indices[f], importances[indices[f]]))
# 绘图
plt.figure()
plt.title("Feature importances")
plt.bar(range(X.shape[1]), importances[indices], color='r', yerr=std[indices], align='center')
plt.xticks(range(X.shape[1]), indices)
plt.xlim([-1, X.shape[1]])
plt.show()
Permuation Importance,Partial Dependence Plots,SHAP Values,Summary Plots
对于非深度学习特征重要性评估(筛选),可以在训练预测之前进行数据的清洗,特征筛选;也可以在训练过程中对特征进行筛选,通常为与决策树相关的算法(RF,xgboost等)。回归任务使用特征的系数作为特征重要性的判断依据。
这是暂时整理的方法概要,后续会查阅深度学习方法中相关的特征重要性评估方法。
参考:
https://www.cnblogs.com/nxf-rabbit75/p/11122415.html
https://www.cnblogs.com/nxf-rabbit75/p/11159320.html
https://www.cnblogs.com/nxf-rabbit75/p/11125001.html
https://www.dazhuanlan.com/2020/01/17/5e20e2321c9df/
https://www.dazhuanlan.com/2020/01/17/5e20e2321c9df/
https://www.jianshu.com/p/1c4ec02dd33f
https://blog.csdn.net/qq_38844711/article/details/103518857
https://www.zhihu.com/question/296523764?sort=created
https://www.zhihu.com/question/319953307