在R tidymodels中如何为指定变量设置sum to zero对比
问题解答
需求可行性结论
你的需求完全可以实现,无需修改全局对比配置,也不会影响其他变量的默认对比规则。你现有代码的核心问题是step_dummy中加了one_hot = TRUE,该参数会生成n个全量虚拟变量,和base R中contr.sum生成n-1个虚拟变量的求和约束逻辑冲突,因此拟合结果和基准代码不一致。
推荐实现方案
方案1:在recipe的step_dummy中指定专属对比
直接利用step_dummy的contrasts参数为指定变量单独设置对比规则,其余变量默认使用全局对照配置:
library(tidymodels) Bikeshare <- ISLR2::Bikeshare # 模型声明 lm_spec <- linear_reg() %>% set_engine("lm") # 配方配置,仅为mnth和hr设置sum to zero对比 the_rec <- recipe( bikers ~ mnth + hr + workingday + temp + weathersit, data = Bikeshare ) %>% step_dummy(c(mnth, hr), contrasts = list(mnth = contr.sum(12), hr = contr.sum(24))) # 工作流装配与拟合 the_workflow <- workflow() %>% add_recipe(the_rec) %>% add_model(lm_spec) the_workflow_fit <- fit(the_workflow, data = Bikeshare) mod_tidy <- extract_fit_parsnip(the_workflow_fit) # 验证和base R结果一致,会返回TRUE all.equal(coef(mod_tidy$fit), coef(mod.lm2))
方案2:在模型引擎参数中指定对比
不需要在recipe中处理虚拟变量,直接将自定义对比规则传给lm引擎的contrasts参数,实现效果完全一致:
library(tidymodels) Bikeshare <- ISLR2::Bikeshare # 模型声明时直接指定专属对比 lm_spec <- linear_reg() %>% set_engine("lm", contrasts = list(mnth = contr.sum(12), hr = contr.sum(24))) # 配方不需要额外处理分类变量 the_rec <- recipe( bikers ~ mnth + hr + workingday + temp + weathersit, data = Bikeshare ) # 工作流装配与拟合 the_workflow <- workflow() %>% add_recipe(the_rec) %>% add_model(lm_spec) the_workflow_fit <- fit(the_workflow, data = Bikeshare)
两种方案都不会修改全局options中的对比规则,其他分类变量(如workingday、weathersit)仍会使用默认的treatment对比,完全符合你的需求。
内容的提问来源于stack exchange,提问作者itsMeInMiami
相关产品推荐
相关产品推荐

