【问题标题】:Why does `ns` and `rcs` generate different predictions in R?为什么`ns`和`rcs`在R中产生不同的预测?
【发布时间】:2020-09-20 13:55:19
【问题描述】:

我的理解是rcs()(来自rms 包)使用截断幂基础来表示自然(受限)三次样条。或者,我可以使用使用 B 样条基础的 ns()(来自 splines 包)。

但是,我注意到训练拟合和测试预测可能非常不同(尤其是在推断 x 时)。我正在尝试了解rcs()ns() 之间的区别以及是否可以互换使用这些功能。

伪造的非线性数据。

library(tidyverse)
library(splines)
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)

ns 拟合一个模型,用rcs 为另一个模型拟合相同的结。

ns_mod <- lm(y ~ ns(x, knots=c(-2, 0, 2)), data=df)

ddist <- datadist(df)
options("datadist" = "ddist")

trunc_power_mod <- ols(y ~ rcs(x, knots=c(-2, 0, 2)), data=df)

检查他们的配合 (MSE)。

mean(ns_mod$residuals^2)
mean(trunc_power_mod$residuals^2)

df$pred_ns <- ns_mod$fitted.values
df$pred_trunc_power <- trunc_power_mod$fitted.values

df_melt <- df %>% 
  gather(key="model", value="predictions", -x, -y)

ggplot(df_melt, aes(x=x, y=y)) +
  geom_point(alpha=0.1) +
  geom_line(aes(x=x, y=predictions, group=model, linetype=model))

生成一个测试数据集并绘制两个模型之间的预测。

newdata <- data.frame(x=seq(-10, 10, 0.1))

pred_ns_new <- predict(ns_mod, newdata=newdata)
pred_trunc_new <- predict(trunc_power_mod, newdata=newdata)

newdata$pred_ns_new <- pred_ns_new
newdata$pred_trunc_new <- pred_trunc_new

newdata_melted <- newdata %>% 
  gather(key="model", value="predictions", -x)

ggplot(newdata_melted, aes(x=x, y=predictions, group=model, linetype=model)) +
  geom_line()

【问题讨论】:

    标签: r linear-regression spline rms


    【解决方案1】:

    有一个相当简单的解释:knots 不是rcs() 的参数。它希望使用参数parms 指定结。另一个问题是knots 参数ns() 没有指定“边界结”,默认为range(x)。因此,要获得相同的预测,您需要

    trunc_power_mod <- ols(y ~ rcs(x, parms=c(min(x), -2, 0, 2, max(x))), data=df)
    

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多