问题描述
我目前正在应用以下配方和工作流程,以便使用 fit_resamples
进行 5 折交叉验证来拟合随机森林。工作流程如下所示:
library(tidymodels)
# import data and convert response to factor
train <- read.csv('https://pastebin.com/raw/LJQqdEEE')
train$accepted <- as.factor(train$accepted)
# Train/test split
new_split <- initial_split(train,prop = 0.7)
new_train <- training(new_split)
new_test <- testing(new_split)
# Feature engineering and data prep
admission_rec <-
recipe(accepted ~ .,data = new_train) %>%
step_impute_median(sat) %>%
step_mutate(
ap_scores = strsplit(as.character(ap_scores),';'),ap_score_max = max(as.numeric(unlist(ap_scores))),ap_score_avg = mean(as.numeric(unlist(ap_scores))),ap_score_min = min(as.numeric(unlist(ap_scores))),ap_score_med = median(as.numeric(unlist(ap_scores)))
) %>%
step_dummy(ethnicity,one_hot = T) %>%
step_center(c(essay_strength,family_income,sat),skip = T) %>%
step_scale(c(essay_strength,skip = T) %>%
step_naomit(everything(),skip = T) %>%
step_rm(ap_scores)
# Random forest model and workflow
rf_spec <-
rand_forest() %>%
set_engine('ranger') %>%
set_mode('classification')
rf_workflow <-
workflow() %>%
add_recipe(admission_rec) %>%
add_model(rf_spec)
# Cross validation
cv_folds <-
vfold_cv(new_train,v = 5)
# Fit model
rf_res <- rf_workflow %>%
fit_resamples(
resamples = cv_folds,metrics = metric_set(
recall,precision,f_meas,accuracy,kap,roc_auc,sens,spec
)
)
在拟合模型时,我收到以下失败消息的提示:
preprocessor 1/1: There are new levels in a factor: NA
preprocessor 1/1,model 1/1 (predictions): Missing data in columns: ethnicity_Asian ...
这看起来仅限于一个热编码列,甚至是 step_naomit(skip = TRUE)
。出于这个原因,我错误地认为将 step_naomit
放在 step_mutate
之后会解决这个问题。
我可能在这里忽略了一些相当简单的事情,这是我在长时间的 R hyathus 之后第一次尝试 {tidymodels}
。
解决方法
您走在正确的轨道上。不幸的是,step_naomit()
不是答案,错误出现在 step_dummy()
中,因为它包含丢失的数据并且不知道如何处理它。解决方案是在之前使用 step_unknown()
,它将采用因子变量并将“未知”分配给缺失值。
我还建议您不要在 skip = T
和 step_center()
中设置 step_scale()
,因为它会在拟合模型时应用居中和缩放,但如果以后使用模型时会跳过上,例如在预测中。这会产生奇怪和不希望的结果。
library(tidymodels)
train <- read.csv('https://pastebin.com/raw/LJQqdEEE')
train$accepted <- as.factor(train$accepted)
# Train/test split
new_split <- initial_split(train,prop = 0.7)
new_train <- training(new_split)
new_test <- testing(new_split)
# Feature engineering and data prep
admission_rec <-
recipe(accepted ~ .,data = new_train) %>%
step_impute_median(sat) %>%
step_mutate(
ap_scores = strsplit(as.character(ap_scores),';'),ap_score_max = max(as.numeric(unlist(ap_scores))),ap_score_avg = mean(as.numeric(unlist(ap_scores))),ap_score_min = min(as.numeric(unlist(ap_scores))),ap_score_med = median(as.numeric(unlist(ap_scores)))
) %>%
step_unknown(ethnicity) %>%
step_dummy(ethnicity,one_hot = T) %>%
step_center(c(essay_strength,family_income,sat)) %>%
step_scale(c(essay_strength,sat)) %>%
step_rm(ap_scores)
# Random forest model and workflow
rf_spec <-
rand_forest() %>%
set_engine('ranger') %>%
set_mode('classification')
rf_workflow <-
workflow() %>%
add_recipe(admission_rec) %>%
add_model(rf_spec)
# Cross validation
cv_folds <-
vfold_cv(new_train,v = 5)
# Fit model
rf_res <- rf_workflow %>%
fit_resamples(
resamples = cv_folds,metrics = metric_set(
recall,precision,f_meas,accuracy,kap,roc_auc,sens,spec
)
)
rf_res
#> # Resampling results
#> # 5-fold cross-validation
#> # A tibble: 5 x 4
#> splits id .metrics .notes
#> <list> <chr> <list> <list>
#> 1 <split [560/140]> Fold1 <tibble [8 × 4]> <tibble [0 × 1]>
#> 2 <split [560/140]> Fold2 <tibble [8 × 4]> <tibble [0 × 1]>
#> 3 <split [560/140]> Fold3 <tibble [8 × 4]> <tibble [0 × 1]>
#> 4 <split [560/140]> Fold4 <tibble [8 × 4]> <tibble [0 × 1]>
#> 5 <split [560/140]> Fold5 <tibble [8 × 4]> <tibble [0 × 1]>
由 reprex package (v2.0.0) 于 2021 年 6 月 22 日创建