【发布时间】:2023-03-26 00:22:01
【问题描述】:
我已经设法编写了一些代码,使用 lightGBM 作为我的回归器进行嵌套交叉验证,并使用 sklearn.pipeline 包装所有内容。
最终,我现在想要进行特征选择(或者实际上只是了解特征对最终模型的重要性),但我想知道从这里采取的最佳路径是什么。我想有两种可能:
1# 使用此方法来使用最佳超参数构建模型(使用 .fit 和 .predict)。然后检查该模型的特征的重要性。
2# 在嵌套 cv 的内部折叠中进行特征选择,但我不确定如何准确执行此操作。
我猜#1 会是最简单的,但我不确定如何为每个外层获得最佳超参数。
这个线程涉及到它: Putting together sklearn pipeline+nested cross-validation for KNN regression
但是选择的答案完全放弃了 cross_val_score,这意味着它不再是嵌套的交叉验证(我仍然想在内折叠上获得最佳超参数后在外折叠上执行 CV)。
所以我的问题如下:
- 我能否获取外部 CV 每一折的特征重要性(我是 意识到如果我有 5 折,我将获得 5 组不同的功能 重要性)?如果是,怎么做?
- 或者,我是否应该为每个获得最佳超参数 折叠(如何?)并在整个数据集上构建一个没有 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')
编辑:清楚地说明问题。
【问题讨论】:
-
有什么问题?
-
特征选择过程是您管道中的一个阶段吗?
-
@serafeim:我添加了一个更清晰(我希望)的问题表述。 @ShaharA:目前没有。我现在只有一个
StandardScaler()和LGBMRegressor。
标签: python scikit-learn cross-validation feature-selection hyperparameters