1.13. 特征选择#
中的类 sklearn.feature_selection
模块可用于对样本集进行特征选择/降维,以提高估计器的准确性分数或提高其在极高维度数据集上的性能。
1.13.1. 删除低方差的功能#
VarianceThreshold
是特征选择的简单基线方法。它会删除方差不满足某个阈值的所有特征。默认情况下,它会删除所有零方差特征,即所有样本中具有相同值的特征。
例如,假设我们有一个具有布尔特征的数据集,并且我们希望删除超过80%的样本中所有为1或0(开或关)的特征。布尔特征是伯努里随机变量,此类变量的方差由下式给出
所以我们可以使用阈值进行选择 .8 * (1 - .8)
>>> 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]]
>>> sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
>>> sel.fit_transform(X)
array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
不出所料, VarianceThreshold
已删除第一列,这有可能 \(p = 5/6 > .8\) 包含一个零。
1.13.2. 单变量特征选择#
单变量特征选择的工作原理是根据单变量统计测试选择最佳特征。它可以被视为估计器的预处理步骤。Scikit-learn将特征选择例程公开为实现 transform
方法:
SelectKBest
删除除 \(k\) 最高得分特征SelectPercentile
删除除用户指定的最高评分百分比之外的所有要素对每个特征使用常见的单变量统计测试:假阳性率
SelectFpr
错误发现率SelectFdr
或家庭明智的错误SelectFwe
.GenericUnivariateSelect
允许通过可配置策略执行单变量特征选择。这允许使用超参数搜索估计器来选择最佳的单变量选择策略。
例如,我们可以使用F测试来检索数据集的两个最佳特征,如下所示:
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectKBest
>>> from sklearn.feature_selection import f_classif
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
>>> X_new = SelectKBest(f_classif, k=2).fit_transform(X, y)
>>> X_new.shape
(150, 2)
这些对象将返回单变量分数和p值(或仅返回 SelectKBest
和 SelectPercentile
):
对于回归:
r_regression
,f_regression
,mutual_info_regression
分类:
chi2
,f_classif
,mutual_info_classif
基于F检验的方法估计两个随机变量之间的线性依赖程度。另一方面,互信息方法可以捕捉任何类型的统计依赖性,但由于是非参数,它们需要更多样本才能准确估计。注意到 \(\chi^2\) -test只应用于非负特征,如频率。
警告
注意不要在分类问题中使用回归评分函数,你会得到无用的结果。
备注
的 SelectPercentile
和 SelectKBest
还支持无监督特征选择。我们需要提供一个 score_func
哪里 y=None
.的 score_func
应在内部使用 X
来计算分数。
示例
1.13.3. 递归特征消除#
给定一个外部估计器,为特征分配权重(例如,线性模型的系数),循环特征消除的目标 (RFE
)是通过迭代考虑越来越小的特征集来选择特征。首先,在初始特征集上训练估计器,并通过任何特定属性(例如 coef_
, feature_importances_
)或可调用。然后,从当前特征集中删除最不重要的特征。该过程在修剪后的集中循环重复,直到最终达到要选择的特征的所需数量。
RFECV
在交叉验证循环中执行RFE以找到最佳数量的特征。更详细地说,所选要素的数量是通过调整 RFE
不同交叉验证拆分上的选择器(由 cv
参数)。的性能 RFE
选择器的评估使用 scorer
用于不同数量的所选特征并聚集在一起。最后,将分数跨折叠取平均,并将所选特征的数量设置为使交叉验证分数最大化的特征数量。
示例
递归特征消除 :一个递归特征消除示例,显示了数字分类任务中像素的相关性。
sphx_glr_auto_examples_feature_selection_plot_rfe_with_cross_validation.py :一个循环特征消除示例,通过交叉验证自动调整选择的特征数量。
1.13.4. 使用SelectFromModel选择特征#
SelectFromModel
是一个元转换器,可以与任何通过特定属性(例如)为每个要素分配重要性的估计器一起使用 coef_
, feature_importances_
)或通过 importance_getter
试穿后可致电。如果要素值的相应重要性低于提供的重要性,则要素被视为不重要并被删除 threshold
参数.除了用数字指定阈值之外,还有内置的使用字符串参数查找阈值的方法。可用的参数是“mean”、“median”和这些参数的浮点倍数,如“0.1*mean”。并结合 threshold
标准,可以使用 max_features
参数用于设置要选择的要素数量限制。
有关如何使用的示例,请参阅以下各节。
示例
1.13.4.1. 基于L1的特征选择#
Linear models 惩罚与L1范数有稀疏的解决方案:他们的许多估计系数为零。当目标是减少数据的维度以与另一个分类器一起使用时,它们可以与 SelectFromModel
选择非零系数。特别是,对此有用的稀疏估计器是 Lasso
对于回归,以及 LogisticRegression
和 LinearSVC
用于分类::
>>> from sklearn.svm import LinearSVC
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
>>> X, y = load_iris(return_X_y=True)
>>> 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)
对于支持者服务器和逻辑回归,参数C控制稀疏性:C越小,选择的特征越少。对于Lasso,Alpha参数越高,选择的功能就越少。
示例
L1-恢复和压缩传感#
对于α的好选择, Lasso 只要满足某些特定条件,就可以仅使用很少的观察就完全恢复非零变量的精确集。特别是,样本数量应该“足够大”,否则L1模型将随机执行,其中“足够大”取决于非零系数的数量、特征数量的对数、噪音量、非零系数的最小绝对值以及设计矩阵X的结构。此外,设计矩阵必须显示某些特定属性,例如不太相关。关于使用Lasso进行稀疏信号恢复,请参阅压缩感知的示例: 压缩感知:使用L1先验进行断层扫描重建(Lasso) .
没有一般规则来选择用于恢复非零系数的α参数。它可以通过交叉验证来设置 (LassoCV
或 LassoLarsCV
),尽管这可能会导致模型受到惩罚不足:包括少量不相关的变量不会损害预测分数。BIC (LassoLarsIC
相反,)倾向于设置较高的alpha值。
引用
Richard G. Baraniuk“压缩感知”,IEEE信号处理杂志 [120] 2007年7月http://users.isr.ist.utl.pt/~aguiar/CS_notes.pdf
1.13.4.2. 基于树的特征选择#
基于树的估计器(请参阅 sklearn.tree
模块和树木森林 sklearn.ensemble
模块)可用于计算基于杂质的特征重要性,这反过来可用于丢弃不相关的特征(当与 SelectFromModel
元变压器)::
>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectFromModel
>>> X, y = load_iris(return_X_y=True)
>>> X.shape
(150, 4)
>>> clf = ExtraTreesClassifier(n_estimators=50)
>>> 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)
示例
树木森林的重要性 :显示实际有意义特征恢复的合成数据示例。
排列重要性与随机森林特征重要性(Millennium) :讨论使用基于杂质的特征重要性作为特征相关性代理的警告的例子。
1.13.5. 顺序特征选择#
顺序特征选择 [sfs] (SFS)中可用 SequentialFeatureSelector
Transformer。SFS可以向前或向后:
Forward-SFS是一个贪婪的过程,它迭代地找到最佳新功能以添加到所选功能集中。具体来说,我们最初从零特征开始,并找到当估计器在这个单一特征上训练时最大化交叉验证分数的一个特征。选择第一个特征后,我们通过向所选特征集中添加新特征来重复该过程。当达到所需的选定要素数量(由 n_features_to_select
参数.
Backward-SFS遵循同样的想法,但方向相反:我们不是从没有功能开始并贪婪地添加功能开始,而是从 all 特色与魅力 remove 从设置的功能。的 direction
参数控制使用正向还是反向SFS。
有关顺序特征选择的详细信息#
一般来说,向前选择和向后选择不会产生等效的结果。此外,根据请求的选定特征数量,一个可能比另一个快得多:如果我们有10个特征并要求7个选定特征,则向前选择将需要执行7次迭代,而向后选择将只需要执行3次迭代。
SFS与 RFE
和 SelectFromModel
因为它不需要底层模型公开 coef_
或 feature_importances_
属性然而,与其他方法相比,考虑到需要评估更多的模型,这种方法可能较慢。例如,在向后选择中,从 m
特征以 m - 1
使用k重交叉验证的要素需要进行匹配 m * k
模特,而 RFE
只需要一次调整,并且 SelectFromModel
总是只进行一次拟合,不需要迭代。
引用
示例
1.13.6. 作为管道一部分的要素选择#
特征选择通常被用作进行实际学习之前的预处理步骤。在scikit-learn中执行此操作的建议方法是使用 Pipeline
clf = Pipeline([
('feature_selection', SelectFromModel(LinearSVC(penalty="l1"))),
('classification', RandomForestClassifier())
])
clf.fit(X, y)
在这个片段中,我们使用了 LinearSVC
加上 SelectFromModel
评估特征的重要性并选择最相关的特征。然后 RandomForestClassifier
根据转换后的输出进行训练,即仅使用相关特征。您可以使用其他特征选择方法以及提供评估特征重要性的方法的分类器执行类似的操作。看到 Pipeline
示例以了解更多详细信息。