【问题标题】:How to perform feature selection (rfecv) in cross validation in sklearn如何在 sklearn 的交叉验证中执行特征选择(rfecv)
【发布时间】:2020-07-10 23:13:25
【问题描述】:

我想在 sklearn 中执行 recursive feature elimination with cross validation (rfecv) 的 10 倍交叉验证(即 cross_val_predictcross_validate)。

由于rfecv 本身的名称中有一个交叉验证部分,我不清楚该怎么做。我目前的代码如下。

from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target

from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier(random_state = 0, class_weight="balanced")

k_fold = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)

rfecv = RFECV(estimator=clf, step=1, cv=k_fold)

请告诉我如何在10-fold cross validation 中使用Xyrfecv 数据。

如果需要,我很乐意提供更多详细信息。

【问题讨论】:

  • 您想在每个折叠中将 RFE 与分类器结合使用,还是什么?
  • @desertnaut 谢谢你的评论。我想做10-fold cross validation 在sklearn 中进行特征选择。有可能吗? :)
  • 您已经说过了,这正是现有答案所提供的,但您似乎仍然不满意。我问了一些不同的问题-如果问题中的随机森林代码无关紧要,为什么顺便说一句?您想使用在 RFE 选择的特征中训练的 RF 分类器进行 CV 吗?
  • @desertnaut 我现在明白你的意思了。谢谢你的澄清。是的,我想使用在 RFE 选定特征中训练的 RF 分类器进行 CV。 :)

标签: python machine-learning scikit-learn classification cross-validation


【解决方案1】:

要使用 RFE然后 执行特征选择,用 10 倍交叉验证拟合 rf,您可以这样做:

from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import confusion_matrix
from sklearn.feature_selection import RFE

rf = RandomForestClassifier(random_state = 0, class_weight="balanced")
rfe = RFE(estimator=rf, step=1)

现在通过拟合RFECV 来转换原始的X

X_new = rfe.fit_transform(X, y)

以下是排名特征(只有 4 个问题不大):

rfe.ranking_
# array([2, 3, 1, 1])

现在拆分为训练和测试数据,并使用GridSearchCV 结合网格搜索执行交叉验证(它们通常一起使用):

X_train, X_test, y_train, y_test = train_test_split(X_new,y,train_size=0.7)

k_fold = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)

param_grid = {
                 'n_estimators': [5, 10, 15, 20],
                 'max_depth': [2, 5, 7, 9]
             }

grid_clf = GridSearchCV(rf, param_grid, cv=k_fold.split(X_train, y_train))
grid_clf.fit(X_train, y_train)

y_pred = grid_clf.predict(X_test)

confusion_matrix(y_test, y_pred)

array([[17,  0,  0],
       [ 0, 11,  0],
       [ 0,  3, 14]], dtype=int64)

【讨论】:

  • 非常感谢您的回答。但是,我想使用 10 折交叉验证,而不是训练和测试拆分。即类似cross_val_predict。有可能与rfecv有关吗?谢谢你:)
  • 您正在进行 10 折交叉验证。唯一的细节是你留下一个看不见的测试样本来获得现实的指标@emj
  • 这在方法上是不可取的;使用所有数据选择特征(甚至通过单独的 CV 程序),然后将这些选择的特征与 CV 一起使用是一条已知的毁灭之路。正确的方法是将两者包装在一个单一的简历流程中,如自己的答案所示。请参阅How NOT to perform feature selection! 以及其中的众多链接和参考资料。
  • 嗯,你提出了一个很好的观点@desertnaut。没有那样想。因此,使用RFE(因此没有交叉验证)遵循同样的方法应该没问题,对吧?
  • @yatu 是的,或多或少。这是一个很好的点,在过去确实摧毁了人们:)
【解决方案2】:

要将递归特征消除与预定义的k_fold 结合使用,您应该使用RFE 而不是RFECV

from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import accuracy_score
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
y = iris.target

k_fold = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)
clf = RandomForestClassifier(random_state = 0, class_weight="balanced")
selector = RFE(clf, 5, step=1)

cv_acc = []

for train_index, val_index in k_fold.split(X, y):
    selector.fit(X[train_index], y[train_index])
    pred = selector.predict(X[val_index])
    acc = accuracy_score(y[val_index], pred)
    cv_acc.append(acc)

cv_acc
# result:
[1.0,
 0.9333333333333333,
 0.9333333333333333,
 1.0,
 0.9333333333333333,
 0.9333333333333333,
 0.8666666666666667,
 1.0,
 0.8666666666666667,
 0.9333333333333333]

【讨论】:

  • 非常感谢。这正是我想要的。感谢您在rfe 中纠正我。 :)
猜你喜欢
  • 2015-11-13
  • 2018-12-13
  • 2021-04-09
  • 2013-11-08
  • 2019-09-07
  • 2016-04-13
  • 2013-05-29
  • 2019-08-30
  • 2016-02-11
相关资源
最近更新 更多