为什么仅预测网格的分辨率发生变化时预测多项式会发生巨大变化?
Why predicted polynomial changes drastically when only the resolution of prediction grid changes?
为什么我有完全相同的模型,但 运行 对 不同网格大小的预测(相差 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)
这是一个编码/编程问题,正如我的快速 运行 我无法通过将 poly()
放入模型公式[=44 中,通过适当的设置重现此问题 =].所以我认为这个问题更适合 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 指出了您实施中的错误。 在制作预测矩阵时,我们希望利用模型矩阵中的构造信息,而不是构造一组新的基。如果你想知道这样的"construction information"是什么,也许你可以通过这个很长的答案:
也许我可以试着做一个简短的总结,然后绕过那个又长又详细的答案。
- 正交多项式的构造总是从输入协变量值居中开始
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
的权力。
首先,预测线与原始数据不符。您未能为预测创建 poly
个对象。
...
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)
为什么我有完全相同的模型,但 运行 对 不同网格大小的预测(相差 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)
这是一个编码/编程问题,正如我的快速 运行 我无法通过将 poly()
放入模型公式[=44 中,通过适当的设置重现此问题 =].所以我认为这个问题更适合 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 指出了您实施中的错误。 在制作预测矩阵时,我们希望利用模型矩阵中的构造信息,而不是构造一组新的基。如果你想知道这样的"construction information"是什么,也许你可以通过这个很长的答案:
也许我可以试着做一个简短的总结,然后绕过那个又长又详细的答案。
- 正交多项式的构造总是从输入协变量值居中开始
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
的权力。
首先,预测线与原始数据不符。您未能为预测创建 poly
个对象。
...
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)