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

带因子分组张量平滑的mgcv GAM绘图、预测与交叉验证问题

GAM模型预测、绘图与交叉验证问题解答

1. 基础概念确认

type="link"返回的就是对数链接尺度的线性预测值,包含所有模型项(截距、分类主效应、平滑项、offset)的加总结果,还未经过链接函数的逆变换。

2. plot.gam输出与自定义预测结果差异的原因

差异主要来自三个核心逻辑的不同:

  • 输出内容不同:plot.gam默认绘制的是单个平滑项的边际独立效应,会自动将其他模型项(截距、size_bin主效应、其他平滑项、offset)的贡献归零,仅展示当前选中的te张量项的效应值;而你自定义预测时默认是所有模型项的总贡献,且手动排除了海流项,两者的数值范围本身就会有巨大差异。
  • 网格过滤规则不同:plot.gam的too.far=0.05参数会自动剔除距离原始观测点过远的网格点,避免外推误差;如果你自定义预测时没有做对应的过滤,会包含大量无观测支撑的外推区域,视觉效果差异明显。
  • 因子by项的处理不同:plot.gam会自动将by因子的其他水平设为参考水平,仅展示当前水平下的平滑项效应,自定义预测时如果没有严格按每个size_bin单独生成预测值、单独绘图,也会出现错位。

3. 分组三向交互项的最优预测绘图方案

按以下步骤操作可以实现结果对齐、符合研究需求的绘图:

  1. 构建标准化预测网格
    • 覆盖研究范围内的经纬度、年份的合理取值,每个size_bin(small/med/large)都完整重复一遍所有时空网格点
    • 如果要绘制单位调查 effort的丰度,将plots_sampled统一设为1,此时offset(log(plots_sampled))=0,不需要额外处理offset
    • 海流变量vo、uo不需要手动赋值,后续通过exclude参数剔除其贡献即可
  2. 调用predict做精准预测
    • 首先运行names(count_te_model.xy.vo.I$smooth)获取所有平滑项的准确名称,避免exclude参数写错失效
    • 如果你要绘制总丰度的时空趋势(剔除海流影响):调用predict(模型, 新数据=预测网格, type="response", exclude=c("海流相关平滑项的完整名称")),此时返回的就是原始计数尺度的、单位调查 effort下的丰度预测值
    • 如果你要绘制和plot.gam对齐的边际平滑效应:调用predict(模型, 新数据=预测网格, type="terms"),提取对应时空交互平滑项的列,再加上对应size_bin的主效应和截距即可
  3. 匹配plot.gam的过滤规则
    调用mgcv::exclude.too.far函数,将预测网格中距离原始观测经纬度点过远的点的预测值设为NA,参数和plot.gam的too.far保持一致即可。
  4. 分面绘图
    按size_bin分面、按年份切片绘制经纬度热力图,或者制作动图展示时间维度的变化趋势。

4. 链接尺度预测值的反变换方法

你使用family(model)$linkinv进行反变换的做法完全正确,比直接用exp()更规范:

  • 对于当前的log链接负二项模型,family(model)$linkinv和exp()的计算结果完全一致
  • 该方法的通用性更强,如果你后续更换其他链接函数(比如cloglog、sqrt等),不需要修改代码逻辑,不会出现适配错误

5. 交叉验证代码的优化建议

你当前的交叉验证代码存在数据泄露问题,需要调整:

  • 交叉验证必须仅用训练集数据拟合模型,不能用到测试集的任何信息:你现在的代码是先在全量数据集上拟合了模型,再拆分训练测试,会高估模型的外推效果
  • 计算r²时,建议给计数加一个极小值避免0值报错:将cor(log(count_est),log(count))改为cor(log(count_est + 1e-6), log(count + 1e-6)),避免出现无穷值影响结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:54:00