如何在tidymodels中用step_interact()生成与Caret一致的全交互项
问题解决:用tidymodels复现Caret中
~.^2的全双向交互项 核心问题
你当前的tidymodels配方中,step_interact(terms = ~.^2)没有正确生成与Caret mpg ~ .^2完全一致的交互项集合。Caret的~.^2会包含所有主效应 + 所有两两变量的交互项,而直接在step_interact中使用~.^2无法正确触发这一行为。
解决方案
将step_interact的terms参数改为~ (all_predictors())^2,这个语法会明确指定基于所有预测变量生成全双向交互项,同时保留主效应,与Caret的~.^2行为完全匹配。
另外确认:
- 标准化步骤放在交互项生成之前,这和Caret的
preProcess行为一致(先标准化主变量,再计算交互项) - 交叉验证折的复用逻辑已经正确,无需调整
修正后的含交互项模型代码
### Create Folds set.seed(123) train_index <- createDataPartition(mtcars$mpg, p = 0.8, list = FALSE) train <- mtcars[train_index, ] test <- mtcars[-train_index, ] # Create model in Caret set.seed(123) my_grid = 10^seq(-5,5,length.out=1000) model_caret <- train(mpg ~ .^2, data = train, method = "glmnet", trControl = trainControl(method = "cv", number = 5), preProcess=c("center","scale"), tuneGrid=expand.grid(alpha=1,lambda=my_grid)) model_caret cat("The final values used for the model were alpha = 1 and lambda = 0.9014776") ### Create the same folds as in Caret rsplit <- map2(model_caret$control$index, model_caret$control$indexOut, function(x,y) list(analysis = x, assessment = y)) splits <- lapply(rsplit, make_splits, data = train) splits <- manual_rset(splits, names(splits)) ### Create Model my_model = linear_reg(mode = "regression", engine = "glmnet", penalty = tune(), mixture = 1) # 修正后的recipe:使用(all_predictors())^2生成全双向交互 my_recipe <- recipe(mpg ~ ., data = train) %>% step_normalize(all_predictors()) %>% step_interact(terms = ~ (all_predictors())^2) ### Create Grid my_grid = tibble(penalty=10^seq(-5,5,length.out=1000)) #### Create Workflow my_wf = workflow() %>% add_recipe(my_recipe) %>% add_model(my_model) ### Tuning hyperparameter model_tuning = tune_grid(my_wf,resamples = splits,grid = my_grid) ### Show Best model_tuning %>% select_best("rmse")
验证说明
修正后,tidymodels生成的特征集合(主变量+全双向交互)会和Caret完全一致,结合已复用的交叉验证折,最终的超参数调优结果(lambda值)应该会和Caret的0.9014776一致。
内容的提问来源于stack exchange,提问作者ACN
相关产品推荐
相关产品推荐

