特征选择

在机器学习工程中,特征工程才是最重要,特征决定着算法的上限,特征工程中最为重要和最为基础的两种技术,就是特征选择和特征降维。特征选择和特征降维的目的很简单,就是选择出或变换出更优的特征,从而更利于我们学习算法的学习

这特征选择的目的和特征降维的目的类似,但是特征选择和特征降维具有本质的区别,特征降维的主要特点是通过一个数学变换进行降维,而特征选择就是从众多特征中剔除不重要的特征,从而保留重要的特征。虽然简单粗暴,但是极其容易实现,并易于使用,所以在工程中特征选择的使用频率要高于特征降维。下面给大家说一下特征选择。

通常来说,我们需要从两点来考虑:

  1. 特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。
  2. 特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。除移除低方差法外,本文介绍的其他方法均从相关性考虑。

根据不同的形式,我们可以将特征选择分为三种:

  • 过滤法(Filter):按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。
  • 封装法(Wrapper):根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。
  • 嵌入法(Embedded):先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。类似于Filter方法,但是是通过训练来确定特征的优劣。

过滤法(Filter)

  • 方差选择法:计算各个特征方差,选择方差大于阈值的特征。当特征值都是离散型变量的时候这种方法才能用,如果是连续型变量,就需要将连续变量离散化之后才能用。可以把它作为特征选择的预处理,先去掉那些取值变化小的特征,然后再从接下来提到的的特征选择方法中选择合适的进行进一步的特征选择。可以从from sklearn.feature_selection import VarianceThreshold 使用这个方法。

  • 相关系数法:计算各个特征的Pearson相关系数 (对于回归问题(y连续)),前阵子写的文章介绍这些系数和python代码实现。 https://blog.csdn.net/weixin_43172660/article/details/83960665

  • 卡方(Chi2)检验:就是统计样本的实际观测值与理论推断值之间的偏离程度,实际观测值与理论推断值之间的偏离程度就决定卡方值的大小**(对于分类问题(y离散)),卡方值越大,越不符合;卡方值越小,偏差越小,越趋于符合。可以从from sklearn.feature_selection import chi2**使用这个方法。下面介绍一个例子,从4个特征里面筛选出两个最重要的特征。

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
iris = load_iris()
X, y = iris.data, iris.target
X.shape
(150, 4)
#移除得分前 k 名以外的所有特征(取top k)
X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
X_new.shape
(150, 2)
  • 互信息法:计算各个特征的信息增益

以上就是一些常用的过滤法,对于过滤法,优点: 快速, 只需要基础统计知识。缺点:特征之间的组合效应难以挖掘。

封装法(Wrapper)

  • 递归消除特征法:递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,移除平方值最小的那个序号i对应的特征,再基于新的特征集进行下一轮训练。以此类推,直到剩下的特征数满足我们的要求为止。下面是一篇具体实现的文章:https://blog.csdn.net/fontthrone/article/details/79004874

优点: 直接面向算法优化, 不需要太多知识。缺点: 庞大的搜索空间, 需要定义启发式策略。

嵌入法(Embedded)

  • 使用带惩罚项的基模型进行特征选择:比如LR加入正则。通过L1正则项来选择特征:L1正则方法具有稀疏解的特性,因此天然具备特征选择的特性,但是要注意,L1没有选到的特征不代表不重要,原因是两个具有高相关性的特征可能只保留了一个,如果要确定哪个特征重要应再通过L2正则方法交叉检验。
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
X.shape
(150, 4)
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X, y)
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
X_new.shape
(150, 3)
  • 树模型的特征选择(随机森林、决策树):训练能够对特征打分的预选模型:RandomForest和Logistic Regression等都能对模型的特征打分,通过打分获得相关性后再训练最终模型。
 from sklearn.ensemble import ExtraTreesClassifier
 from sklearn.datasets import load_iris
 from sklearn.feature_selection import SelectFromModel
 iris = load_iris()
 X, y = iris.data, iris.target
 X.shape
 (150, 4)
 clf = ExtraTreesClassifier()
 clf = clf.fit(X, y)
 clf.feature_importances_  
 array([ 0.04...,  0.05...,  0.4...,  0.4...])
 model = SelectFromModel(clf, prefit=True)
 X_new = model.transform(X)
 X_new.shape               
 (150, 2)

优点:效果最好速度最快,模式单调,快速并且效果明显。缺点:但是如何参数设置, 需要深厚的背景知识。

总结

各个方法有各个的特点,具体选用哪个方法,需要我们多进行尝试!

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐