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

tidymodels包Lasso逻辑回归精度指标计算错误问题求助

问题:tidymodels中precision指标计算不符的修正方法

问题背景

我用tidymodels完成以下操作后,发现包计算的precision与手动计算结果不一致:

  1. 模拟数据集:
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))
  1. 构建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)
                
              )
  1. 通过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
  1. 手动合并各折预测结果得到混淆矩阵:
> 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:17:24