9

我使用bam来自的函数在多个数据集上拟合相同的广义加法模型mgcv。而对于我的大多数数据集,拟合在 10 到 20 分钟之间的合理时间内完成。对于一些数据集,运行需要 10 多个小时才能完成。我找不到慢案例之间的任何相似之处,最终的拟合既不是特别好也不是特别差,也不包含任何明显的异常值。

我如何才能弄清楚为什么这些实例的拟合速度如此之慢?我怎样才能加快这些速度?

我的模型包含两个平滑项(使用循环三次样条基础)和一些额外的数值和因子变量。总共估计了 300 个系数(包括平滑项的系数)。我故意将节数保持在理论上最佳的信息以下,以加快拟合过程。我的数据集包含大约 850k 行。

这是函数调用:

bam(
    value
    ~ 0
    + weekday_x
    + weekday
    + time
    + "a couple of factor variables encoding special events"
    + delta:weekday
    + s(share_of_year, k=length(knotsYear), bs="cc")
    + s(share_of_year_x, k=length(knotsYear), bs="cc")
    , knots=list(
      share_of_year=knotsYear
      , share_of_year_x=knotsYear
    )
    , family=quasipoisson()
    , data=data
)

节年包含 26 节。

这个模型在大多数情况下收敛得相当快,但在少数情况下却慢得令人难以置信。

4

1 回答 1

18

最可能的原因:“fREML”失败

在像上面这样的典型模型中,没有张量平滑teti,我的经验是 REML 迭代在某些情况下会失败。

规范bam实现使用fast.REML.fit. 此例程的收敛测试需要修复,但随着 Simon 继续前进并更多地关注该discrete方法,他并不热衷于修复它。固定版本(目前)仅在用于测试的扩展包中可用,“哲元插件”是我博士论文的补充。但fast.REML.fit也不是那么脆弱,这样的收敛失败并不常见,否则成堆的大报告会在 2012 年解决这个问题。

以下内容只是帮助您进行检查而不是修复。

fit您成为需要 10 小时的合身模型,检查fit$outer.info。这给出了它需要的 REML 迭代次数,以及梯度和 Hessian 等收敛信息。如果你看到iter = 200,或者任何信息说一些失败,比如“步骤失败”,那么你就会知道为什么需要这么长时间。但是,如果您查看梯度,您很可能会发现它几乎为零。换句话说,REML 迭代实际上已经收敛但fast.REML.fit未能检测到它。


另一个检查:“性能迭代”

由于您正在拟合 GAM 而不是 AM(具有高斯响应的加法模型),因此在 REML 迭代之外还有另一个 P-IRLS(惩罚迭代重新加权最小二乘)。是的,整个(规范)bam估计是一个双循环嵌套,称为“性能迭代”。这也可能失败,但这种失败更内在,可能无法克服,因为“性能迭代”不能保证收敛。所以,检查fit$iter它是否也很大(在最坏的情况下它可能是 200)。mgcv手册有一个专门的部分?gam.convergence讨论这种类型的收敛失败,这就是“外部迭代”是可取的驱动原因。然而,对于大型数据集,“外部迭代”的实现成本太高。所以,忍受“性能迭代”。

mgcv有一个“跟踪”选项。如果您control = gam.control(trace = TRUE)在调用时设置bam,则偏差信息和迭代计数器将随着“性能迭代”的进行而打印到屏幕上。这为您提供了一条清晰的受罚偏差路径,因此您可以检查它是在循环还是在某个点被困住。这比存储在fit$iter.


也许尝试新方法?

也许您想尝试新的discrete = TRUE(2015 年添加;论文于 2017 年正式发表)。它使用新的拟合迭代。与旧方法相比,我们(更)乐于测试其实际收敛能力。使用时,也要开启“trace”。如果它未能收敛,请考虑报告它,但我们需要一个可重现的案例。

于 2017-05-17T18:19:12.667 回答