Tidymodels与 glmnet——Cox模型的交叉验证错误:不可对齐的参数

编程语言 2026-07-09

我想在tidymodels框架下对Cox模型进行交叉验证。我的代码的一个可重现示例(reprex)如下:

library(survival)
library(glmnet)
library(tidymodels)
library(tidyverse)
library(censored)
n <- 800

df <- data.frame(patid = (1:n),
                 treatment = sample(c("A", "B", "C"), n, replace = T),
                 age = runif(n, 18, 99),
                 sex = sample(c("m", "f"), n, replace = T),
                 time = rexp(n),
                 event = sample(c(0, 1), n, replace = T)) %>% 
  mutate(event_surv = Surv(time, event))

# DATA PRE-PROCESSING
ph_preprocess <- recipe(event_surv ~ ., data = df) %>% 
  update_role(event_surv, new_role = "outcome") %>% 
  step_filter(time > 0) %>% 
  step_select(-time, -event) %>% 
  update_role(patid, new_role = "ID")

# MODEL DEFINITION
# Model definition (Cox PH)
ph_model_spec <- proportional_hazards(penalty = tune(),
                                      mixture = 1) |>
  set_engine("glmnet") |>
  set_mode("censored regression")

# Model fit workflow
ph_wflow <- workflow() %>% 
  add_recipe(ph_preprocess) %>% 
  add_model(ph_model_spec)

# UNTUNED FIT
# Model fit (no cross validaton)
ph_fit <- fit(ph_wflow, data = df)
autoplot(ph_fit$fit$fit)


# CROSS VALIDATION
# Define a grid of hyperparameters to search
hypergrid <- expand.grid(
  penalty = seq(0.001, 1, length.out = 10)
)

# Set up a cross-validation resampling method
# 10-fold cross-validation
cv <- vfold_cv(df, v = 10)

# Tune the Lasso model using cross-validation
elasticnet_t <- tune_grid(
  object = ph_wflow,
  resamples = cv,
  grid = hypergrid,
  metrics = metric_set(concordance_survival)
)

然而,在执行交叉验证步骤(对 tune_grid() 的调用)时,出现以下错误:

在为函数 'as.matrix' 选择方法时评估参数 'x' 出错:不可比配的参数

某些计算存在问题A: x10

警告信息:

所有模型均已失败。请运行 show_notes(.Last.tune.result) 以获取更多信息。

如何让 tune_grid() 运行?

解决方案

你可以在预处理配方中使用 step_dummy(all_nominal_predictors()) 对所有名义预测变量进行哑变量编码,从而使代码能够运行:

# Source - https://stackoverflow.com/q/79929921
# Posted by Lukas D. Sauer
# Retrieved 2026-04-24, License - CC BY-SA 4.0

library(survival)
library(glmnet)
library(tidymodels)
library(tidyverse)
library(censored)
n <- 800

df <- data.frame(patid = (1:n),
                 treatment = sample(c("A", "B", "C"), n, replace = T),
                 age = runif(n, 18, 99),
                 sex = sample(c("m", "f"), n, replace = T),
                 time = rexp(n),
                 event = sample(c(0, 1), n, replace = T)) %>% 
  mutate(event_surv = Surv(time, event))

# DATA PRE-PROCESSING
ph_preprocess <- recipe(event_surv ~ ., data = df) %>% 
  update_role(event_surv, new_role = "outcome") %>% 
  step_filter(time > 0) %>% 
  step_select(-time, -event) %>% 
  update_role(patid, new_role = "ID") %>%
  step_dummy(all_nominal_predictors())


# MODEL DEFINITION
# Model definition (Cox PH)
ph_model_spec <- proportional_hazards(penalty = tune(),
                                      mixture = 1) |>
  set_engine("glmnet") |>
  set_mode("censored regression")

# Model fit workflow
ph_wflow <- workflow() %>% 
  add_recipe(ph_preprocess) %>% 
  add_model(ph_model_spec)

# UNTUNED FIT
# Model fit (no cross validaton)
ph_fit <- fit(ph_wflow, data = df)
autoplot(ph_fit$fit$fit)


# CROSS VALIDATION
# Define a grid of hyperparameters to search
hypergrid <- expand.grid(
  penalty = seq(0.001, 1, length.out = 10)
)

# Set up a cross-validation resampling method
# 10-fold cross-validation
cv <- vfold_cv(df, v = 10)

# Tune the Lasso model using cross-validation
elasticnet_t <- tune_grid(
  object = ph_wflow,
  resamples = cv,
  grid = hypergrid,
  metrics = metric_set(concordance_survival)
)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章