首页 > 解决方案 > 使用“模型”函数调用模型/变量进行预测时如何使用字符值?

问题描述

我的目标是创建一个函数,您可以在其中输入要预测的变量,然后在多种类型的模型(即 Naive、ETS、Mean)上使用交叉验证,然后使用“拉”函数,我将拉出模型RMSE 最低,那么我会用最好的模型预测 1 步。

但是,我在倒数第二行遇到问题,在预测时使用字符值“best.model”作为模型的输入。(错误在您自己运行的代码下方)。

这是更有意义的代码:

library(fpp3)
tsibble <- prices

function.fc <- function (variable) {

## cross validation models
cv.fit <- tsibble %>%
  select(year, !!sym(variable)) %>%
  stretch_tsibble(.init = 180, .step = 1) %>%
  filter(.id != max(.id)) %>%
  model(
    MEAN(!!sym(variable)),
    NAIVE(!!sym(variable))
  ) 

## cv forecasts
cv.fc <- cv.fit %>%
  forecast(h = 1)

## cv accuracy
cv.accuracy <- cv.fc %>%
  accuracy(tsibble)

## pulls out the name of the best model
best.model <- cv.accuracy %>%
  select(.model, .type, RMSE) %>%
  arrange(RMSE) %>%
  filter(row_number(RMSE) == 1) %>%
  pull(.model)

## pulls out 1 step forecast 
fc <- model(.data = tsibble, noquote(best.model)) %>%
  forecast(h = 1)


return(fc)

}


function.fc("copper")

Error: Model definition(s) incorrectly created: noquote(best.model) Check that specified model(s) are model definitions. Run `rlang::last_error()` to see where the error occurred

如您所见,我已尝试使用“取消引用”功能,但这仍然不起作用。有人对使用什么有任何建议吗?我一直在努力寻找与我的问题有关的其他帖子。

标签: rtime-seriescharacterforecastingtsibble

解决方案


这是一个采用稍微不同方法的解决方案,首先定义一个命名的模型列表以供选择,然后使用best.model从列表中进行选择。这通常比陷入非标准评估更可取。另请注意,我习惯于{{“管道”未引用的参数。您会注意到我还更改了一些对象名称。这是因为您通常应该避免.使用对象名称,以避免与S3R 中的面向对象编程系统混淆。

library(fpp3)

my_forecast <- function(data, variable) {
  
  # Define a list of models with sensible names
  models <- list(
    mean = fable::MEAN,
    naive = fable::NAIVE
  )
  
  ## cross validation models
  cv_fit <- data %>%
    select(year, {{ variable }}) %>%
    stretch_tsibble(.init = 180, .step = 1) %>%
    filter(.id != max(.id)) %>%
    model(
      mean = models$mean({{ variable }}),
      naive = models$naive({{ variable }})
    ) 
  
  ## cv forecasts
  cv_fc <- cv_fit %>%
    forecast(h = 1)
  
  ## cv accuracy
  cv_accuracy <- cv_fc %>%
    accuracy(data)
  
  ## pulls out the name of the best model
  best_model <- cv_accuracy %>%
    select(.model, .type, RMSE) %>%
    arrange(RMSE) %>%
    filter(row_number() == 1) %>%
    pull(.model)
  
  ## pulls out 1 step forecast 
  fc <- data %>% 
    model("{best_model}" := models[[best_model]]({{ variable }})) %>%
    forecast(h = 1)
  
  fc
  
}

my_forecast(prices, copper)
#> # A fable: 1 x 4 [1Y]
#> # Key:     .model [1]
#>   .model  year       copper .mean
#>   <chr>  <dbl>       <dist> <dbl>
#> 1 naive   1998 N(2.6, 0.69)  2.59

reprex 包于 2021-05-11 创建 (v2.0.0 )


推荐阅读