利用scikit-learn进行机器学习:特征工程(二)特征选择

浏览: 5629

特征选择 

1 概述 

2 特征选择之Filter 

  2.1 方差选择法 

  2.2 卡方检验法 

  2.3 互信息法 

3 特征选择之Wrapper 

  3.1 递归式特征消除法 

4 特征选择之Embedded 

  4.1 基于惩罚项的特征选择法 

  4.2 基于树模型的特征选择法

image.png

1 概述 

    相信有打过kaggle比赛的筒子们一定不会小看特征工程这个工作。既然机器学习界早有“数据和特征决定模型上限的说法”,那么特征工程就必须是我们学习机器学习必须重视的过程。在上一节推送中,小编跟大家介绍了特征工程中数据预处理的基本方法,在对数据进行预处理之后,我们就需要从数据中选取相应的特征来进行训练了。所以,特征选择简单而言就是从数据中选取一些特征来进行建模。

    当然你可能也猜到了,事情并没有那么简单。在选取特征的时候,并不是说我们看哪个特征比较顺眼或者主观臆测某些特征丢入模型中跑一下,然后效果不好再踢出来换一些特征。特征选择的本质在于如何从数据集中选到一个最优的子集,如果这个选出来的子集在我们使用的机器学习算法上有着相对较好的表现的话,那么可以认为我们的特征选择工作做得还算可以。所以,关于特征选择的核心内容就是如何选取能够在一些算法上表现还算可以的数据子集。

    在特征工程中,特征选择有着一套较为完整的方法论。总结起来主要包括 Filter(过滤法)Wrapper(包装法)Embedded(嵌入法),在使用上这些方法在Python的sklearn中都有相应的模块来实现,sklearn中的feature_selection是特征选择的一把好手。

2 特征选择方法之Filter 

    即过滤法,按照发散性或者相关性对各个特征进行评分,通过设定一些阈值或者待选择阈值的个数来选择特征。在scikit-learn中过滤法具体包括方差选择法、卡方检验法和互信息法,在feature_selection模块中均可轻易实现。 2.1 方差选择法 所谓方差选择法,就是剔除那些零方差或者低方差的特征,如果一个特征方差为零或者很低,即样本在这个特征上表现基本一致,差异性较小,这样的特征对于我们做预测并无用处。假设数据集中有一个特征为布尔值,现在我们想移除一些在整个数据中特征值为0或者1的比例超过80%的特征,我们可以通过0.8*(1-0.8)这样一个阈值在sklearn中进行选择:

  1. from sklearn.feature_selection import VarianceThreshold

  2. X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]

  3. sel = VarianceThreshold(threshold=(.8 * (1 - .8)))

  4. sel.fit_transform(X)

  5. array([[0, 1],

  6.       [1, 0],

  7.       [0, 0],

  8.       [1, 1],

  9.       [1, 0],

  10.       [1, 1]])

    第一列值为0的比例超过了80%,在结果中VarianceThreshold剔除这一列。

2.2 卡方检验法 

    在统计学中,卡方检验量用来检验定性变量之间相关下的统计量。在sklearn中,卡方检验法除了通过检验定性变量自变量对因变量的相关性来筛选特征之外,还可以用于稀疏数据的特征选择。在feature_selection模块中,卡方检验法筛选特征模块为chi2.具体应用实例如下:

  1. from sklearn.datasets import load_iris

  2. from sklearn.feature_selection import SelectKBest

  3. from sklearn.feature_selection import chi2

  4. iris = load_iris()

  5. X, y = iris.data, iris.target

  6. X.shape

  7. (150, 4)

  8. X_new = SelectKBest(chi2, k=2).fit_transform(X, y)

  9. X_new.shape

  10. (150, 2)

2.3 互信息法 

    和卡方检验法一样,互信息法也是用于定性变量之间相关性的统计方法。互信息法通过信息计算公式来表示定性自变量对定性因变量的相关性,但该方法也可用于筛选定量数据特征,featureselection 模块中的 mutualinforegression  和  mutualinfoclassif  通常结合起来利用可以计算两个随机变量之间的线性相关程度。具体应用可参考代码:http://sklearn.apachecn.org/cn/0.19.0/modules/generated/sklearn.featureselection.mutualinfoclassif.html 

    以上便是Filter方法进行特征选择,总体而言,Filter方法并不复杂,但想运用得当还需一番功力。

3 特征选择方法之Wrapper 

    Wrapper方法可取名为包裹式方法,就是选定一些算法,根据算法在数据上的表现来选择特征集合,一般选用的算法包括随机森林、支持向量机和k近邻等常用算法。 3.1 递归式特征消除法 递归式特征消除法,听起来就感觉很复杂,简单来说就是在给定一个外部评估器的条件下,对数据特征赋予一定的权重,通过考虑越来越小的特征集合来递归的选择特征。首先评估器在初始的特征集合上面训练且特征的重要程度由一个featureimportance属性获得。然后从当前的特征集合中提出最不重要的特征,不断重复递归这个步骤,直到达到所需要的特征数量为止。如此可见,递归式特征消除法开始关键的一步在于指定一个性能较优的评估器。具体应用实例如下,该例中通过递归式特征消除来自动调整交叉验证中选择的特征数。

importmatplotlib.pyplot asplt

from sklearn.svm import SVC

fromsklearn.model_selection importStratifiedKFold

from sklearn.feature_selection importRFECV

fromsklearn.datasets importmake_classification


X, y = make_classification(n_samples=1000, n_features=25, n_informative=3,n_redundant=2, n_repeated=0, n_classes=8,

n_clusters_per_class=1, random_state=0)svc = SVC(kernel="linear")

rfecv = RFECV(estimator=svc, step=1, cv=StratifiedKFold(2),scoring='accuracy')

rfecv.fit(X, y)


print("Optimal number of features : %d" % rfecv.n_features_)


plt.figure()

plt.xlabel("Number of features selected")

plt.ylabel("Cross validation score (nb of correct classifications)")

plt.plot(range(1, len(rfecv.grid_scores_) + 1), rfecv.grid_scores_)

plt.show()

Optimal number of features : 3

image.png

4 特征选择方法之Embedded 

    Embedded方法即嵌入法,在三大经典特征选择方法中难度系数最高,考验的是各位少侠的机器学习内功程度。嵌入式特征选择方法主要包括基于惩罚项和基于树模型的特征选择方法。 

4.1 基于惩罚项的特征选择法 

    熟悉机器学习正则化理论方法的筒子一定了解L0、L1和L2正则化算子。而基于惩罚项的特征选择方法就是利用正则化思想将一些特征属性的权重变为零,除了上面提到的三大正则化算子,常用的正则化方法还包括Elastic Net、多任务弹性网络、最小角回归等。例如基于L1范数的正则化方法可以实现稀疏,实现稀疏的好处除了模型的可解释增强之外就是还可以进行特征选择。 当我们的目标是降低训练数据的维度时,L1范数可以与SelectFromModel一起使用来选择非零系数:

fromsklearn.svm import

LinearSVC

fromsklearn.datasets importload_iris

from sklearn.feature_selection importSelectFromModel

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)

4.2 基于树模型的特征选择方法 

    基于树模型的评估器也是计算特征重要性的利器,目前为广大kaggler所喜爱的XGBoost就可以给出数据集的特征重要程度。基于树模型的特征选择例子如下:

from sklearn.ensemble importExtraTreesClassifier

from sklearn.datasets import load_iris

fromsklearn.feature_selection importSelectFromModel

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)

    除了特征选择方法之外,有时候我们还需要从已有的特征中构造出一些新的特征,这种特征构造的方法也叫做特征提取,除了需要我们掌握必要的机器学习方法之外,对数据集的理解和相关的领域知识都是我们最后模型的预测准确率好坏的因素之一。

参考资料:

http://scikit-learn.org/stable/modules/preprocessing.html#preprocessing

  http://www.cnblogs.com/jasonfreak/p/5448385.html

image.png

推荐 1
本文由 鲁伟 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册