码迷,mamicode.com
首页 > 其他好文 > 详细

特征选择

时间:2018-04-09 17:20:52      阅读:1002      评论:0      收藏:0      [点我收藏+]

标签:测试   随机   回归   lan   tar   线性   add   线性模型   基于   

特征选择

特征选择是从数据集的诸多特征里面选择和目标变量相关的特征,去掉那些不相关的特征。

特征选择分为两个问题:一个是子集搜索问题,另外一个是子集评价问题。比如将前向搜索和信息熵评价这两种策略进行结合就是决策树算法,事实上决策树算法可以进行特征选择。sklearn当中的“树形”算法的feature_importances_就是特征重要性的体现。

常用的特征选择分为三类:过滤式(filter),包裹式(wrapper)和嵌入式(embedding)

过滤式: 先进行特征选择,然后进行后续的训练,特征选择和后续的训练过程没有关系。

包裹式: 将机器学习的性能当做子集评价标准。

嵌入式: 将特征选择和机器学习融为一体,两者在同一个优化过程当中完成。和包裹式学习不同的是,包裹式中的子集选择和机器训练过程还是有区分的,而嵌入式将这两个过程融为一个过程。

sklearn当中的特征选择

1:移除方差较低的特征 VarianceThreshold方法

移除方差比较低的特征,使用方差作为特征选择的一个标准,是因为观察到这么一个事实,方差较低的样本差异不大,对我们的目标变量贡献比较低,所以我们移除方差比较低的样本。

举个例子,假如特征是boolean类型,那么它是伯努利随机变量,它的方差为$D(X) = p(1-p)$。 假如我们想要移除特征当中有超过80%要么是0要么是1的样本,那么我们把方差的阈值定义为 0.8*(1-0.8)=0.16

from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
#样本为:
‘‘‘
0 0 1
0 1 0
0 1 1
0 1 0
0 1 1
‘‘‘
clf = VarianceThreshold(threshold=(0.8 * (1-0.8)))
print(clf.fit_transform(X))

输出结果如下,可以看到把第一列给移除了:

[[0 1]
 [1 0]
 [0 0]
 [1 1]
 [1 0]
 [1 1]]

2:单变量特征选择

利用统计学当中的方差假设检验的知识来对模型的特征进行选择,

其中SelectKBest是用来选择k个最高分数的特征,SelectPercentile是选择百分比个分数最高的特征

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
print(X.shape)
X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
print(X_new.shape)

结果如下:

(150, 4)
(150, 2)

上面选用的是$\chi^2$测试,

其它的还有:对于回归问题:f_regression, mutual_info_regression 。对于分类问题有: chi2, f_classif, mutual_info_classif

3: 回归特征消除

Recursive feature elimination(RFE) 是使用回归的方法,在一个模型里面不断的减少不重要的特征,最后达到我们要的特征。下面是RFE中的参数:

estimator:输入需要的模型。

n_features_to_select:需要选择的特征,默认选择半数。

step:如果大于等于1,那么每次迭代的时候去除step个,如果是0到1之间的小数,代表每次迭代去除的百分比。

下面是在手写数字识别数据集当中进行像素选择的例子:

from sklearn.datasets import load_digits
from sklearn.svm import SVC
from sklearn.feature_selection import RFE
import matplotlib.pyplot as plt
digits = load_digits()
X = digits.images.reshape((len(digits.images), -1))
y = digits.target

svc = SVC(kernel=linear, C=1)
rfe = RFE(svc, n_features_to_select=1, step=1)
rfe.fit(X, y)
ranking = rfe.ranking_.reshape(digits.images[0].shape)

plt.matshow(ranking, cmap=plt.cm.Blues)
plt.colorbar()
plt.title("Ranking of pixels with RFE")
plt.show()

输出结果如下:

技术分享图片

还有一个方法是RFECV,是将回归特征消除和交叉验证结合在一起了。 那么它和RFE有什么不同哪?RFE是使用模型当中的coef_或者feature_importances_这两个属性来评价特征的好坏,前者是线性模型的特征相关系数,后者是树模型的重要性。而RFECV是使用交叉验证来评估特征对模型的好坏,可以传入自己的评分函数。

 

使用SelectFromModel来对特征进行选择

SelectFromModel使用了core_和feature_importances_,前者在线性模型当中使用,后者在树模型当中使用。

4:基于L1正则化的特征选择。

线性模型使用L1正则化作为罚函数,在这种情况下系数当中有很多是0,这些为0的系数是不重要的系数,可以去掉,这就起到了特征选择的作用。它可以和SelectFromModel一起结合使用。

from sklearn.datasets import load_iris
from sklearn.svm import LinearSVC
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
print(X.shape)
lsvc = LinearSVC(C=0.01, penalty=‘l1‘, dual=False).fit(X, y)
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
print(X_new.shape)

结果如下:

(150, 4)
(150, 3)

5:基于树结构的特征选择:

from sklearn.datasets import load_iris
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
clf = ExtraTreesClassifier()
clf = clf.fit(X, y)
print(clf.feature_importances_)
print(X.shape)
model = SelectFromModel(clf, prefit=True)
X_new = model.transform(X)
print(X_new.shape)

结果如下:

[0.09666543 0.06817362 0.50460169 0.33055925]
(150, 4)
(150, 2)

 

 

总结一下:

第一种方法和第二种方法都属于过滤式,前者利用方差信息,后者利用统计学中的单变量统计测试方法进行特征选择,特征的选择和后续的训练没有关系。 第三种方法RFE以及RFECV属于包裹式,使用递归的方法进行特征选择,使用模型的结果来进行特征评估。第四种和第五种方法分别讲了利用线性模型和树模型进行特征选择的过程,属于嵌入式。 嵌入式和包裹式的不同从上面的算法当中也可以看出来,嵌入式将模型选择和机器学习看做一个优化过程,而包裹式则是利用模型的性能当做特征的评价标准。

 

 

参考:

Feature selection

周志华 《机器学习》

特征选择

标签:测试   随机   回归   lan   tar   线性   add   线性模型   基于   

原文地址:https://www.cnblogs.com/jiaxin359/p/8760094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!