使用自然样条拟合进行预测

3

我已经拟合了一个简单的自然样条(df = 3)模型,现在想对一些样本外的观测值进行预测。使用 predict() 函数,我可以得到样本内观测值的拟合值,但是我无法得到新观测值的预测值。

以下是我的代码:

library(splines)

set.seed(12345)
x <- seq(0, 2, by = 0.01)
y <- rnorm(length(x)) + 2*sin(2*pi*(x-1/4))

# My n.s fit:
fit.temp <- lm(y ~ ns(x, knots = seq(0.01, 2, by = 0.1)))

# Getting fitted values:
fit.temp.values <- predict(fit.temp,interval="prediction", level = 1 - 0.05)

# Plotting the data, the fit, and the 95% CI:
plot(x, y, ylim = c(-6, +6))
lines(x, fit.temp.values[,1], col = "darkred")
lines(x, fit.temp.values[,2], col = "darkblue", lty = 2)
lines(x, fit.temp.values[,3], col = "darkblue", lty = 2)

# Consider the points for which we want to get the predicted values:
x.new <- c(0.275, 0.375, 0.475, 0.575, 1.345)

如何获取x.new的预测值?

非常感谢您的帮助,

p.s. 我在SO上搜了所有相关问题,但没有找到答案。


有一些针对上述示例的简单解决方案。我的观点是学习使用predict()函数来获取外样本观测值的预测值。 - Sam
你的第一步应该是阅读?predict.lm - Roland
嗨@Roland,感谢您的评论。我做了。问题是当我们的协变量中有ns()时,我不知道“newdata”应该是什么。 - Sam
2个回答

8
创建一个包含名为x的列的数据框,并将其作为newdata参数传递给predict函数:
predict(fit.temp, newdata=data.frame(x=x.new))

谢谢 @Hong Ooi。在发帖之前,我尝试过这个方法,但是我没有在数据框中加入x,所以出现了错误。现在问题已经解决了。 - Sam

1
你正在向lm发送单独的向量。如果你想知道这里出了什么问题,那么请键入:
 fit.temp$terms

请注意,x-predictor的名称是:

attr(,"term.labels")
[1] "ns(x, knots = seq(0.01, 2, by = 0.1))"

你需要给predict一个以x为名称的列表。更简单的方法是使用lmlm.predict,并使用数据框作为参数进行预测,以便可以通过内部重新评估新值来进行预测。

 df <- data.frame(x,y)
 # My n.s fit:
 fit.temp <- lm(y ~ ns(x, knots = seq(0.01, 2, by = 0.1)) , data=df)
 predict(fit.temp, newdata=list(x =c(0.275, 0.375, 0.475, 0.575, 1.345) )  )
#        1         2         3         4         5 
#0.9264572 1.6549046 2.0743470 1.9507962 0.8220687 
points(x.new, predict(fit.temp, 
               newdata=list(x =c(0.275, 0.375, 0.475, 0.575, 1.345) )), 
       col="red", cex=2)

1
实际上,predict.lm 足够聪明,可以计算出底层变量是 x。不需要将变量收集到数据框中(尽管这通常是一个好主意)。 - Hong Ooi
所以,原帖失败的原因只是因为他没有使用 list(x=new.x) 吗?我感到非常尴尬。 - IRTFM
谢谢你们俩的帮助。问题是我使用了x.new本身,而不是将它放在data.frame中,所以出现了错误。现在问题已经解决了。 - Sam
你没有在传递给 predict 函数的参数中将其命名为 "x",这是问题所在。函数试图强制转换为类 'data.frame'。 - IRTFM
好的。完成了。我还尝试添加lowesslowess,但它们都还不存在标签中。 - IRTFM
不行,我尝试过但失败了。显然这两个标签都还不存在。我知道它们是不同的。你提到的参数样条允许指定基础,而lowess和loess是局部平滑样条,可用的控制较少。 - IRTFM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接