You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Tidymodels调优rpart泊松决策树时公式报错问题

解决Tidymodels调优泊松决策树时的公式解析错误

问题重现

我用rpart包实现了泊松决策树,随后用Tidymodels复现固定超参数的拟合,结果完全一致。但尝试用Tidymodels进行超参数调优时,所有模型训练失败,报错信息如下:

Error in str2lang(x): :1:32: unexpected symbol
1: cbind(cbind(exposure, n_claims).exposure
^

相关代码见原提问的rpart实现、Tidymodels固定参数拟合及调优代码。

问题原因

Tidymodels的workflow在调优过程中会对公式做内部解析处理,当直接使用cbind(exposure, n_claims) ~ ...这种多响应变量格式时,解析逻辑会出现重复包裹响应变量的错误,把本应是分隔符的.误识别为无效符号,导致公式语法错误。而直接调用fit()时没有这个问题,是因为此时公式会直接传递给rpart引擎,没有经过调优模块的额外解析。

解决方案

避免在add_formula()中直接使用cbind,提前构造好适合rpart泊松模型的响应变量矩阵,让Tidymodels能正确传递给底层引擎。

方案1:提前构造响应变量列

在训练数据中先创建响应变量的矩阵列,再在公式中引用该列:

# 提前构造响应变量矩阵
dat_train <- dat_train %>% 
  mutate(response = cbind(exposure, n_claims))

# 模型规格不变
tree_spec <- decision_tree(
  cost_complexity = tune(),
  tree_depth = tune(),
  min_n = tune()) %>%
  set_engine("rpart", method = "poisson") %>%
  set_mode("regression")

# 更新workflow的公式
tree_wf <- workflow() %>%
  add_model(tree_spec) %>%
  add_formula(response ~ is_renewed + gender + age_group + cluster_k3 + insured_amount)

# 后续调优代码保持不变
tree_grid <- grid_latin_hypercube(extract_parameter_set_dials(tree_spec), size = 50)
doParallel::registerDoParallel()
set.seed(345)
tree_rs <- tree_wf %>%
  tune_grid(
    resamples = folds,
    grid = tree_grid,
    metrics = metric_set(yardstick::rmse)
  )

方案2:使用Recipe处理响应变量

如果更倾向用Tidymodels的recipe体系管理数据预处理,可以这样实现:

# 创建recipe,合并响应变量
tree_rec <- recipe(dat_train) %>%
  # 标记变量角色
  update_role(exposure, n_claims, new_role = "outcome") %>%
  update_role(is_renewed, gender, age_group, cluster_k3, insured_amount, new_role = "predictor") %>%
  # 构造rpart所需的响应矩阵
  step_mutate(response = cbind(exposure, n_claims), role = "outcome") %>%
  # 移除原单独的结果列
  step_rm(exposure, n_claims)

# 模型规格不变
tree_spec <- decision_tree(
  cost_complexity = tune(),
  tree_depth = tune(),
  min_n = tune()) %>%
  set_engine("rpart", method = "poisson") %>%
  set_mode("regression")

# 使用recipe构建workflow
tree_wf <- workflow() %>%
  add_model(tree_spec) %>%
  add_recipe(tree_rec)

# 后续调优代码保持不变
tree_grid <- grid_latin_hypercube(extract_parameter_set_dials(tree_spec), size = 50)
doParallel::registerDoParallel()
set.seed(345)
tree_rs <- tree_wf %>%
  tune_grid(
    resamples = folds,
    grid = tree_grid,
    metrics = metric_set(yardstick::rmse)
  )

说明

两种方案都是通过提前构造好rpart泊松模型所需的响应变量矩阵,避免了Tidymodels调优模块对cbind公式的错误解析,保证调优过程能正常运行。

内容的提问来源于stack exchange,提问作者gabriel chirinos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 16:47:06