我设法编写了一些代码,使用lightGBM作为我的回归器进行嵌套的交叉验证,并使用sklearn.pipeline包装了所有内容。
最终,我现在想进行特征选择(或者实际上只是获得特征对于最终模型的重要性),但是我想知道从这里采取的最佳途径是什么。我想可能有两种可能性:
1#使用此方法可使用最佳超参数来构建模型(使用.fit和.predict)。然后检查此模型功能的重要性。
2#在嵌套cv的内部折叠中进行特征选择,但是我不确定如何精确地做到这一点。
我想最简单的方法是#1,但我不确定如何为每个外部折叠获得最佳的超参数。
此线程触及到它:Putting together sklearn pipeline+nested cross-validation for KNN regression
但是选定的答案完全放弃了cross_val_score,这意味着它不再嵌套交叉验证(我希望在内部折页获得最佳超参数之后,在外部折页上执行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')
编辑:清楚地陈述了问题。
我在导入lightGBM
模块时遇到问题,因此无法运行您的代码。但是a post在这里解释了如何无法从feature_importance_
的嵌套交叉验证中获得“获胜”或最佳超参数(以及cross_val_score
)。简要地说,原因是cross_val_score
仅返回测量值。
cross_val_score
的答案是否定的。但是,如果您遵循该帖子中的代码,则可以在feature_importance_
之后的for循环下通过GSCV.best_estimator_.feature_importance_
轻松获得GSCV.fit()
。
这正是该帖子在谈论的内容:通过嵌套cv为您提供“最佳”超参数。理想情况下,您将观察到一种超参数组合,该组合始终获胜,这就是您将用于最终模型(带有整个训练集)的超参数。但是,当我在简历中出现不同的“最佳”超参数组合时,据我所知,没有标准的处理方法。