【问题标题】:Error returned predicting new data using GAM with periodic smoother使用具有周期性平滑器的 GAM 预测新数据时返回错误
【发布时间】:2012-07-31 22:06:11
【问题描述】:

抱歉,如果这更适合 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 上?

【问题讨论】:

  • 好问题,但是当您生成数据时,请确保使用set.seed,以便每次都获得相同的数据。例如,在代码顶部使用set.seed(2),您将重新生成错误。

标签: r gam


【解决方案1】:

我在第一次运行时没有收到错误,但在第二次尝试时我确实复制了错误。也许您需要使用set.seed(123) #{no error}set.seed(223) #{produces error}。看看这是否会产生部分成功。我认为您只是在推导和验证数据集中看到了一些点相对较少的变化。适合 GAM 的 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

【讨论】:

  • 嗯,这很有道理。抱歉 set.seed 问题。感谢您的部分解决方案。
【解决方案2】:

问题在于您的测试集包含不在您的训练集范围内的值。由于您使用了样条曲线,因此在 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])

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

【讨论】:

  • 这很有道理,谢谢。我将尝试看看如何将外部结设置为 -pi / +pi。这对我来说似乎比仅仅切断新数据更简洁,因为数据的理论范围是 -pi -- pi。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2017-11-15
  • 2012-10-17
  • 1970-01-01
相关资源
最近更新 更多