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


我想使用scikit-learn为每个特征子集执行嵌套网格搜索和交叉验证,以执行递归特征消除。来自 RFECV 文档听起来像使用这种类型的操作 estimator_params 参数:

estimator_params : dict

    Parameters for the external estimator. Useful for doing grid searches.

但是,当我尝试将超参数网格传递给RFECV对象时

from sklearn.datasets import make_friedman1
from sklearn.feature_selection import RFECV
from sklearn.svm import SVR
X, y = make_friedman1(n_samples=50, n_features=10, random_state=0)
estimator = SVR(kernel="linear")
selector = RFECV(estimator, step=1, cv=5, estimator_params={'C': [0.1, 10, 100, 1000]})
selector = selector.fit(X, y)

我得到一个错误

  File "U:/My Documents/Code/ModelFeatures/bin/model_rcc_gene_features.py", line 130, in <module>
    selector = selector.fit(X, y)
  File "C:\Python27\lib\site-packages\sklearn\feature_selection\rfe.py", line 336, in fit
    ranking_ = rfe.fit(X_train, y_train).ranking_
  File "C:\Python27\lib\site-packages\sklearn\feature_selection\rfe.py", line 146, in fit
    estimator.fit(X[:, features], y)
  File "C:\Python27\lib\site-packages\sklearn\svm\base.py", line 178, in fit
    fit(X, y, sample_weight, solver_type, kernel, random_seed=seed)
  File "C:\Python27\lib\site-packages\sklearn\svm\base.py", line 233, in _dense_fit
    max_iter=self.max_iter, random_seed=random_seed)
  File "libsvm.pyx", line 59, in sklearn.svm.libsvm.fit (sklearn\svm\libsvm.c:1628)
TypeError: a float is required

如果有人能告诉我我做错了什么,非常感谢,谢谢!

编辑:

在安德烈亚斯的回应变得更加清晰之后,下面是RFECV结合网格搜索的一个工作示例。

from sklearn.datasets import make_friedman1
from sklearn.feature_selection import RFECV
from sklearn.grid_search import GridSearchCV
from sklearn.svm import SVR
X, y = make_friedman1(n_samples=50, n_features=10, random_state=0)
param_grid = [{'C': 0.01}, {'C': 0.1}, {'C': 1.0}, {'C': 10.0}, {'C': 100.0}, {'C': 1000.0}, {'C': 10000.0}]
estimator = SVR(kernel="linear")
selector = RFECV(estimator, step=1, cv=4)
clf = GridSearchCV(selector, {'estimator_params': param_grid}, cv=7)
clf.fit(X, y)
clf.best_estimator_.estimator_
clf.best_estimator_.grid_scores_
clf.best_estimator_.ranking_

1590
2018-05-22 19:53


起源

阅读此答案以避免警告 - Paulo Alves


答案:


不幸的是,RFECV仅限于交叉验证组件的数量。您无法使用它搜索SVM的参数。错误是因为SVC期望浮点数为C,并且您给它一个列表。

您可以执行以下两项操作之一:在RFECV上运行GridSearchCV,这将导致将数据拆分为两次折叠(GridSearchCV内部和RFECV内部),但搜索组件数量将是有效的,或者您可以执行GridSearchCV只是在RFE上,这将导致数据的单个分裂,但是对RFE估计器的参数进行非常低效的扫描。

如果你想使文档字符串不那么模糊,欢迎拉取请求:)


10
2018-05-23 17:42



好的,谢谢你的帮助,现在更清楚了。我添加了一个使用RFECV进行网格搜索的示例到我原来的帖子中,以供其他可能正在努力的人使用。另外,提交了拉动请求和一些修改后的文档,希望它有所帮助。 - DavidS
我也感谢你的解释,因为我遇到了同样的问题。是否提出了文件改进的拉动请求?如果还没有完成,我会很乐意做出贡献。 - J.B. Brown
是的,拉请求已经提交并被接受。 - DavidS


DavidS提供的代码对我不起作用(sklearn 0.18),但需要对param_grid及其用法进行一些小改动。

from sklearn.datasets import make_friedman1
from sklearn.feature_selection import RFECV
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVR
X, y = make_friedman1(n_samples=50, n_features=10, random_state=0)
param_grid = [{'estimator__C': [0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]}]
estimator = SVR(kernel="linear")
selector = RFECV(estimator, step=1, cv=4)
clf = GridSearchCV(selector, param_grid, cv=7)
clf.fit(X, y)
clf.best_estimator_.estimator_
clf.best_estimator_.grid_scores_
clf.best_estimator_.ranking_

2
2018-05-09 18:23



Danke schoen))这个作品就像一个魅力。我甚至会在最后3个语句中添加print()以显示所有语句的输出。 - Anatoly Alekseev