tidymodels包Lasso逻辑回归精度指标计算错误问题求助
问题:tidymodels中precision指标计算不符的修正方法
问题背景
我用tidymodels完成以下操作后,发现包计算的precision与手动计算结果不一致:
- 模拟数据集:
require(tidymodels) set.seed(123) x1=rnorm(1000,0,1) x2=rnorm(1000,0.5,1) x3=rnorm(1000,2.5,1) x4=rnorm(1000,2.5,1.5) y=exp(0.3*x1 + 0.25*x2 + 0.75)/(1+exp(0.3*x1 + 0.25*x2 + 0.75)) y_bin=ifelse(y>0.8,1,0) data_sim=data.frame(x1,x2=2.5*x2,x3=3*x3, x4,y_bin=factor(y_bin))
- 构建Lasso逻辑回归并执行5折交叉验证:
set.seed(123) fold_data=vfold_cv(data_sim,v=5) lasso_spec<- logistic_reg( penalty = tune(), mixture = 1) %>% set_engine("glmnet") lamd_grid <- grid_regular(penalty(), levels =50) res_basic <- recipe(y_bin ~ x1 +x2+x3 + x4 , data=data_sim) wf <- workflow() %>% add_model(lasso_spec) %>% add_recipe(res_basic) lasso_tune <- wf %>% tune_grid( resamples=fold_data, grid=lamd_grid, control=control_grid(verbose = FALSE, save_pred = T), metrics=metric_set(roc_auc, sensitivity, precision, recall) )
- 通过
show_best("precision")得到精度均值为0.997:
lasso_tune %>% show_best("precision") # A tibble: 5 × 7 penalty .metric .estimator mean n std_err .config <dbl> <chr> <chr> <dbl> <int> <dbl> <chr> 1 1 e-10 precision binary 0.997 5 0.00138 Preprocessor1_Model01 2 1.60e-10 precision binary 0.997 5 0.00138 Preprocessor1_Model02 3 2.56e-10 precision binary 0.997 5 0.00138 Preprocessor1_Model03 4 4.09e-10 precision binary 0.997 5 0.00138 Preprocessor1_Model04 5 6.55e-10 precision binary 0.997 5 0.00138 Preprocessor1_Model05
- 手动合并各折预测结果得到混淆矩阵:
> table(fold_cmb$.pred_class,fold_cmb$y_bin) 0 1 0 885 3 1 1 111
手动计算类别1的精度应为111/(111+1)=0.991,但包计算结果为0.997,推测是包默认计算了类别0的精度。
原因分析
tidymodels中二分类任务的precision默认以因子型因变量的第一个水平作为正类。你的y_bin是因子型,默认水平顺序是0在前、1在后,所以包计算的是类别0的精度:885/(885+3)=0.9966,四舍五入后就是0.997,和show_best的结果一致。
解决方案
要计算类别1的精度,有两种可行方法:
方法1:修改因变量的因子水平顺序
将类别1设为第一个水平(正类),后续代码无需调整:
# 修改数据集的因变量水平顺序 data_sim$y_bin <- factor(data_sim$y_bin, levels = c("1", "0")) # 重新运行交叉验证、建模流程即可
方法2:自定义精度指标,指定正类为1
使用precision()函数的event_level参数,指定正类为原因子的第二个水平:
# 自定义指标集,指定precision的正类为"1" custom_metrics <- metric_set( roc_auc, sensitivity, recall, function(data, truth, estimate, ...) { precision(data, truth = truth, estimate = estimate, event_level = "second") } ) # 在tune_grid中使用自定义指标集 lasso_tune <- wf %>% tune_grid( resamples=fold_data, grid=lamd_grid, control=control_grid(verbose = FALSE, save_pred = T), metrics=custom_metrics )
验证
修改后调用show_best("precision"),得到的精度均值会与手动计算的0.991一致。
内容的提问来源于stack exchange,提问作者student_R123
相关产品推荐
相关产品推荐

