mgcv包bam构建GAM模型的预测结果随newdata构成不同出现差异
问题原因定位
该差异是mgcv包中bam函数启用离散加速(discrete=TRUE)的特有机制导致的,不属于程序bug,是数值近似计算的正常现象:
- 拟合模型时指定了
discrete=TRUE,predict.bam默认会继承该参数设置,预测阶段同样会启用离散加速逻辑 - 离散加速的核心是将连续预测变量的取值按边界划分成固定数量的分箱,用分箱均值代替原始值进行后续计算,大幅降低大样本下的运算开销
- 分箱的上下边界会根据当前传入的整批
newdata的连续变量取值范围自动计算:单独传入25万子集时,连续变量的极值范围仅来自该子集;和全量250万数据一起传入时,极值范围会被全量数据的极值拉伸,分箱边界出现偏移,同一个原始取值可能被划分到相邻分箱,最终产生微小的预测值差异 - 额外的微小差异可能来自多线程并行计算的浮点运算顺序误差,但贡献远小于离散分箱的影响
修复方案
可根据性能和精度需求选择以下任意一种方案:
- 预测时显式关闭离散加速,直接用原始连续值计算,结果完全可复现,代码修改如下:
predictions <- predict(model, newdata = newdata, type="response", discrete = FALSE) # 新增这一行,强制关闭离散加速
该方案的唯一缺点是全量250万行的预测速度会有所下降,对大部分场景而言性能损失在可接受范围内。
- 若需要保留离散加速的高性能,可统一分箱规则:提前基于全量预测数据集计算所有连续预测变量的分箱边界,后续预测子集和全量时都使用固定边界进行离散化,该方案需要自行实现分箱逻辑,操作复杂度更高。
- 若需要重新拟合模型,可将拟合时的
discrete参数改为FALSE,后续所有预测默认都不会出现该问题,但拟合阶段的速度会明显变慢,适合不需要频繁重训模型的场景。
内容的提问来源于stack exchange,提问作者rw2
相关产品推荐
相关产品推荐

