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
相关产品推荐
相关产品推荐

