我的问题:我最近遇到了一位统计学家,他告诉我样条曲线仅对探索数据有用并且会过度拟合,因此在预测中没有用。他更喜欢用简单的多项式进行探索......因为我是样条曲线的忠实粉丝,这违背了我的直觉,我有兴趣找出这些论点的有效性,以及是否存在大量反样条曲线-激进分子在那里?
背景:当我创建模型时,我尝试遵循 Frank Harrell,回归建模策略 (1)。他认为受限三次样条是探索连续变量的有效工具。他还认为,多项式在建模某些关系方面很差,例如阈值、对数 (2)。为了测试模型的线性,他建议对样条进行 ANOVA 测试:
我用谷歌搜索过样条曲线,但没有发现有多大用处(除了关于不使用太多结的一般警告)。在这个论坛中,似乎更喜欢样条建模、Kolassa、Harrell、gung。
我发现了一篇关于多项式的博客文章,这是关于预测多项式的过度拟合的恶魔。帖子以这些评论结束:
在某种程度上,这里给出的例子是作弊——多项式回归被认为是非常不鲁棒的。在实践中更好的是使用样条而不是多项式。
现在这提示我检查样条在示例中的表现:
library(rms)
p4 <- poly(1:100, degree=4)
true4 <- p4 %*% c(1,2,-6,9)
days <- 1:70
set.seed(7987)
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,4))
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_ols, newdata=nd), col="darkblue", lwd=3)
legend("top", fill=c("orange", "red","darkblue"),
legend=c("Poly", "Natural splines", "RCS - ols"))
给出以下图像:
总之,我没有发现太多可以说服我重新考虑样条曲线的东西,我错过了什么?
- FE Harrell,回归建模策略:应用于线性模型、逻辑回归和生存分析,精装第 1 版的精装版重印。2001. 施普林格,2010。
- FE Harrell、KL Lee 和 BG Pollock,“临床研究中的回归模型:确定预测因子和反应之间的关系”,JNCI J Natl Cancer Inst,第一卷。80,没有。15,第 1198-1202 页,1988 年 10 月。
更新
这些评论让我想知道在数据范围内会发生什么但曲线不舒服。在大多数情况下,我不会超出数据边界,如上面的示例所示。我不确定这是否符合预测...
无论如何,这是一个示例,我创建了一条无法转换为多项式的更复杂的线。由于大多数观察结果都位于数据的中心,因此我也尝试对其进行模拟:
library(rms)
cmplx_line <- 1:200/10
cmplx_line <- cmplx_line + 0.05*(cmplx_line - quantile(cmplx_line, .7))^2
cmplx_line <- cmplx_line - 0.06*(cmplx_line - quantile(cmplx_line, .3))^2
center <- (length(cmplx_line)/4*2):(length(cmplx_line)/4*3)
cmplx_line[center] <- cmplx_line[center] +
dnorm(6*(1:length(center)-length(center)/2)/length(center))*10
ds <- data.frame(cmplx_line, x=1:200)
days <- 1:140/2
set.seed(1234)
sample <- round(rnorm(600, mean=100, 60))
sample <- sample[sample <= max(ds$x) &
sample >= min(ds$x)]
sample_ds <- ds[sample, ]
sample_ds$noise4 <- sample_ds$cmplx_line + rnorm(nrow(sample_ds), sd=2)
reg.n4.4 <- lm(noise4 ~ poly(x, 6), data=sample_ds)
dd <- datadist(sample_ds)
options("datadist" = "dd")
reg.n4.4rcs_ols <- ols(noise4 ~ rcs(x, 7), data=sample_ds)
AIC(reg.n4.4)
plot(sample_ds$x, sample_ds$noise4, col="#AAAAAA")
lines(x=ds$x, y=ds$cmplx_line, lwd=3, col="black", lty=4)
nd <- data.frame(x=ds$x)
lines(ds$x, predict(reg.n4.4, newdata=ds), col="orange", lwd=3)
lines(ds$x, predict(reg.n4.4rcs_ols, newdata=ds), col="lightblue", lwd=3)
legend("bottomright", fill=c("black", "orange","lightblue"),
legend=c("True line", "Poly", "RCS - ols"), inset=.05)
这给出了以下情节: