具体的前面已经介绍过了一些方法来提取特征,下面继续介绍包裹法和嵌入法来提取特征。
特征的选取方式一共有三种,在sklearn实现了的包裹式(wrapper)特诊选取只有两个递归式特征消除的方法,如下:
recursive feature elimination ( RFE )
通过学习器返回的 coef_ 属性 或者 feature_importances_ 属性来获得每个特征的重要程度。 然后,从当前的特征集合中移除最不重要的特征。在特征集合上不断的重复递归这个步骤,直到最终达到所需要的特征数量为止。RFECV
通过交叉验证来找到最优的特征数量。如果减少特征会造成性能损失,那么将不会去除任何特征。这个方法用以选取单模型特征相当不错,但是有两个缺陷,一,计算量大。二,随着学习器(评估器)的改变,最佳特征组合也会改变,有些时候会造成不利影响。PFE 自身的特性,使得我们可以比较好的进行手动的特征选择,但是同样的他也存在原模型在去除特征后的数据集上的性能表现要差于原数据集,这和方差过滤一样,同样是因为去除的特征中保留有有效信息的原因。下面的代码就很好的展示了这种现象。
from sklearn.feature_selection import RFE, RFECV
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn import model_selection
iris = load_iris()
X, y = iris.data, iris.target
## 特征提取
estimator = LinearSVC()
selector = RFE(estimator=estimator, n_features_to_select=2)
X_t = selector.fit_transform(X, y)
### 切分测试集与验证集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y,
test_size=0.25, random_state=0, stratify=y)
X_train_t, X_test_t, y_train_t, y_test_t = model_selection.train_test_split(X_t, y,
test_size=0.25, random_state=0,
stratify=y)
## 测试与验证
clf = LinearSVC()
clf_t = LinearSVC()
clf.fit(X_train, y_train)
clf_t.fit(X_train_t, y_train_t)
print("Original DataSet: test score=%s" % (clf.score(X_test, y_test)))
print("Selected DataSet: test score=%s" % (clf_t.score(X_test_t, y_test_t)))
Original DataSet: test score=0.973684210526
Selected DataSet: test score=0.947368421053
从上面的代码我们可以看出,原模型的性能在使用RFE后确实下降了,如同方差过滤,单变量特征选取一样,这种方式看来使用这个方法我们也需要谨慎一些啊。
print("N_features %s" % selector.n_features_) # 保留的特征数
print("Support is %s" % selector.support_) # 是否保留
print("Ranking %s" % selector.ranking_) # 重要程度排名
N_features 2
Support is [False True False True]
Ranking [3 1 2 1]
使用交叉验证来保留最佳性能的特征。不过这里的交叉验证的数据集切割对象不再是 行数据(样本),而是列数据(特征),同时学习器本身不变,最终得到不同特征对于score的重要程度,然后保留最佳的特征组合。其分割方式类似于随机森林中的列上子采样。
scorer
作为输入对象对于 迭代器或者没有输入(None), 如果 y 是 二进制 或者 多类,则使用 sklearn.model_selection.StratifiedKFold
. 如果学习器是个分类器 或者 如果 y 不是 二进制 或者 多类,使用 sklearn.model_selection.KFold
.
如果你对于前面的花不太理解,那么你可以看一下下面的例子,或者自己动手尝试一下
对于前面RFE中的数据集进行验证,应当应该保留那些特征:
N_features 4
Support is [ True True True True]
Ranking [1 1 1 1]
Grid Scores [ 0.91421569 0.94689542 0.95383987 0.96691176]
好吧,看来都应该保留
RFECV的强大作用:
Optimal number of features : 3
Ranking of features : [ 5 1 12 19 15 6 17 1 2 21 23 11 16 10 13 22 8 14 1 20 7 9 3 4 18]
(划重点了,咳咳)
通过RFECV我们得知,原来只需要三个特征就好了,首先这确实符合我们构造的数据,同时这也向我们展示了RFECV的强大潜力,看来它将成为我们之后进行特征选取的一个重要助手
嵌入方法提取特征
使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。使用feature_selection库的SelectFromModel类结合带L1惩罚项的逻辑回归模型,来选择特征的代码如下:
1 from sklearn.feature_selection import SelectFromModel
2 from sklearn.linear_model import LogisticRegression
3
4 #带L1惩罚项的逻辑回归作为基模型的特征选择
5 SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(iris.data, iris.target)
3.3.2 基于树模型的特征选择法
树模型中GBDT可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型,来选择特征的代码如下:
1 from sklearn.feature_selection import SelectFromModel
2 from sklearn.ensemble import GradientBoostingClassifier
3
4 #GBDT作为基模型的特征选择
5 SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
具体的例子看下一篇文章。谢谢、