mgcv:修复GAMM中的平滑参数和模型嵌套的有效性

时间:2016-11-09 10:15:58

标签: r regression mixed-models gam mgcv

我目前正在尝试使用x包中的协变量gamm(年龄)和性别0-1变量与mgcv之间的互动进行建模。在为每个性别指定一个具有平滑术语的主模型(让我们称之为M0)后,我想测试一个更简单的假设,即性别之间的差异是线性的(而不是任意平滑)。我有以下两个问题:

  1. 当试图正确地嵌套模型时,我想从M0中获得0-性别平滑的平滑参数,并在更简单的模型规范中使用它。但是我收到以下错误消息:
  2.   

    gamm.setup出错(gp,pterms = pTerms,data = mf,knots = knots,parametric.only = FALSE,:

         

    gamm无法处理链接的平滑参数(可能来自使用`id'或自适应平滑)

    1. 第二个问题是更愚蠢的问题。当我从平滑的每个性别变为0性别平滑和线性差异到1性别时,模型是否甚至嵌套?
    2. 下面是一个例子。我模拟了一些随机数据,因此数据不会显示我实际数据的行为,但问题仍然存在。

      library(mgcv) 
      
      ### Simulate random data
      x <- rnorm(100, mean = 10, sd = 1.5)
      y <- rnorm(100, mean = 1, sd = 0.025)
      
      id <- sample(1:10, size = 100, replace = T)
      id <- as.factor(id)
      
      gender <- sample(c(0,1), size = 100, replace = T)
      
      
      ### Specify main model, M0
      ctrl <- list(niterEM=0,optimMethod="L-BFGS-B", msMaxIter = 100)
      M0 <- gamm(y~s(x, by = as.factor(gender)) + gender, 
                 random=list(id=~1+x), control=ctrl)
      
      ### Specify model with linear difference between gender0 and gender1
      M1 <- gamm(y~s(x) + gender:x + gender, 
                 random=list(id=~1+x), control=ctrl)
      
      ### Testing
      anova(M0$lme, M1$lme)
      
      ### Problems:
      sp0 <- M0$gam$sp[1]
      M1 <- gamm(y~s(x, sp = sp0) + gender:x + gender, 
                 random=list(id=~1+x), control=ctrl)
      
        

      gamm.setup出错(gp,pterms = pTerms,data = mf,knots = knots,parametric.only = FALSE,:

           

      gamm无法处理链接的平滑参数(可能来自使用`id'或自适应平滑)

      有什么想法?提前谢谢。

1 个答案:

答案 0 :(得分:3)

关于gamm错误

这是一件非常有趣的事情......好吧,我应该首先解释逻辑。

原则上gamm 中修复平滑参数是违法的,因为gamm会将平滑的摇摆组件视为随机效果,其方差为由lme估算(因为你有高斯数据)。如果您尝试修复平滑参数,那基本上就是说要修复随机效果的方差。好吧,lme不允许你这样做(我怀疑这种尝试在混合建模中是否合法。)

因此gamm会禁用平滑参数的任何可能限制,包括:

  1. 平滑参数的下限,通过min.sp;
  2. 通过id;
  3. 中的s()链接平滑共享相同的平滑参数
  4. 通过sp直接指定平滑参数,通过s()
  5. 前两个完美检查。 gamm没有像min.sp那样的gam参数;即使您通过...指定它,也不会被使用(因为在NULL期间传递给gam.setup的{​​{1}}之后,所以您的指定{{1}被忽略了)。您看到的错误消息也会检测到gamm.setup的规范,但当然您没有指定min.sp,因此上述错误并未在此处报告正确的问题,因此存在错误。

    第三个,实际上并未通过id直接检查。理想情况下,只要id / gamm公式被解释(gamm),gam就应该重置为interpret.gam,如果不是,应发出关于此的警告信息。但是,这部分缺失了。因此,目前您可以做的最好的事情就是不指定sp

    您是否有有效的模型嵌套?

    现在让我们转向您对嵌套的关注。 嵌套与基础设置有关,而不是平滑参数的选择。只要您具有相同的基础集(相同的基础类型,相同数量和/或位置的“结”),模型矩阵将是相同的。例如,在您的模型-1sp中,您具有与M0默认M1 s()相同的配置。因此mgcv的设计矩阵在两个模型中是相同的。 bs = 'tp', k = 10只会将此s()复制到主模型by = factor(gender)s()的所有级别。也许它不容易看到,但实际上您的gender嵌套在M0

    让我们考虑一个小例子来验证这一点。为简单起见,我不会使用M1中的M0,而是使用s(x)(想象它是mgcv)。让我们先生成一些玩具数据:

    poly(x, degree = 2)

    由于s(x)不是有序因子,x <- 1:10 f <- gl(2, 5, labels = c("M", "F")) 通过为f的所有级别复制s(x, by = factor(f))来生成设计矩阵:

    s(x)

    您的第二个模型f只有一个平滑的术语## original design matrix for `s(x)` X0 <- poly(x, 2) ## design matrix for `f`, without contrasting Xf <- model.matrix(~ f + 0) ## design matrix for level `M` X1 <- X0 * Xf[, 1] ## design matrix for level `F` X2 <- X0 * Xf[, 2] ## design matrix for `s(x, by = f)` "please, imagine it as `poly`" X <- cbind(X1, X2) # 1 2 1 2 # [1,] -0.49543369 0.52223297 0.00000000 0.00000000 # [2,] -0.38533732 0.17407766 0.00000000 0.00000000 # [3,] -0.27524094 -0.08703883 0.00000000 0.00000000 # [4,] -0.16514456 -0.26111648 0.00000000 0.00000000 # [5,] -0.05504819 -0.34815531 0.00000000 0.00000000 # [6,] 0.00000000 0.00000000 0.05504819 -0.34815531 # [7,] 0.00000000 0.00000000 0.16514456 -0.26111648 # [8,] 0.00000000 0.00000000 0.27524094 -0.08703883 # [9,] 0.00000000 0.00000000 0.38533732 0.17407766 #[10,] 0.00000000 0.00000000 0.49543369 0.52223297 ,其设计矩阵为M1

    以下是我们如何看待您的s(x)嵌套在X0中:

    1. 作为M1M0X1 + X2 = X0的设计矩阵具有相同的列范围,因此s(x)嵌套在s(x, by = f);
    2. 由于s(x)嵌套在s(x, by = f)中,x嵌套在s(x)中。
    3. 我会做什么

      虽然您的模型已经很好地嵌套,但主模型x:f与您的s(x, by = f)没有相似的解释。您的主要模型M0最终将为每个级别提供一个独立的平滑,而您的M1则关注两个组之间的差异。

      如果我们能够控制M0接受一种“参考平滑+差异平滑”的形式,那将是一件好事。然后,如果差异平滑变成一条线,而没有实际拟合M1,我们已经知道没有证据表明组之间存在非线性差异。

      M0中,如果您的因子是有序的,则将构建差异平滑。所以我建议你适合你的主要模型:

      M1

      如果估算结果显示差异平滑mgcv为一条线,则您知道可以改为使用更简单的模型

      gender1 <- ordered(gender)  ## create an ordered factor
      s(x) + s(x, by = gender1) + gender
      

      即使不使用s(x, by = gender1)

      注意,为了构造“差异”平滑,有一个有序因子s(x) + gender:x + gender 是非常重要的。如果你这样做

      F-test

      bys(x) + s(x, by = gender) + gender ## note, it is "gender" in "by" 完全线性相关。生成的模型矩阵将排名不足

      一些后续行动

        

      我忘了在我的示例中包含我首先将AIC参数化为s(x)s(x, by = gender)的相同模型进行比较(回忆s(x, by = as.factor(gender))为0-1数值变量)。这些模型在统计上是等价的,但在这些情况下,平滑参数显然有不同的估计,因此AIC略有不同。

      哦,是的。您的s(x) + s(x, by = gender)是二进制的,因此数字gender也是构建差异平滑的好主意。但要小心这样做。数字gender不会产生居中的光滑。因此,by将隐式地具有拦截列,与模型拦截混淆。你应该使用by