我正试图在过度拟合上重现this blog post。我想探索样条曲线与测试多项式的比较。
我的问题:使用rcs() - 受限制的三次样条 - 来自rms包我在常规lm()中应用时会得到非常奇怪的预测。 ols()工作正常,但我对这种奇怪的行为感到有些惊讶。有人可以向我解释发生了什么吗?
library(rms)
p4 <- poly(1:100, degree=4)
true4 <- p4 %*% c(1,2,-6,9)
days <- 1:70
noise4 <- true4 + rnorm(100, sd=.5)
reg.n4.4 <- lm(noise4[1:70] ~ poly(days, 4))
reg.n4.4ns <- lm(noise4[1:70] ~ ns(days,5))
reg.n4.4rcs <- lm(noise4[1:70] ~ rcs(days,5))
dd <- datadist(noise4[1:70], days)
options("datadist" = "dd")
reg.n4.4rcs_ols <- ols(noise4[1:70] ~ rcs(days,5))
plot(1:100, noise4)
nd <- data.frame(days=1:100)
lines(1:100, predict(reg.n4.4, newdata=nd), col="orange", lwd=3)
lines(1:100, predict(reg.n4.4ns, newdata=nd), col="red", lwd=3)
lines(1:100, predict(reg.n4.4rcs, newdata=nd), col="darkblue", lwd=3)
lines(1:100, predict(reg.n4.4rcs_ols, newdata=nd), col="grey", lwd=3)
legend("top", fill=c("orange", "red", "darkblue", "grey"),
legend=c("Poly", "Natural splines", "RCS - lm", "RCS - ols"))
正如你所看到的那样,暗蓝色就在这个地方......
答案 0 :(得分:3)
只要指定结,就可以将rcs()与非均方根钳制器配合使用。预测默认值是ols对象的predict.ols,这很好,因为它可以“记住”适合模型的位置。 Forecast.lm不具有此功能,因此它使用新数据集的分布来确定结的位置,而不是训练数据的分布。
答案 1 :(得分:0)
即使在lm
中指定了结,将rcs
与rcs
一起使用也是一个坏主意。这是一个示例:
假数据。
library(tidyverse)
library(rms)
set.seed(100)
xx <- rnorm(1000)
yy <- 10 + 5*xx - 0.5*xx^2 - 2*xx^3 + rnorm(1000, 0, 4)
df <- data.frame(x=xx, y=yy)
设置您的环境以使用ols
。
ddist <- datadist(df)
options("datadist" = "ddist")
适合lm
模型和ols
模型。
mod_ols <- ols(y ~ rcs(x, parms=c(min(x), -2, 0, 2, max(x))), data=df)
mod_lm <- lm(y ~ rcs(x, parms=c(min(x),-2, 0, 2, max(x))), data=df)
创建测试数据集。
newdf <- data.frame(x=seq(-10, 10, 0.1))
在得分newdf
之后比较模型预测。
preds_ols <- predict(mod_ols, newdata=newdf)
preds_lm <- predict(mod_lm, newdata=newdf)
mean((preds_ols - preds_lm)^2)
as.numeric(coef(mod_ols))
as.numeric(coef(mod_lm))
compare_df <- newdf
compare_df$ols <- preds_ols
compare_df$lm <- preds_lm
compare_df <- compare_df %>%
gather(key="model", value="prediction", -x)
ggplot(compare_df, aes(x=x, y=prediction, group=model, linetype=model)) +
geom_line()
即使两个模型之间的系数相同,对新数据的模型预测也可能不同。
编辑:
删除参数max()
中对min()
和parms
的函数调用即可解决此问题。
kKnots <- with(df, c(min(x), -2, 0, 2, max(x))) ## hard-code
mod_ols <- ols(y ~ rcs(x, parms=kKnots), data=df)
mod_lm <- lm(y ~ rcs(x, parms=kKnots), data=df)