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

R中partykit::glmtree无法完成违约评分分箱,寻求解决方法

问题背景

需要用R的partykit包中glmtree函数,对代表违约(default=1)可能性的评分进行分箱,要求每个分箱内违约率相近。此前方法可行,但当评分的违约预测能力大幅提升后,glmtree无法输出有效解。

合成数据示例
library(tidyverse)

sigmoid <- function(x) {
  1 / (1 + exp(-x))
}

n_sample <- 10^5
score <- runif(n_sample, min = -5, max = 5)
defaults <- rbinom(length(score), size = 1, prob = sigmoid(score))

df <- tibble(score = score, default_flag = defaults) 

partykit::glmtree(formula = default_flag ~ score,
                  data = as.data.frame(df),
                  family = binomial)
评分等分分箱后的违约率分布

执行以下代码将评分等分为100个分箱,并绘制违约率分布:

df %>% 
   mutate(score_bin = cut(score, breaks = 100)) %>% 
   group_by(score_bin) %>% 
   summarise(default_rate = sum(default_flag)/ n()) %>% 
   plot()

违约率分箱图

用户疑问与核心问题
  • 用户直觉:glmtree无法找到解,会不会是因为存在大量效果优异的分割点,都能将数据分成违约率差异明显的组?这个推测是否合理?
  • 核心问题:如何让partykit::glmtree在上述示例中成功完成分箱?
已尝试的方案
  • 将maxit参数增加至100
  • 增大minsize参数
  • 使用ctree函数可快速得到分箱解
解决方案

1. 调整正则化参数

当变量预测能力极强时,glmtree易因分割点过多或过度拟合无法收敛,可通过alpha(L1正则化)、lambda(L2正则化)限制模型复杂度:

partykit::glmtree(formula = default_flag ~ score,
                  data = as.data.frame(df),
                  family = binomial,
                  alpha = 0.5,  # 0为纯L2正则化,1为纯L1正则化,0-1为混合正则化
                  lambda = 0.1) # 正则化强度,可根据数据调整

2. 限制树的最大深度

通过maxdepth参数控制分割层数,避免模型尝试过多无意义的分割:

partykit::glmtree(formula = default_flag ~ score,
                  data = as.data.frame(df),
                  family = binomial,
                  maxdepth = 3) # 限制树最多3层分割

3. 放宽分割检验的显著性阈值

默认检验标准可能过于严格,可通过testtype和对应alpha参数(此alpha为检验显著性水平,与正则化参数区分)调整:

partykit::glmtree(formula = default_flag ~ score,
                  data = as.data.frame(df),
                  family = binomial,
                  testtype = "Bonferroni",
                  alpha = 0.1) # 阈值从默认0.05提高至0.1,放宽检验标准

4. 先预分箱再建模

若上述方法无效,可先对评分做粗分箱,再基于分箱后的变量建模:

# 先将评分分为10个初始分箱
df <- df %>% 
  mutate(score_pre_bin = cut(score, breaks = 10))

# 基于预分箱变量运行glmtree
partykit::glmtree(formula = default_flag ~ score_pre_bin,
                  data = as.data.frame(df),
                  family = binomial)

关于用户直觉的验证

你的推测是合理的:当评分预测能力极强时,几乎所有分割点都能显著区分违约率高低的组,导致glmtree在选择最优分割点时陷入困境——大量分割点的检验统计量都极高,模型难以收敛到稳定解。而ctree的分割逻辑更侧重显著性检验,因此这种场景下更容易输出结果。


内容的提问来源于stack exchange,提问作者PalimPalim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:23:17