Scikit-Learn RFECV 仅基于网格分数的特征数量

Posted

技术标签:

【中文标题】Scikit-Learn RFECV 仅基于网格分数的特征数量【英文标题】:Scikit-Learn RFECV number of features based on grid scores only 【发布时间】:2016-08-31 12:01:22 【问题描述】:

从 scikit-learn RFE documentation 中,算法会依次选择更小的特征集,并且只保留权重最高的特征。低权重的特征被丢弃,这个过程不断重复,直到剩余的特征数量与用户指定的匹配(或默认为原始特征数量的一半)。

RFECV docs 表示特征按 RFE 和 KFCV 排序。

documentation example for RFECV 中显示的代码中有一组 25 个功能:

from sklearn.svm import SVC
from sklearn.cross_validation import StratifiedKFold
from sklearn.feature_selection import RFECV,RFE
from sklearn.datasets import make_classification

# Build a classification task using 3 informative features
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)

# Create the RFE object and compute a cross-validated score.
svc = SVC(kernel="linear")
# The "accuracy" scoring is proportional to the number of correct
# classifications
rfecv = RFECV(estimator=svc, step=1, cv=StratifiedKFold(y, 2),scoring='accuracy')
rfecv.fit(X, y)
rfe = RFE(estimator=svc, step=1)
rfe.fit(X, y)

print('Original number of features is %s' % X.shape[1])
print("RFE final number of features : %d" % rfe.n_features_)
print("RFECV final number of features : %d" % rfecv.n_features_)
print('')

import numpy as np
g_scores = rfecv.grid_scores_
indices = np.argsort(g_scores)[::-1]
print('Printing RFECV results:')
for f in range(X.shape[1]):
    print("%d. Number of features: %d;
                  Grid_Score: %f" % (f + 1, indices[f]+1, g_scores[indices[f]]))

这是我得到的输出:

Original number of features is 25
RFE final number of features : 12
RFECV final number of features : 3

Printing RFECV results:
1. Number of features: 3; Grid_Score: 0.818041
2. Number of features: 4; Grid_Score: 0.816065
3. Number of features: 5; Grid_Score: 0.816053
4. Number of features: 6; Grid_Score: 0.799107
5. Number of features: 7; Grid_Score: 0.797047
6. Number of features: 8; Grid_Score: 0.783034
7. Number of features: 10; Grid_Score: 0.783022
8. Number of features: 9; Grid_Score: 0.781992
9. Number of features: 11; Grid_Score: 0.778028
10. Number of features: 12; Grid_Score: 0.774052
11. Number of features: 14; Grid_Score: 0.762015
12. Number of features: 13; Grid_Score: 0.760075
13. Number of features: 15; Grid_Score: 0.752003
14. Number of features: 16; Grid_Score: 0.750015
15. Number of features: 18; Grid_Score: 0.750003
16. Number of features: 22; Grid_Score: 0.748039
17. Number of features: 17; Grid_Score: 0.746003
18. Number of features: 19; Grid_Score: 0.739105
19. Number of features: 20; Grid_Score: 0.739021
20. Number of features: 21; Grid_Score: 0.738003
21. Number of features: 23; Grid_Score: 0.729068
22. Number of features: 25; Grid_Score: 0.725056
23. Number of features: 24; Grid_Score: 0.725044
24. Number of features: 2; Grid_Score: 0.506952
25. Number of features: 1; Grid_Score: 0.272896

在这个特定的例子中:

    对于 RFE:代码始终返回 12 个特征(大约 25 个特征的一半,正如文档中所预期的那样) 对于 RFECV,代码返回 1-25 的不同数字(不是特征数量的一半)

It seems to me that when RFECV is being selected, the number of features is being picked only based on the KFCV scores - i.e. the cross validation scores are over-riding RFE's successive pruning of features.

这是真的吗?如果想使用原生递归特征消除算法,那么 RFECV 是使用该算法还是使用它的混合版本?

在 RFECV 中,是否对修剪后剩余的特征子集进行交叉验证?如果是这样,在 RFECV 中每次修剪后保留了多少特征?

【问题讨论】:

【参考方案1】:

在交叉验证版本中,特征在每一步都重新排序,排名最低的特征被丢弃——这在文档中被称为“递归特征选择”。

如果您想将此与原始版本进行比较,则需要计算 RFE 选择的功能的交叉验证分数。我的猜测是 RFECV 的答案是正确的——从特征减少时模型性能的急剧提升来看,您可能有一些高度相关的特征正在损害模型的性能。

【讨论】:

1.是否在修剪特征之后进行交叉验证 - 即在截断的特征集上进行?另外为什么它只删除功能 - 这是一个规则吗? 2. 相关特征是指线性相关特征吗?或者特征之间是否存在任何其他类型的相关性? 是的,我们应该期待 3 个功能。我采用的代码仅来自文档示例,其目的是使用 3 个信息特征进行分类。但很明显,原生 RFE 并没有给出这个 - 如果我们不提前知道有多少特征存在,那么我们将使用 RFE,并在最后留下默认数量的特征(在这种情况下为 12 个)。在我看来,只有 RFECV 会在这里给出正确的答案......也许这只是原生 RFE 的一个重大限制 - 即它不能消除相关功能,因此这种情况需要网格分数? 是的,交叉验证是在修剪后完成的,RFECV 中有一个名为 step 的参数,它指定每一步要删除多少特征,默认为 1。我认为它可以是任何类型的相关性,尽管我不是 100% 了解不同类型的相关性将如何影响模型。 对于您的其他问题,交叉验证基本上是进行统计的“现代”方式,其他启发式方法(如标准 RFE)存在的原因是因为计算能力过去不可用。但是现在计算机很便宜,您几乎应该总是更喜欢交叉验证(或其他一些训练测试拆分)来评估模型性能3 非常感谢!这回答了我的问题。

以上是关于Scikit-Learn RFECV 仅基于网格分数的特征数量的主要内容,如果未能解决你的问题,请参考以下文章

使用嵌套在 GridSearchCV 中的 RFECV 时,如何避免使用 estimator_params?

使用 scikit-learn 进行递归特征消除和网格搜索

使用 scikit-learn 对 SVR 进行递归特征消除和网格搜索

从 gridsearchCV 中的 RFECV 检索选定的特征

与 RFECV 结合时如何在 Gridsearch 中使用“max_features”?

Scikit-learn 中的特征选择遇到了混合变量类型的问题