使用受限三次样条曲线的新数据的预测值

时间:2016-12-21 20:38:13

标签: r lm rms

我有一些数据,我使用受限制的三次样条建模。我使用rcs包中的rms转换函数生成线性模型的转换变量。这是一个使用5节的例子。

library('rms')

my_df <- data.frame(
    y = -4 * -100:100 + -1.5 * (-100:100)**2 + 3 * (-100:100)**3 + rnorm(201, 0, 1e5),
    x = -100:100
)

mod <- lm(y ~ rcs(x, 5), data = my_df)

在我拟合数据后,我想找到y值的特定域的预测x值。这就是我现在正在做的事情:

new_data <- data.frame(x = -3:3)

predict(mod, newdata = new_data)

但是,这会生成一条警告消息:

Warning message:
In rcspline.eval(x, nk = nknots, inclx = TRUE, pc = pc, fractied = fractied) :
    5 knots requested with 7 unique values of x.  knots set to 5 interior values.

这意味着什么,以及发生了什么?我预计结点位置应该已经在mod中定义,所以我不明白为什么它似乎试图找到我给它的七个x值的新结。我可以通过在x中提供更多new_data值来避免警告消息,而忽略那些我不需要的值,但我担心predict实际上在做什么。

2 个答案:

答案 0 :(得分:1)

根据Hadley对此question的评论,您不应期望lmrcs合作。快速演示为什么会出现问题:

mod <- lm(y ~ rcs(x, 5), data = my_df)

new_data <- data.frame(x = -3:3)
new_data2 <- data.frame(x = -300:300/100)

plot(new_data2$x, predict(mod, newdata = new_data2), type='l')
lines(new_data$x,predict(mod, newdata = new_data), col='red')

Graph produced as code output

预测因x值的数量而异,即使是相同的范围,因此结合这些功能绝对不是一个好主意。

答案 1 :(得分:0)

我相信predict函数将在公式中查找并用newdata中的变量替换找到的变量。诀窍是,rcs函数可根据提供的数据(数据的分布)确定打结的位置。因此,如果new_data中的数据与my_df中的数据具有不同的分布,则结点将位于不同的位置,它将改变曲线。无论如何,修复节点的位置可以解决问题。

要固定结位置,不能使用rcs函数,而要使用rcspline.eval函数,该函数将结位置作为参数。您可以使用相同的函数来计算“应该”结的位置。请参见下面的代码。

Knots <- rcspline.eval(my_df$x, knots.only = TRUE) # returns only locations of knots
# see ??Hmisc::rcspline.eval for details of how it determines knot locations
mod2 <- lm(y ~ rcspline.eval(x, knots = Knots), data = my_df) # fit model
predict(mod2, newdata = new_data) # predict based on mod2 and new data

由于mod2公式包含结点位置,因此曲线应为相同形状。