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

R语言如何正确校准glmnet模型输出的二分类预测概率?

R二分类glmnet模型概率校准代码问题修正

代码存在的核心问题

  • 校准模型训练数据源错误:直接调用predict(glmnet_ML, Train)获取训练集预测值训练校准模型,这类结果是模型在已经学习过的样本上输出的重代入预测值,本身存在过拟合、置信度虚高的偏差。按照《Applied Predictive Modeling》中的方法要求,训练sigmoid校准(即Platt缩放)必须使用模型训练过程中折外(out-of-fold,即交叉验证中样本未参与当前折模型训练时输出的预测值)的预测结果,否则训练出的校准模型泛化性极差,在测试集上无法输出符合校准预期的概率。
  • 存在无效冗余代码:第一次计算测试集预测概率后单独出现的无赋值pred行属于残次代码片段,不影响运行结果但无实际作用。
  • 示例数据集存在局限性:筛选得到的versicolor、virginica二分类iris子集线性可分度极高,glmnet在该数据集上输出的原始概率本身已经极度趋近0/1,加上数据集总样本量仅100条,拆分后测试集单类样本仅20条,校准曲线分箱后单箱样本量不足,随机波动会导致曲线视觉上偏离对角线,属于小样本下的正常现象,并非校准方法失效。

修正后的可复现代码

核心修正点为:直接提取caret::train训练过程中保存的交叉验证折外预测结果训练校准模型,而非使用训练集重代入的预测值。

library(tidyverse)
library(caret)

# 构造二分类iris数据集
my_data  <- iris %>% 
  filter(Species %in% c("virginica", "versicolor")) %>% 
  select(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species) %>% 
  droplevels()

# 拆分训练、测试集
set.seed(355)
index <- createDataPartition(y=my_data$Species, p=0.6, list=FALSE) 
Train <- my_data[index,]
Test <-  my_data[-index,]

# 训练glmnet模型,配置项开启保存折外预测结果
classCtrl <- trainControl(
  method = "repeatedcv", 
  number = 10,
  repeats = 5,
  classProbs = TRUE,
  savePredictions = "final"
)
set.seed(355)
glmnet_ML <- train(
  Species ~ ., 
  data = Train, 
  method = "glmnet",  
  trControl = classCtrl
)

# 提取最优超参数对应的折外预测结果,用于训练校准模型
cv_preds <- glmnet_ML$pred %>% 
  filter(lambda == glmnet_ML$bestTune$lambda, alpha == glmnet_ML$bestTune$alpha) %>% 
  select(obs, versicolor) %>% 
  rename(Species = obs, PredProb = versicolor)

# 训练sigmoid校准模型
sigmoidalCal <- glm(
  relevel(Species, ref= "virginica") ~ PredProb,
  data = cv_preds,
  family = binomial
)

# 生成测试集原始预测结果
predTest <- predict(glmnet_ML, Test)
predTestprob <- predict(glmnet_ML, Test, type="prob")
Test$PredProb <- predTestprob[,"versicolor"]
Test$Pred <- predTest

# 生成测试集校准后概率
Test$CalProb <- predict(
  sigmoidalCal,
  newdata = Test[, "PredProb", drop = FALSE],
  type = "response"
)

# 绘制校准曲线,可通过cuts参数调整分箱数量适配小样本场景
calCurve2 <- calibration(Species ~ PredProb + CalProb, data = Test, class = "versicolor", cuts = 5)
xyplot(calCurve2, auto.key = list(columns = 2))

补充说明

  • 小样本场景下绘制校准曲线时,可适当降低cuts参数值减少分箱数量,避免单箱样本量过少导致曲线波动幅度过大,影响视觉判断。
  • 对于区分度极高的模型(如本示例中AUC接近1的glmnet模型),原始概率本身校准度已经处于较高水平,校准操作的提升空间非常有限,无需强行追求曲线完全贴合对角线,小样本下的随机偏差属于正常情况。
  • 若样本量足够大,也可将sigmoid校准替换为等距回归(isotonic regression)获得更灵活的校准效果,但样本量不足时等距回归更容易过拟合,效果反而不如sigmoid校准稳定。

内容的提问来源于stack exchange,提问作者Jean-Alexandre Patteet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:03:25