4

我正在尝试复制这篇关于过度拟合的博客文章。我想探索样条与测试多项式的比较。

我的问题:使用来自 rms 包的 rcs() - 受限三次样条曲线 - 在常规 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"))

如您所见,深蓝色到处都是……

剧情

4

2 回答 2

5

只要您指定结点,就可以将 rcs() 与非 rms 装配工一起使用。对于 ols 对象,predict 默认为 predict.ols,这很好,因为它“记住”了它在适合模型时放置结的位置。predict.lm 没有该功能,因此它使用新数据集的分布来确定节点的位置,而不是训练数据的分布。

于 2019-10-17T14:46:44.747 回答
0

使用lmwithrcs是个坏主意,即使您在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()删除参数中对andmin()的函数调用可以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)
于 2020-09-19T07:21:09.187 回答