返回错误使用具有周期性平滑的GAM预测新数据

时间:2012-07-31 22:06:11

标签: r gam

如果这更适合CrossValidated,请道歉。

我使用R中的mgcv包将GAM模型拟合到二项式数据。其中一个协变量是周期性的,因此我指定bs = "cc"循环三次样条。我在交叉验证框架中这样做,但是当我使用predict函数调整我的保持数据时,我得到以下错误:

Error in pred.mat(x, object$xp, object$BD) : 
  can't predict outside range of knots with periodic smoother

以下是一些应该复制错误的代码:

# generate data:
x <- runif(100,min=-pi,max=pi)
linPred <- 2*cos(x) # value of the linear predictor
theta <- 1 / (1 + exp(-linPred)) # 
y <- rbinom(100,1,theta)
plot(x,theta)
df <- data.frame(x=x,y=y)

# fit gam with periodic smoother:
gamFit <- gam(y ~ s(x,bs="cc",k=5),data=df,family=binomial())
summary(gamFit)

plot(gamFit)

# predict y values for new data:
x.2 <- runif(100,min=-pi,max=pi)
df.2 <- data.frame(x=x.2)
predict(gamFit,newdata=df.2)

对于我出错的地方的任何建议将不胜感激。也许手动指定结点落在-pi和pi?

2 个答案:

答案 0 :(得分:2)

我在第一次运行时没有收到错误,但我确实在第二次尝试时复制了错误。也许您需要使用set.seed(123) #{no error}set.seed(223) #{produces error}。看看是否会产生部分成功。我认为您只是在派生和验证数据集中看到一些变量而且点数相对较少。 GAM fit的100分并不是特别“慷慨”。

查看gamFit对象,看起来结的范围是用gamFit$smooth[[1]]['xp']编码的,因此这应该将输入限制在适当的范围内:

 x.2 <- runif(100,min=-pi,max=pi); 
 x.2 <- x.2[findInterval(x.2, range(gamFit$smooth[[1]]['xp']) )== 1]

 # Removes the errors in all the situations I tested
 # There were three points outside the range in the set.seed(223) case

答案 1 :(得分:1)

问题是您的测试集包含的值不在训练集的范围内。由于您使用了样条曲线,因此在x的最小值和最大值处创建了结,并且未在该范围之外定义拟合函数。因此,在测试模型时,应排除那些超出范围的点。以下是如何排除测试集中的点:

set.seed(2)
... <Your code>
predict(gamFit,newdata=df.2[df.2$x>=min(df$x) & df.2$x<=max(df$x),,drop=F])

或者,您可以将模型中的“外部”结点指定为整个数据的最小值和最大值。我不知道该怎么做。