使用样条曲线包中的bs函数指定b样条拟合的自由度

时间:2012-04-27 22:41:36

标签: r

我正在使用样条曲线包的bs函数来创建用于图形目的的b样条曲线平滑曲线。 (至少有一个报告表示Excel使用三阶b样条线作为其平滑线图,我希望能够复制这些曲线。)我无法理解bs函数所需的参数。代表性代码如下所示,改编自bs文档:

require(splines)
require(ggplot2)
n <- 10
x <- 1:10
y <- rnorm(n)
d <- data.frame(x=x, y=y)
summary(fm1 <- lm(y ~ bs(x, degree=3)), data=d)
x.spline <- seq(1, 10, length.out=n*10)
spline.data <- data.frame(x=x.spline, y=predict(fm1, data.frame(x=x.spline)))
ggplot(d, aes(x,y)) + geom_point + geom_line(aes(x,y), data=spline.data)

bs文档中的示例代码在对bs的调用中指定df = 5,并且未指定degree。我不知道我有多少自由度。我所知道的是我想要一个三阶b样条。我已经尝试过指定不同的df值而不是或者除了度数之外,我得到了截然不同的结果。这就是为什么我怀疑df的规格是这里的问题。在这种情况下我如何计算df?

帮助文件建议df = length(knots)+ degree。如果我将内部点视为结点,这个例子给出了df = 11,这会生成错误消息和无意义的样条拟合。

提前谢谢。

我的意图显然不清楚。我想这样做: How can I use spline() with ggplot?,但有b样条。

2 个答案:

答案 0 :(得分:2)

你不应该试图适应每一点。我们的目标是找到一个可接受的摘要,但这取决于有限数量的结。增加高于默认值3的多项式的hte度没有多大价值。只有10分你肯定不希望df = 11。尝试df = 5,结果应该相当平坦。 rms / Hnisc软件包作者Frank Harrell更喜欢受限制的三次样条,因为极值的预测是线性的,因此比其他多项式基数的预测更少。

我更正了几个拼写错误并添加了knots参数以使您的代码正常工作:

require(splines)
require(ggplot2); set.seed(trunc(100000*pi))

n <- 10
x <- 1:10
y <- rnorm(n)
d <- data.frame(x=x, y=y)
summary(fm1 <- lm(y ~ bs(x, degree=3, knots=2)), data=d)
x.spline <- seq(1, 10, length.out=n*10)
spline.data <- data.frame(x=x.spline, y=predict(fm1, data.frame(x=x.spline)))
ggplot(d, aes(x,y)) + geom_point() + geom_line(aes(x,y), data=spline.data)

我从弗兰克哈瑞尔知道他在说什么的意见中摒弃了改变随机种子的行为。在使用他的包裹时,我不会在极端情况下得到同样的行为。

答案 1 :(得分:0)

我做了一些工作并想出了以下内容。首先,道歉。我正在寻找的是平滑样条,而不是回归样条。我没有足够的词汇来恰当地表达问题。虽然bs()的帮助文件中的示例似乎提供了此功能,但该函数不会为我的示例数据提供相同的行为。在stats包中还有另一个函数smooth.spline,它提供了我需要的功能。

set.seed(tunc(100000*pi))
n <- 10
x <- 1:n
xx <- seq(1, n, length.out=200)
y <- rnorm(n)
d <- data.frame(x=x, y=y)
spl <- smooth.spline(x,y, spar=0.1)
spline.data <- data.frame(y=predict(spl,xx))
ggplot(d,aes(x,y)) + geom_point() + geom_line(aes(x,y), spline.data)
spl2 <- smooth.spline(x, y, control=
            list(trace=TRUE, tol=1e-6, spar=0.1, low=-1.5, high=0.3))
spline.data2 <- data.frame(predit(spl2,xx))
ggplot(d,aes(x,y)) + geom_point() + geom_line(aes(x,y), spline.data2)

对smooth.spline的两次调用代表两种方法。第一个手动指定平滑参数,第二个迭代到最佳解决方案。我发现我必须正确地约束优化以获得我所追求的解决方案类型。

结果旨在匹配Excel折线图使用的b样条曲线。我有合作者认为Excel图形是标准,我需要至少匹配该性能。