Tidymodels中如何用代价矩阵惩罚少数类错判解决类别不平衡问题
Tidymodels 代价敏感分类实现方案
Tidymodels 生态有全场景通用的代价敏感学习实现,不局限于 baguette 包的袋装树模型,常用方案如下:
1. 通用 case weights 方案(适配所有支持权重的模型)
Tidymodels 原生支持 case weights 机制,可以直接给少数类样本赋予更高的训练权重,等价于自定义代价矩阵的惩罚效果:
- 第一步:在数据集里新增权重列,按你的代价要求设置权重值,比如少数类错判代价是多数类的10倍:
library(tidymodels) # 假设数据集为df,目标列是y,少数类标签为"1" df_weighted <- df %>% mutate(case_weight = ifelse(y == "1", 10, 1)) %>% # 声明权重列类型 mutate(case_weight = hardhat::importance_weights(case_weight))
- 第二步:工作流中绑定权重,正常训练即可:
# 定义模型(以逻辑回归为例,也可替换为随机森林、XGBoost等任意支持权重的模型) logreg_spec <- logistic_reg() %>% set_engine("glm") %>% set_mode("classification") # 定义工作流 wf <- workflow() %>% add_model(logreg_spec) %>% add_formula(y ~ .) %>% # 指定权重列 add_case_weights(case_weight) # 训练 fit <- wf %>% fit(data = df_weighted)
2. 自定义代价损失函数(适配特殊需求)
如果你的代价矩阵逻辑复杂,或者使用的模型不支持内置权重,可以通过 parsnip 扩展自定义代价敏感损失函数,比如自定义加权交叉熵、自定义SVM hinge损失等,注册后即可像原生模型一样调用。
3. 阈值后调方案(无需修改训练逻辑)
不需要调整训练过程的轻量方案:
- 先正常训练分类模型,输出样本的预测概率
- 根据你的代价矩阵计算最优分类阈值,替换默认的0.5阈值,比如漏判少数类代价是误判多数类的10倍时,可以将阈值调低到0.1,尽量捕捉少数类样本
- 可以结合
yardstick包的自定义指标,直接基于代价矩阵计算模型收益,自动搜索最优阈值。
注:你找到的
baguette::class_cost()确实仅适配袋装树模型,上述三种方案的适配范围覆盖 Tidymodels 全生态的分类模型,更适合通用场景。
内容的提问来源于stack exchange,提问作者O René
相关产品推荐
相关产品推荐

