如何为smooth.spline()选择平滑参数?

时间:2013-02-18 03:59:33

标签: r lambda smooth spline smoothing

我知道平滑参数(lambda)对于拟合平滑样条非常重要,但是我没有看到关于如何选择合理的lambda(spar =?)的任何帖子,我被告知spar通常来自0到1.使用smooth.spline()时,有没有人可以分享你的经验?感谢。

    smooth.spline(x, y = NULL, w = NULL, df, spar = NULL,
          cv = FALSE, all.knots = FALSE, nknots = NULL,
          keep.data = TRUE, df.offset = 0, penalty = 1,
          control.spar = list(), tol = 1e-6 * IQR(x))

3 个答案:

答案 0 :(得分:9)

agstudy提供了一种选择spar的直观方式。我记得我从线性模型类(但不精确)学到的是使用交叉验证来选择“最佳”spar。这是从agstudy借来的玩具示例:

x = seq(1:18)
y = c(1:3,5,4,7:3,2*(2:5),rep(10,4))
splineres <- function(spar){
  res <- rep(0, length(x))
  for (i in 1:length(x)){
    mod <- smooth.spline(x[-i], y[-i], spar = spar)
    res[i] <- predict(mod, x[i])$y - y[i]
  }
  return(sum(res^2))
}

spars <- seq(0, 1.5, by = 0.001)
ss <- rep(0, length(spars))
for (i in 1:length(spars)){
  ss[i] <- splineres(spars[i])
}
plot(spars, ss, 'l', xlab = 'spar', ylab = 'Cross Validation Residual Sum of Squares' , main = 'CV RSS vs Spar')
spars[which.min(ss)]
R > spars[which.min(ss)]
[1] 0.381

enter image description here

代码不是最好的,但很容易理解。另外,如果您在cv=T中指定smooth.spline

R > xyspline <- smooth.spline(x, y, cv=T)
R > xyspline$spar
[1] 0.3881

答案 1 :(得分:5)

smooth.spline的帮助下,您有以下内容:

  

使用的计算λ(作为\ code {spar}的函数)是λ= r *   256 ^(3 * spar - 1)

晶石可以大于1(但我猜不会太多)。我认为您可以改变这些参数并通过绘制不同翼梁的拟合值以图形方式选择它。例如:

spars <- seq(0.2,2,length.out=10)          ## I will choose between 10 values 
dat <- data.frame(
  spar= as.factor(rep(spars,each=18)),    ## spar to group data(to get different colors)
  x = seq(1:18),                          ## recycling here to repeat x and y 
  y = c(1:3,5,4,7:3,2*(2:5),rep(10,4)))
xyplot(y~x|spar,data =dat, type=c('p'), pch=19,groups=spar,
       panel =function(x,y,groups,...)
       {
          s2  <- smooth.spline(y,spar=spars[panel.number()])
          panel.lines(s2)
          panel.xyplot(x,y,groups,...)
       })

例如,我得到spars = 0.4

的最佳结果

enter image description here

答案 2 :(得分:3)

如果你没有相同x值的重复点,那么尝试设置GCV = TRUE - 广义交叉验证(GCV)程序是一种聪明的方法,可以选择一个非常好的方法来为lambda选择一个好的值(跨度)。关于GCV的一个简洁细节是它实际上不必为每一组一个左撇子点进行计算的麻烦 - 正如Simon Wood的书中所强调的那样。有关这方面的详细信息,请查看Simon Wood在MGCV上的网页上的说明。

Adrian Bowman的(sm)r-package有一个函数h.select(),专门用于选择lambda值的繁琐工作(虽然我不是100%确定它与{基本包中的{1}}函数。