问题描述
为什么我拥有完全相同的模型,但是在不同的网格大小(分别为0.001和0.01)上运行预测会得到不同的预测?
Why I have the exact same model, but run predictions on different grid size (by 0.001 vs by 0.01) getting different predictions?
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)
推荐答案
这是一个编码/编程问题,因为在我快速运行时,我无法通过在模型中放入poly()
进行适当的设置来重现此公式.因此,我认为这个问题更适合堆栈溢出.
This is a coding / programming problem as on my quick run I can't reproduce this with appropriate set-up by putting poly()
inside model formula. So I think this question better suited for 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)
cuttlefish44 指出了您的实现中的错误. 在制作预测矩阵时,我们希望在模型矩阵中使用构造信息,而不是构造新的基础.如果您想知道这种构造信息"是什么,也许您可以仔细研究一下长答案: poly()如何生成正交多项式?如何理解返回的珊瑚"?
cuttlefish44 has pointed out the fault in your implementation. When making prediction matrix, we want to use the construction information in model matrix, rather than constructing a new set of basis. If you wonder what such "construction information" is, perhaps you can go through this very long answer: How poly() generates orthogonal polynomials? How to understand the "coefs" returned?
也许我可以尝试做一个简短的总结并解决冗长而详细的答案.
Perhaps I can try making a brief summary and getting around that long, detailed answer.
- 正交多项式的构造始终从居中输入协变量值
x
开始.如果此中心不同,则其余所有中心都将不同.现在,这是poly(x, coef = NULL)
和poly(x, coef = some_coefficients)
之间的区别.前者将始终使用新的中心构建新的基准集,而后者将使用some_coefficients
中的现有中心信息来预测给定设置的基准值.当然,这是我们进行预测时想要的. -
poly(x, coef = some_coefficients)
实际上会调用predict.poly
(我在那个长长的答案中对此进行了解释).除非我们正在进行测试,否则当我们需要自行设置coef
参数时,这种情况相对很少见.如果我们使用上面快速运行中介绍的方式建立线性模型,则predict.lm
足够聪明,可以实现预测poly
模型项的正确方法,即,在内部它将为我们完成poly(new_x, coef = some_coefficients)
. - 作为一个有趣的对比,普通多项式对此没有问题.例如,如果在代码中的所有
poly()
调用中指定raw = TRUE
,则不会有麻烦.这是因为原始多项式没有构造信息.它只是在使用x
的1, 2, ... degree
力量.
- The construction of orthogonal polynomial always starts from centring the input covariate values
x
. If this centre is different, then all the rest will be different. Now, this is the difference betweenpoly(x, coef = NULL)
andpoly(x, coef = some_coefficients)
. The former will always construct a new set of basis using a new centre, while the latter, will use the existing centring information insome_coefficients
to predict basis value on given set-up. Surely this is what we want when making prediction. poly(x, coef = some_coefficients)
will actually callpredict.poly
(which I explained in that long answer). It is relatively rare when we need to setcoef
argument ourselves, unless we are doing testing. If we set up the linear model using the way I present in my quick run above,predict.lm
is smart enough to realize the correct way to predictpoly
model terms, i.e., internally it will do thepoly(new_x, coef = some_coefficients)
for us.- As an interesting contrast, ordinary polynomial don't have problem with this. For example, if you specify
raw = TRUE
in allpoly()
calls in your code, you will have no trouble. This is because raw polynomial has no construction information; it is just taking powers1, 2, ... degree
ofx
.
这篇关于当仅预测网格的分辨率发生变化时,为什么预测多项式会急剧变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!