当只有预测网格的分辨率发生变化时,为什么预测多项式会发生剧烈变化?

时间:2016-11-04 02:23:01

标签: r regression linear-regression lm polynomials

为什么我拥有完全相同的模型,但是对不同的网格大小(0.001比较0.01)进行预测会得到不同的预测?

set.seed(0)
n_data=2000
x=runif(n_data)-0.5
y=0.1*sin(x*30)/x+runif(n_data)
plot(x,y)


poly_df=5
x_exp=as.data.frame(cbind(y,poly(x, poly_df)))
fit=lm(y~.,data=x_exp)

x_plt1=seq(-1,1,0.001)
x_plt_exp1=as.data.frame(poly(x_plt1,poly_df))
lines(x_plt1,predict(fit,x_plt_exp1),lwd=3,col=2)

x_plt2=seq(-1,1,0.01)
x_plt_exp2=as.data.frame(poly(x_plt2,poly_df))
lines(x_plt2,predict(fit,x_plt_exp2),lwd=3,col=3)

enter image description here

2 个答案:

答案 0 :(得分:5)

这是一个编码/编程问题,因为在我的快速运行中,我可以通过将poly()置于模型公式中并通过适当的设置重现此。所以我认为这个问题更适合Stack Overflow。

## quick test ##

set.seed(0)
x <- runif(2000) - 0.5
y <- 0.1 * sin(x * 30) / x + runif(2000)
plot(x,y)

x_exp <- data.frame(x, y)
fit <- lm(y ~ poly(x, 5), data = x_exp)

x1 <- seq(-1, 1, 0.001)
y1 <- predict(fit, newdata = list(x = x1))
lines(x1, y1, lwd = 5, col = 2)

x2 <- seq(-1, 1, 0.01)
y2 <- predict(fit, newdata = list(x = x2))
lines(x2, y2, lwd = 2, col = 3)

enter image description here

cuttlefish44 指出了您实施中的错误。 在制作预测矩阵时,我们希望在模型矩阵中使用构造信息,而不是构建一组新的基础。如果你想知道这样的&#34;构造信息&#34;也许你可以通过这个很长的答案:How poly() generates orthogonal polynomials? How to understand the “coefs” returned?

也许我可以尝试做一个简短的总结,并绕过这个详尽的答案。

  1. 正交多项式的构造总是从输入协变量值x的中心开始。如果这个中心不同,那么其余的都将是不同的。现在,这是poly(x, coef = NULL)poly(x, coef = some_coefficients)之间的差异。前者将始终使用新中心构建一组新的基础,而后者将使用some_coefficients中的现有中心信息来预测给定设置的基础值。当然,这是我们在进行预测时所需要的。
  2. poly(x, coef = some_coefficients)实际上会调用predict.poly(我在那个长答案中解释过)。除非我们正在进行测试,否则我们需要自己设置coef参数是相对罕见的。如果我们使用上面快速运行中提供的方式设置线性模型,predict.lm足够聪明,可以实现预测poly模型术语的正确方法,即在内部它将执行{poly(new_x, coef = some_coefficients) 1}}对我们来说。
  3. 作为一个有趣的对比,普通的多项式没有问题。例如,如果您在代码中的所有raw = TRUE次调用中指定poly(),那么您将毫无困难。这是因为原始多项式没有构造信息;它仅仅取得1, 2, ... degree的权力x

答案 1 :(得分:4)

首先,预测线不适合原始数据。您未能使poly objs进行预测。

...
poly_ori <- poly(x, poly_df)    # important
...   

plot(x,y)

x_plt1 = seq(-1, 1, 0.001)
x_plt_exp1 = as.data.frame(poly(x_plt1, poly_df, coefs = attr(poly_ori, "coefs")))
lines(x_plt1, predict(fit, x_plt_exp1),lwd = 3, col = 2)

x_plt2 = seq(-1, 1, 0.01)
x_plt_exp2 = as.data.frame(poly(x_plt2, poly_df, coefs = attr(poly_ori, "coefs")))
lines(x_plt2, predict(fit, x_plt_exp2), lwd = 3, col = 3)