【问题标题】:How to perform feature selection with gridsearchcv in sklearn in python如何在 python 的 sklearn 中使用 gridsearchcv 执行特征选择
【发布时间】:2019-08-31 17:20:37
【问题描述】:

我使用recursive feature elimination with cross validation (rfecv) 作为randomforest classifier 的功能选择器,如下所示。

X = df[[my_features]] #all my features
y = df['gold_standard'] #labels

clf = RandomForestClassifier(random_state = 42, class_weight="balanced")
rfecv = RFECV(estimator=clf, step=1, cv=StratifiedKFold(10), scoring='roc_auc')
rfecv.fit(X,y)

print("Optimal number of features : %d" % rfecv.n_features_)
features=list(X.columns[rfecv.support_])

我也在执行GridSearchCV如下调整RandomForestClassifier的超参数如下。

X = df[[my_features]] #all my features
y = df['gold_standard'] #labels

x_train, x_test, y_train, y_test = train_test_split(X, y, random_state=0)

rfc = RandomForestClassifier(random_state=42, class_weight = 'balanced')
param_grid = { 
    'n_estimators': [200, 500],
    'max_features': ['auto', 'sqrt', 'log2'],
    'max_depth' : [4,5,6,7,8],
    'criterion' :['gini', 'entropy']
}
k_fold = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)
CV_rfc = GridSearchCV(estimator=rfc, param_grid=param_grid, cv= k_fold, scoring = 'roc_auc')
CV_rfc.fit(x_train, y_train)
print(CV_rfc.best_params_)
print(CV_rfc.best_score_)
print(CV_rfc.best_estimator_)

pred = CV_rfc.predict_proba(x_test)[:,1]
print(roc_auc_score(y_test, pred))

但是,我不清楚如何将特征选择 (rfecv) 与 GridSearchCV 合并。

编辑:

当我运行@Gambit 建议的答案时,出现以下错误:

ValueError: Invalid parameter criterion for estimator RFECV(cv=StratifiedKFold(n_splits=10, random_state=None, shuffle=False),
   estimator=RandomForestClassifier(bootstrap=True, class_weight='balanced',
            criterion='gini', max_depth=None, max_features='auto',
            max_leaf_nodes=None, min_impurity_decrease=0.0,
            min_impurity_split=None, min_samples_leaf=1,
            min_samples_split=2, min_weight_fraction_leaf=0.0,
            n_estimators='warn', n_jobs=None, oob_score=False,
            random_state=42, verbose=0, warm_start=False),
   min_features_to_select=1, n_jobs=None, scoring='roc_auc', step=1,
   verbose=0). Check the list of available parameters with `estimator.get_params().keys()`.

我可以通过在param_grid 参数列表中使用estimator__ 来解决上述问题。


我现在的问题是如何使用x_test 中选定的特征和参数来验证模型是否可以正常处理看不见的数据。如何获取best features 并使用optimal hyperparameters 进行训练?

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

【问题讨论】:

    标签: python machine-learning scikit-learn data-science grid-search


    【解决方案1】:

    您只需将递归特征消除估计器直接传递给GridSearchCV 对象。像这样的东西应该可以工作

    X = df[my_features] #all my features
    y = df['gold_standard'] #labels
    
    clf = RandomForestClassifier(random_state = 42, class_weight="balanced")
    rfecv = RFECV(estimator=clf, step=1, cv=StratifiedKFold(10), scoring='auc_roc')
    
    param_grid = { 
        'n_estimators': [200, 500],
        'max_features': ['auto', 'sqrt', 'log2'],
        'max_depth' : [4,5,6,7,8],
        'criterion' :['gini', 'entropy']
    }
    k_fold = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)
    
    #------------- Just pass your RFECV object as estimator here directly --------#
    
    CV_rfc = GridSearchCV(estimator=rfecv, param_grid=param_grid, cv= k_fold, scoring = 'roc_auc')
    
    
    CV_rfc.fit(x_train, y_train)
    print(CV_rfc.best_params_)
    print(CV_rfc.best_score_)
    print(CV_rfc.best_estimator_)
    

    【讨论】:

    • 非常感谢您的出色回答。有没有办法从rfecv 获取选定的功能?此外,我们如何使用所选功能验证X_test?期待您的回音。再次非常感谢你:)
    • 我试图运行你的代码。但是,我收到以下错误。 ValueError: Invalid parameter criterion for estimator。你能告诉我如何解决这个问题。非常感谢:)
    【解决方案2】:

    可以做你想做的事,在你想传递给估计器的参数名称前加上'estimator__'

    X = df[[my_features]]
    y = df[gold_standard]
    
    clf = RandomForestClassifier(random_state=0, class_weight="balanced")
    rfecv = RFECV(estimator=clf, step=1, cv=StratifiedKFold(3), scoring='roc_auc')
    
    param_grid = { 
        'estimator__n_estimators': [200, 500],
        'estimator__max_features': ['auto', 'sqrt', 'log2'],
        'estimator__max_depth' : [4,5,6,7,8],
        'estimator__criterion' :['gini', 'entropy']
    }
    k_fold = StratifiedKFold(n_splits=3, shuffle=True, random_state=0)
    
    CV_rfc = GridSearchCV(estimator=rfecv, param_grid=param_grid, cv= k_fold, scoring = 'roc_auc')
    
    X_train, X_test, y_train, y_test = train_test_split(X, y)
    
    CV_rfc.fit(X_train, y_train)
    

    我制作的虚假数据的输出:

    {'estimator__n_estimators': 200, 'estimator__max_depth': 6, 'estimator__criterion': 'entropy', 'estimator__max_features': 'auto'}
    0.5653035605690997
    RFECV(cv=StratifiedKFold(n_splits=3, random_state=None, shuffle=False),
       estimator=RandomForestClassifier(bootstrap=True, class_weight='balanced',
                criterion='entropy', max_depth=6, max_features='auto',
                max_leaf_nodes=None, min_impurity_decrease=0.0,
                min_impurity_split=None, min_samples_leaf=1,
                min_samples_split=2, min_weight_fraction_leaf=0.0,
                n_estimators=200, n_jobs=None, oob_score=False, random_state=0,
                verbose=0, warm_start=False),
       min_features_to_select=1, n_jobs=None, scoring='roc_auc', step=1,
       verbose=0)
    

    【讨论】:

    • 非常感谢您的出色回答。你能告诉我如何使用X_test 来验证结果吗?期待您的回音。非常感谢:)
    • roc_auc_score(y_test, CV_rfc.predict_proba(X_test))?
    • 非常感谢。最后一个问题。我想看看通过这个过程选择了哪些功能。是否有可能获得那些选择的功能? :)
    • 将选定的特征数量设为rfecv.n_features_ 是否正确。如果我错了,请纠正我。期待您的回音。非常感谢:)
    【解决方案3】:

    基本上,您希望在使用递归特征消除(使用交叉验证)进行特征选择之后微调分类器的超参数(使用交叉验证)。

    管道对象正是用于组装数据转换和应用估算器的目的。

    也许您可以使用不同的模型(GradientBoostingClassifier 等)进行最终分类。可以采用以下方法:

    from sklearn.datasets import load_breast_cancer
    from sklearn.feature_selection import RFECV
    from sklearn.model_selection import GridSearchCV
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestClassifier
    
    X, y = load_breast_cancer(return_X_y=True)
    X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                        test_size=0.33, 
                                                        random_state=42)
    
    
    from sklearn.pipeline import Pipeline
    
    #this is the classifier used for feature selection
    clf_featr_sele = RandomForestClassifier(n_estimators=30, 
                                            random_state=42,
                                            class_weight="balanced") 
    rfecv = RFECV(estimator=clf_featr_sele, 
                  step=1, 
                  cv=5, 
                  scoring = 'roc_auc')
    
    #you can have different classifier for your final classifier
    clf = RandomForestClassifier(n_estimators=10, 
                                 random_state=42,
                                 class_weight="balanced") 
    CV_rfc = GridSearchCV(clf, 
                          param_grid={'max_depth':[2,3]},
                          cv= 5, scoring = 'roc_auc')
    
    pipeline  = Pipeline([('feature_sele',rfecv),
                          ('clf_cv',CV_rfc)])
    
    pipeline.fit(X_train, y_train)
    pipeline.predict(X_test)
    

    现在,您可以将此管道(包括特征选择)应用于测试数据。

    【讨论】:

    • 非常感谢您的出色回答。为什么你认为使用不同的分类器进行特征选择很重要?有什么理由吗? Lokking 期待收到您的来信。非常感谢:)
    • 如你所知,特征选择可以通过比较简单的classsifer来完成。但是当你想做最终分类时,你会对性能更感兴趣,因此你可能会选择 mlp 分类器或类似的东西。
    • 非常感谢。只是一个简单的问题。您会推荐哪些simple classifiers 用于功能选择?期待您的来信:)
    • 我会从logisticRegresssion开始,然后是sgdClassifier、ridgeClassifier、decisionTree等。
    • 非常感谢。你会推荐什么算法来调整参数?此外,如果您知道以下问题的答案,请告诉我stackoverflow.com/questions/55649352/…
    猜你喜欢
    • 2022-07-27
    • 1970-01-01
    • 2020-07-10
    • 2017-04-06
    • 2014-09-21
    • 2017-04-26
    • 2016-08-30
    • 2023-04-07
    • 2019-01-12
    相关资源
    最近更新 更多