我使用bam中的mgcv函数将相同的通用加性模型拟合到多个数据集。虽然对于我的大多数数据集,拟合过程都在10到20分钟之间的合理时间内完成。对于一些数据集,运行需要10多个小时才能完成。我发现慢速情况之间没有任何相似之处,最终拟合既不是特别好也不是坏,也不包含任何明显的异常值。

我如何弄清楚为什么在这些情况下拟合如此之慢?而我又如何能够加快这些速度呢?

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

这是函数调用:

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节。

在大多数情况下,该模型收敛得很快,而在少数情况下,收敛得非常慢。

最佳答案

最可能的原因:“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年正式发布)。它使用了新的拟合迭代。与旧方法相比,我们(MUCH)更愿意测试其实际收敛能力。使用时,也请打开“跟踪”。如果它无法收敛,请考虑报告它,但是我们需要一个可重现的案例。

关于r - 为什么来自mgcv的bam对于某些数据比较慢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40788972/

10-10 00:37