colino的step_select_*与workflow_map/tune_grid联用报错问题
问题:colino的step_select系列函数与workflow_set/tune_grid联用触发tibble列尺寸不兼容报错
在使用workflow_set拟合多模型前,尝试将colino包的各类step_select_*函数作为预处理步骤加入recipe,但无法与workflow_map正常联用;直接调用包含step_select_*函数的workflow执行tune_grid时也会触发相同报错。报错提示purrr::map执行时出现tibble列尺寸不兼容问题,但无法定位涉事tibble。
复现代码:
library(parsnip) library(dplyr) library(fastDummies) library(colino) library(workflowsets) library(tune) data(iris) logit_model <- logistic_reg(engine = "glm") iris2 <- iris %>% as_tibble() %>% filter(Species != "setosa") iris_cv <- vfold_cv(iris2) recipe <- recipe(Species ~ ., data = iris2) %>% step_nzv(all_predictors()) %>% step_select_vip(all_predictors(), model = logit_model, threshold = 0.9, outcome = "Species") %>% step_normalize(all_numeric_predictors()) logit_vip2 <- workflow_set( preproc = list(rec = recipe), models = list(logit = logistic_reg(engine = "glm")), cross = TRUE) res_logit_vip2 <- logit_vip2 %>% workflow_map(fn = "tune_grid", resamples =iris_cv, verbose = TRUE, control =control_grid(verbose =TRUE))
问题原因
colino的step_select_vip这类动态特征选择步骤,在交叉验证的不同折中,会基于当前折的训练数据计算特征重要性,进而选择满足threshold的特征。由于不同折的数据分布存在差异,最终选出的特征数量/名称可能不一致,导致每折处理后的数据集列数不同。而tune_grid和workflow_map要求交叉验证的所有折输出的数据集结构必须完全一致,因此触发了列尺寸不兼容的错误。
解决方案
方案1:提前在全量训练集上完成特征选择
先基于整个训练数据集确定固定的特征列表,再将这些特征加入recipe,避免交叉验证折内的动态选择导致结构不一致:
# 基于全量训练数据计算VIP特征并筛选 full_vip_results <- logit_model %>% fit(Species ~ ., data = iris2) %>% vip::vi() %>% arrange(desc(Importance)) %>% filter(cumsum(Importance) <= 0.9) %>% pull(Variable) # 使用固定特征列表构建recipe fixed_recipe <- recipe(Species ~ ., data = iris2) %>% step_nzv(all_predictors()) %>% step_select(all_of(full_vip_results)) %>% step_normalize(all_numeric_predictors()) # 正常执行workflow_set和workflow_map logit_vip_fixed <- workflow_set( preproc = list(rec = fixed_recipe), models = list(logit = logistic_reg(engine = "glm")), cross = TRUE) res_logit_vip_fixed <- logit_vip_fixed %>% workflow_map(fn = "tune_grid", resamples = iris_cv, verbose = TRUE, control = control_grid(verbose = TRUE))
方案2:固定选择的特征数量
如果必须在折内动态选择特征,可将step_select_vip的参数从threshold改为top_p,固定选择指定数量的特征,确保每折输出的数据集列数一致:
# 使用top_p固定选择特征数量 recipe_fixed_p <- recipe(Species ~ ., data = iris2) %>% step_nzv(all_predictors()) %>% step_select_vip(all_predictors(), model = logit_model, top_p = 3, outcome = "Species") %>% # 固定选择top3特征 step_normalize(all_numeric_predictors()) # 正常执行workflow_set和workflow_map logit_vip_p <- workflow_set( preproc = list(rec = recipe_fixed_p), models = list(logit = logistic_reg(engine = "glm")), cross = TRUE) res_logit_vip_p <- logit_vip_p %>% workflow_map(fn = "tune_grid", resamples = iris_cv, verbose = TRUE, control = control_grid(verbose = TRUE))
内容的提问来源于stack exchange,提问作者Louie-david Desachy
相关产品推荐
相关产品推荐

