使用受限三次样条的新数据的预测值
Predicted values for new data using restricted cubic splines
我有一些数据正在使用受限三次样条建模。我正在使用 rms
包中的 rcs
转换函数来生成线性模型的转换变量。这是一个使用 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)
拟合数据后,我想找到 x
值的特定域的预测 y
值。这是我现在正在做的事情:
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
值找到新的节点。我可以通过在 new_data
中提供更多 x
值并忽略我不需要的值来避免警告消息,但我担心 predict
实际在做什么。
根据 Hadley 对此 question 的评论,您不应期望 lm
与 rcs
一起工作。快速演示为什么会出现问题:
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')
预测会根据 x 值的数量而变化,即使对于相同的范围也是如此,因此组合这些函数绝对不是一个好主意。
我相信 predict
函数会在公式中查找并将它在其中找到的变量替换为 newdata
中的变量。诀窍是,rcs
函数根据提供的数据(它的分布)确定节点的位置。因此,如果 new_data
中的数据与 my_df
中的数据分布不同,节点将位于不同的位置,这将改变曲线。无论如何,固定结的位置可以解决问题。
要固定节点位置,您不能使用 rcs
函数,而是使用 rcspline.eval
函数,该函数将节点位置作为参数。您可以使用相同的函数来计算节点 "should" 的位置。请参阅下面的代码。
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
公式包含节点位置,曲线应该是相同的形状。
我有一些数据正在使用受限三次样条建模。我正在使用 rms
包中的 rcs
转换函数来生成线性模型的转换变量。这是一个使用 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)
拟合数据后,我想找到 x
值的特定域的预测 y
值。这是我现在正在做的事情:
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
值找到新的节点。我可以通过在 new_data
中提供更多 x
值并忽略我不需要的值来避免警告消息,但我担心 predict
实际在做什么。
根据 Hadley 对此 question 的评论,您不应期望 lm
与 rcs
一起工作。快速演示为什么会出现问题:
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')
预测会根据 x 值的数量而变化,即使对于相同的范围也是如此,因此组合这些函数绝对不是一个好主意。
我相信 predict
函数会在公式中查找并将它在其中找到的变量替换为 newdata
中的变量。诀窍是,rcs
函数根据提供的数据(它的分布)确定节点的位置。因此,如果 new_data
中的数据与 my_df
中的数据分布不同,节点将位于不同的位置,这将改变曲线。无论如何,固定结的位置可以解决问题。
要固定节点位置,您不能使用 rcs
函数,而是使用 rcspline.eval
函数,该函数将节点位置作为参数。您可以使用相同的函数来计算节点 "should" 的位置。请参阅下面的代码。
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
公式包含节点位置,曲线应该是相同的形状。