如何使用smooth.spline()函数制作单调(增加)平滑样条曲线?

时间:2014-08-22 13:17:33

标签: r spline

由于易于使用此功能,我的数据严格增加,并且希望适合平滑样条,如果可能的话,也会使smooth.spline()函数单调增加。

例如,我可以使用以下示例有效地复制我的数据:

testx <- 1:100
testy <- abs(rnorm(length(testx)))^3
testy <- cumsum(testy)
plot(testx,testy)
sspl <- smooth.spline(testx,testy)
lines(sspl,col="blue")

不一定在各处增加。有什么建议吗?

3 个答案:

答案 0 :(得分:10)

这不会使用smooth.spline(),但splinefun(..., method="hyman")将适合单调递增的样条曲线并且也易于使用。例如:

testx <- 1:100
testy <- abs(rnorm(length(testx)))^3
testy <- cumsum(testy)
plot(testx,testy)
sspl <- smooth.spline(testx,testy)
lines(sspl,col="blue")
tmp <- splinefun(x=testx, y=cumsum(testy), method="hyman")
lines(testx[-1], diff(tmp(testx)), col="red")

产生下图(红色是单调增加样条曲线的值) enter image description here

来自splinefun的帮助文件:&#34;方法&#34; hyman&#34;使用Hyman过滤方法计算单调三次样条=&#34; fmm&#34;适合严格的单调输入。 (在R 2.15.2中添加。)&#34;

答案 1 :(得分:2)

您可以使用形状受限的样条曲线,例如使用scam包:

require(scam)
fit = scam(testy~s(testx, k=100, bs="mpi", m=5), 
            family=gaussian(link="identity"))
plot(testx,testy)
lines(testx,predict(fit),col="red")

enter image description here

或者如果你想使用L1损失而不是L2丢失,这对于异常值不太敏感,你也可以使用cobs包...

与上述解决方案相比,此方法的优点在于,如果原始数据由于存在噪声而可能不是100%单调的,它也可以工作......

答案 2 :(得分:0)

我建议使用loess来实现这种单调增加的功能。

检查样条曲线的导数我们发现在某些情况下它是负面的和非平凡的:

> plot(testx,testy)
> sspl <- smooth.spline(testx,testy)
> min(diff(sspl$y))
[1] -0.4851321

如果我们使用黄土,我认为这个问题会不那么严重。

 d <- data.frame(testx,testy)
 fit.lo <- loess(testy ~ testx,data=d)
 lines(fit.lo$x,fit.lo$y)

然后检查我们得到的衍生物:

> min(diff(fit.lo$y))
[1] 1.151079e-12

这基本上是0.在接近0时,我们有时得到一个非常小的负值。

以下是上述黄土适合的示例。 enter image description here

不确定这是否适用于所有情况,但似乎比样条更好。