@chanvee
2015-05-20T19:28:35.000000Z
字数 3113
阅读 4452
Python
数据挖掘
模块sklearn.feature_selection可以用来在样本集上做特征选取/降维(feature selection/dimensionality reduction),要么提高预测器的准确性,要么可以提高其在高维数据集上的表现。
[VarianceThreshold](VarianceThreshold is a simple baseline approach to feature selection. It removes all features whose variance doesn’t meet some threshold. By default, it removes all zero-variance features, i.e. features that have the same value in all samples.) 是特征选取的一种基本方法。它会去除掉特征中所有不满足某个阈值的特征。默认情况下,它会去除掉所有zero-variance的特征, 比如说那些在所有样本上取值都一样的特征。
举个例子,假设我们有一个包含布尔特征(Boolean features)的数据集,然后我们想去除所有的在样本中超过80%的全为1或是全为0的特征 。由于Boolean特征是伯努利随机变量,变量的方差如下:
所以我们可以选择阈值0.8 * (1 - 0.8):
%doctest_mode #removing >>> manually
>>> 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)
Exception reporting mode: Context
Doctest mode is: OFF
array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
如所期望的,VarianceThreshold
去除掉了第一列,因为其为0的概率 p = 5/6 > 0.8。
单变量特征选取(Univariate feature selection)是基于单变量统计测试来选取最好的特征。它可以看作是预测器的一个预处理步骤。 Scikit-learn 通过以下的转变方法来实现特征的选取:
- SelectKBest 保留得分最高的K个特征
- SelectPercentile 保留用户指定的最高的百分比的特征
- 每个特征采用常用的单变量测试:false positive rate SelectFpr, false discovery rate SelectFdr, or family wise error SelectFwe.
- GenericUnivariateSelect可以用来做单变量特征
举个例子,我们用
>>> 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)
>>> X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
>>> X_new.shape
(150, 2)
这些对象可以以得分函数作为输入返回单变量的 p-values:
- For regression: f_regression
- For classification: chi2 or f_classif
如果你使用的是稀疏数据,那么只有 chi2可以在不使其稠密的前提下使用
给定一个外部的预测器可以对特征赋权重(比如线性模型的系数), recursive feature elimination (RFE)通过递归的考虑越来越小的特征集来选取特征 。首先,预测及会给初始的特征集的所有特征给一个相同的权值。然后, 那些权值的绝对值最小的特征会被从当前的特征集中去掉。递归的停止条件是达到了设定的期望的特征数。
线性模型通过L1范数进行惩罚时可能会有许多稀疏的解:比如许多稀疏都为0。当使用另一个分类器的目的是对数据进行降维,它会采取一个变换方法来选取非0的系数。特别的,基于这个目的,稀疏预测器中可以用linear_model.Lasso解决回归问题, linear_model.LogisticRegression 和 svm.LinearSVC 用于分类问题:
>>> from sklearn.svm import LinearSVC
>>> from sklearn.datasets import load_iris
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X.shape
(150, 4)
>>> X_new = LinearSVC(C=0.01, penalty="l1", dual=False).fit_transform(X, y)
>>> X_new.shape
(150, 3)
(150, 3)
当采用SVMs 和 logistic-regression, 参数 C 控制稀疏度: C 越小选取的特征越少。对于Lasso,参数 alpha越大,则选取的特征越少。
基于树的预测器(详见sklearn.tree模块 和 sklearn.ensemble module) 可以计算特征的重要性, 反过来也可以用于选取特征:
>>> from sklearn.ensemble import ExtraTreesClassifier
>>> from sklearn.datasets import load_iris
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X.shape
(150, 4)
>>> clf = ExtraTreesClassifier()
>>> X_new = clf.fit(X, y).transform(X)
>>> clf.feature_importances_
array([ 0.0574718 , 0.06609667, 0.46177457, 0.41465696])
X_new.shape
(150, 2)
特征选取通常是真正开始学习前的一个预处理步骤。在scikit-learn中推荐的额做法是利用sklearn.pipeline.Pipeline:
clf = Pipeline([
('feature_selection', LinearSVC(penalty="l1")),
('classification', RandomForestClassifier())
])
clf.fit(X, y)