Прогнозируемые значения для новых данных с использованием ограниченных кубических сплайнов

У меня есть данные, которые я моделирую с помощью ограниченных кубических сплайнов. Я использую функцию преобразования 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 на самом деле делает.


r lm rms
person user102162    schedule 21.12.2016    source источник


Ответы (2)


Согласно комментарию Хэдли по этому вопросу, вы не должны ожидать, что 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, даже для одного и того же диапазона, поэтому определенно не рекомендуется комбинировать эти функции.

person Miff    schedule 06.07.2017
comment
Это где-нибудь задокументировано? - person user102162; 11.07.2017

Я считаю, что функция 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 содержит местоположения узлов, кривая должна иметь такую ​​же форму.

person Crt Ahlin    schedule 28.06.2018