功能选择:在嵌套交叉验证之后或期间?

问题描述 投票:1回答:1

我设法编写了一些代码,使用lightGBM作为我的回归器进行嵌套的交叉验证,并使用sklearn.pipeline包装了所有内容。

最终,我现在想进行特征选择(或者实际上只是获得特征对于最终模型的重要性),但是我想知道从这里采取的最佳途径是什么。我想可能有两种可能性:

1#使用此方法可使用最佳超参数来构建模型(使用.fit和.predict)。然后检查此模型功能的重要性。

2#在嵌套cv的内部折叠中进行特征选择,但是我不确定如何精确地做到这一点。

我想最简单的方法是#1,但我不确定如何为每个外部折叠获得最佳的超参数。

此线程触及到它:Putting together sklearn pipeline+nested cross-validation for KNN regression

但是选定的答案完全放弃了cross_val_score,这意味着它不再嵌套交叉验证(我希望在内部折页获得最佳超参数之后,在外部折页上执行CV)。

所以我的问题是以下内容:

  1. 我能否获得外部CV每一折的特征重要性(我是知道如果我有5折,我会得到5套不同的功能重要性)?如果是,怎么办?
  2. 或者,我是否应该为每个参数获得最佳的超参数折叠(如何?)并在整个数据集上建立没有CV的新模型,基于这些超参数?

这里是我到目前为止的代码:

import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import cross_val_score, RandomizedSearchCV, KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
import scipy.stats as st

#Parameters for model building an reproducibility
X = X_age
y = y_age
RNGesus = 42 
state = 13
outer_scoring = 'neg_mean_absolute_error'
inner_scoring = 'neg_mean_absolute_error'

#### Nested CV with Random gridsearch ####

# Pipeline with standard scaling and the regressor    
regressors = [lgb.LGBMRegressor(random_state = state)]
continuous_transformer = Pipeline([('scaler', StandardScaler())])
preprocessor = ColumnTransformer([('cont',continuous_transformer, continuous_variables)], remainder = 'passthrough')

for reg in regressors:
    steps=[('preprocessor', preprocessor), ('regressor', reg)]
    pipeline = Pipeline(steps)

#inner and outer fold to be used
inner_cv = KFold(n_splits=5, shuffle=True, random_state=RNGesus)
outer_cv = KFold(n_splits=5, shuffle=True, random_state=RNGesus)

#Hyperparameters of the regressor to be optimized using randomized search
params = {
'regressor__max_depth': (3, 5, 7, 10),
'regressor__lambda_l1': st.uniform(0, 5),
 'regressor__lambda_l2': st.uniform(0, 3)
}

#Pass the RandomizedSearchCV to cross_val_score

regression = RandomizedSearchCV(estimator = pipeline, param_distributions = params, scoring=inner_scoring, cv=inner_cv, n_iter=200, verbose= 3, n_jobs= -1)
nested_score = cross_val_score(regression, X= X, y= y, cv = outer_cv, scoring=outer_scoring)

print('\n MAE for lightGBM model predicting age: %.3f' % (abs(nested_score.mean())))

print('\n'str(nested_score) + '<- outer CV')

编辑:清楚地陈述了问题。

python scikit-learn cross-validation feature-selection hyperparameters
1个回答
0
投票

我在导入lightGBM模块时遇到问题,因此无法运行您的代码。但是a post在这里解释了如何无法从feature_importance_的嵌套交叉验证中获得“获胜”或最佳超参数(以及cross_val_score)。简要地说,原因是cross_val_score仅返回测量值。

  1. 我可以从外部CV的每一折中获得特征重要性(我知道,如果有5折,我将获得5组不同的特征重要性)?如果是,怎么办?

cross_val_score的答案是否定的。但是,如果您遵循该帖子中的代码,则可以在feature_importance_之后的for循环下通过GSCV.best_estimator_.feature_importance_轻松获得GSCV.fit()

  1. 或者,我是否应该只为每个折叠获取最佳超参数(如何?),并基于这些超参数在整个数据集上构建一个没有CV的新模型?
  2. 这正是该帖子在谈论的内容:通过嵌套cv为您提供“最佳”超参数。理想情况下,您将观察到一种超参数组合,该组合始终获胜,这就是您将用于最终模型(带有整个训练集)的超参数。但是,当我在简历中出现不同的“最佳”超参数组合时,据我所知,没有标准的处理方法。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.