#r #purrr
Вопрос:
У меня есть модель, которая в качестве предиктора имеет предыдущий прогноз. например target ~ lag(target prediction)
Используя purrr::накопите, я могу написать пользовательскую функцию для прогнозирования. Пример некоторых глупых данных и глупой модели, которая иллюстрирует:
### A model that uses a lag prediction as a predictor using purrr::accumulate() ###
my_diamonds <- diamonds %>%
group_by(cut) %>%
mutate(cumprice = cumsum(price)) %>% # cumulative within groups
mutate(lag_cumprice = lag(cumprice)) %>%
mutate(InitialValue = min(cumprice)) %>%
filter(!is.na(lag_cumprice)) %>%
select(cut, cumprice, lag_cumprice, x, InitialValue)
silly_model <- glm(formula = cumprice ~ x lag_cumprice, family = 'poisson', data = my_diamonds)
Эта модель использует предыдущий прогноз в качестве входных данных для следующего прогноза. Я могу написать пользовательскую функцию для изменения прогноза:
# when predicting won't have lag_cumprice, instead the result of the previous pediction should be an input to the model:
accPrice <- function(mod, acc, cur) {
db=cur_data_all() # grouped data segment
x = db$x[cur] # cur is the current row in the data, use it to get 'this' iterations value of x
total_exponent <- mod$coefficients['(Intercept)']
(mod$coefficients['x'] * x)
(mod$coefficients['lag_cumprice'] * acc) # acc is the accumulated prediction for cumprice
}
# now predict
my_diamonds <- my_diamonds %>%
mutate(predicted = accumulate(.x = row_number()[-1], .init = InitialValue %>% unique, .f = accPrice, mod = silly_model))
Пока все хорошо. В этом примере я использовал предыдущий прогноз acc
в качестве входных данных.
Но я создал вариационную модель, которая теперь использует две запаздывающие переменные в качестве предикторов:
### now a model with lag on two variables not just one ###
my_diamonds2 <- diamonds %>%
group_by(cut) %>%
mutate(cumprice = cumsum(price)) %>% # cumulative within groups
mutate(lag_cumprice = lag(cumprice)) %>%
mutate(InitialValue = min(cumprice)) %>%
mutate(rn = row_number()) %>%
mutate(cumrn = cumsum(rn)) %>%
mutate(lag_cumrn = lag(cumrn)) %>%
filter(!is.na(lag_cumprice)) %>%
select(cut, cumprice, lag_cumprice, lag_cumrn, x, InitialValue)
silly_model2 <- glm(formula = cumprice ~ x lag_cumprice lag_cumrn, family = 'poisson', data = my_diamonds2)
### Stuck after here ###
Как я могу изменить функцию accPrice() выше, чтобы накапливать 2 переменные, как lag_cumprice, так и lag_cumrn, а не просто lag_cumprice, как раньше?
Комментарии:
1. есть
accumulate2
2. @akrun правильно, я начал существовать, когда увидел это, но, возможно, я неправильно понял документацию… насколько я мог судить, accumulate2() не накапливается на 2 var, вместо этого он просто позволяет передать дополнительный var в функцию. Если только я не неправильно его понял? Я нахожу эту конкретную проблему r более сложной, чем другие, с которыми я боролся в прошлом
3.
for
Вариант с циклом был бы более прямым4. Bsaed на посту, вы не используете
lag_cumprice' or
lag_cumrn в функции?5. вы можете добавить новый параметр в функцию
accPrice2 <- function(mod, acc, acc2, cur)
Ответ №1:
Мы могли бы добавить аргумент в функцию. Затем извлеките соответствующий коэффициент из модели и умножьте на него
accPrice2 <- function(mod, acc, acc2, cur) {
db=cur_data_all() # grouped data segment
x = db$x[cur] # cur is the current row in the data, use it to get 'this' iterations value of x
total_exponent <- mod$coefficients['(Intercept)']
(mod$coefficients['x'] * x)
(mod$coefficients['lag_cumprice'] * acc)
(mod$coefficients['lag_cumrn'] * acc2)
}
my_diamonds2 %>%
mutate(predicted = accumulate(.x = row_number()[-1],
.init = InitialValue %>%
unique, .f = accPrice2, mod = silly_model))
Комментарии:
1. Потрясающе! Он действительно работает! Большое спасибо. Один свободный конец с ним, при вызове, в последней строке, с которой я использую начальное значение
.init
. Когда он запускается, предположительно, он использует одно и то же начальное значение как для acc, так и для acc2? Любая идея, как сказать «используйте .init для начального значения lag_cumprice и, например,. init2 для начального значения lag_cumrn»2. @DougFir Я тоже думал о вашей структуре. Создается
InitialValue'
изmin
«cumprice», что будет соответствовать cumrn3. Для этого примера это было бы то же самое, но для cumrn, поэтому, когда я создавал второй пример набора данных, я должен был добавить что-то вроде
mutate(InitialValueRN = min(cumrn)) %>%
4. @DougFir не
min(cumrn)
будет всегда 15. Я имел в виду, что я бы сделал, например.
if(cur==1) acc2 = db$myvar[curr] else acc2