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

R 如何使用smooth.spline()函数制作单调(递增)平滑样条曲线?,r,spline,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"

我有严格递增的数据,希望拟合一条单调递增的平滑样条曲线,如果可能,还可以使用
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")
testx我建议对这种单调递增函数使用

通过检查样条曲线的导数,我们发现它在某些情况下是负的且不平凡的:

> plot(testx,testy)
> sspl <- smooth.spline(testx,testy)
> min(diff(sspl$y))
[1] -0.4851321
基本上是0。在接近0时,我们有时会得到一个非常小的负值

下面是上述黄土拟合的一个示例。

不确定这是否在所有情况下都适用,但它似乎比样条函数做得更好。

我建议使用这种类型的单调递增函数

通过检查样条曲线的导数,我们发现它在某些情况下是负的且不平凡的:

> plot(testx,testy)
> sspl <- smooth.spline(testx,testy)
> min(diff(sspl$y))
[1] -0.4851321
基本上是0。在接近0时,我们有时会得到一个非常小的负值

下面是上述黄土拟合的一个示例。


不确定这是否在所有情况下都适用,但它似乎比样条曲线做得更好。

这并没有使用
平滑.spline()
,但是
样条曲线(…,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")

testx这不使用
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")

testx您可以为此使用形状约束样条线,例如使用
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")

或者,如果您希望使用L1损失而不是L2损失,因为L2损失对异常值不太敏感,那么您也可以使用
cobs
包来实现这一点


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

您可以使用形状约束样条曲线进行此操作,例如使用
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")

或者,如果您希望使用L1损失而不是L2损失,因为L2损失对异常值不太敏感,那么您也可以使用
cobs
包来实现这一点


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

您可以更改一些参数以产生所需的行为;这可能需要根据具体情况进行<代码>sspl谢谢!不幸的是,我正在寻找一个可推广的解决方案。也就是说,我的数据总是单调的,但每次运行样条曲线时都不同。鉴于数据是单调递增的,样条曲线真的最有意义吗?为什么不拟合单调递增函数?只是一个想法。你也可以选择另一种适合的方法。粒度可以通过
f
参数进行调整。一般来说,您可以将其封装在一个方法中,以尝试参数选项,并对照
min(diff(sspl$y,1))
进行检查,以确保单调的行为;这可能需要根据具体情况进行<代码>sspl谢谢!不幸的是,我正在寻找一个可推广的解决方案。也就是说,我的数据总是单调的,但每次运行样条曲线时都不同。鉴于数据是单调递增的,样条曲线真的最有意义吗?为什么不拟合单调递增函数?只是一个想法。你也可以选择另一种适合的方法。粒度可以通过
f
参数进行调整。一般来说,您可以将其封装在一个方法中,以尝试参数选项并检查
min(diff(sspl$y,1))
以确保单调的行为。
splinefun
正是我所需要的。对于未来的读者:
splinefun
返回一个可以直接调用的新函数,而不是传统意义上的合适模型。要使用此拟合样条函数预测新值,请调用新创建的函数并传入新数据。这取代了传统模型拟合中使用的
predict
。例如,
MonotonicSpline这仅在所有原始数据实际上都是单调递增的情况下才有效,即如果数据上没有噪声(否则splinefun将返回错误)。如果有,那么您可以在scam或cobs包中使用形状约束样条曲线,如下所述……作为对@TomWenseleers的回应:您对这一点的理解是正确的,仅适用于单调递增的数据。但是,这可能是由有噪声的数据引起的,其中基础数据有噪声,但您已经使用了累积和,
cumsum()
。我过去曾用它来插值非负值时间序列中的观测值。我希望在不同的时间尺度上观察到我的观测数据。例如,我需要每周的数据,但我只有关于公共卫生监测病例数的每月观察数据(即必须大于或等于0)。
splinefun
正是我需要的。对于未来的读者:
splinefun
返回一个可以直接调用的新函数,而不是传统意义上的合适模型。要使用此拟合样条函数预测新值,请调用新创建的函数并传入新数据。这取代了传统模型拟合中使用的
predict
。例如,
MonotonicSpline这仅在所有原始数据实际上都是单调递增的情况下才有效,即如果数据上没有噪声(否则splinefun将返回错误)。如果有,那么您可以在scam或cobs包中使用形状约束样条曲线,如下所述……作为对@TomWenseleers的回应:您对这一点的理解是正确的,仅适用于monotonica