使用fable包在Validation_set上计算准确率指标报错求助
无法让accuracy()函数仅指向验证集validation_set:当该函数传入完整数据集data_tsibble时代码运行正常,但指定validation_set时,会收到“参数必须可转换为非负整数”的错误提示。
Messaggi di avvertimento:
1: 2 errors (1 unique) encountered
[2] l'argomento dev'essere coercibile in un intero non-negativo2: 2 errors (1 unique) encountered
[2] l'argomento dev'essere coercibile in un intero non-negativo3: 2 errors (1 unique) encountered
[2] l'argomento dev'essere coercibile in un intero non-negativo4: 2 errors (1 unique) encountered
[2] l'argomento dev'essere coercibile in un intero non-negativo5: 2 errors (1 unique) encountered
[2] l'argomento dev'essere coercibile in un intero non-negativo
(注:错误提示为意大利语,翻译为“参数必须可转换为非负整数”)
# 清空工作区所有变量 rm(list = ls()) # 加载所需包 library(tidyverse) library(fpp3) library(readxl) library(distributional) # 读取数据集 data <- read_excel("D:/TEST.xlsx") # 转换为tsibble格式(时间序列数据框) data_tsibble <- data |> mutate(Mesi = yearmonth(Mesi)) |> as_tsibble(index = Mesi) dput(data_tsibble) # 划分训练集与验证集 train_set <- data_tsibble |> filter_index(~ "12/01/2023") validation_set <- data_tsibble |> filter_index("01/01/2024" ~ .) # 拟合多个模型 fit_models <- train_set |> model(Ets = ETS(Intermediato), Arima = ARIMA(Intermediato, stepwise=FALSE, approximation=FALSE), tslm1 = TSLM(Intermediato ~ trend() + season()), tslm2 = TSLM(Intermediato ~ trend() + I(trend()^2) + season()), tslm3 = TSLM(Intermediato ~ trend() + I(trend()^2) + season())) glance(fit_models) |> arrange(AICc) |> select(.model:BIC) # 生成预测 fc_models <- fit_models |> forecast(h=nrow(validation_set)) # 传入完整数据集时accuracy函数运行正常 fc_models |> accuracy( data = validation_set, measures = list( crps = CRPS, rmse = RMSE, mase = MASE, ss_crps = skill_score(CRPS), ss_rmse = skill_score(RMSE) ), n_quantiles = 100 ) |> group_by(.model) %>% summarise( ss_crps = mean(ss_crps) * 100, ss_rmse = mean(ss_rmse) * 100, mase = mean(mase) ) # 传入完整数据集时accuracy函数运行正常 fc_models |> accuracy(validation_set, list(rmse=RMSE, mae=MAE, mape=MAPE, mase=MASE, rmsse=RMSSE, acf1=ACF1, crps=CRPS, skill_crps=skill_score(CRPS), skill_rmse=skill_score(RMSE)))
问题根源在于MASE和RMSSE指标需要依赖训练集数据计算基准误差,仅传入验证集时,函数无法获取训练集信息,导致参数转换错误。提供两种解决方式:
方法一:指定训练集参数
在accuracy()中通过train参数传入训练集,让函数能正常计算MASE/RMSSE:
fc_models |> accuracy( data = validation_set, train = train_set, measures = list( crps = CRPS, rmse = RMSE, mase = MASE, ss_crps = skill_score(CRPS), ss_rmse = skill_score(RMSE) ), n_quantiles = 100 ) |> group_by(.model) %>% summarise( ss_crps = mean(ss_crps) * 100, ss_rmse = mean(ss_rmse) * 100, mase = mean(mase) )
方法二:移除依赖训练集的指标
如果不需要MASE/RMSSE,可从指标列表中删除这两项,直接用验证集计算剩余指标:
fc_models |> accuracy( data = validation_set, measures = list( crps = CRPS, rmse = RMSE, ss_crps = skill_score(CRPS), ss_rmse = skill_score(RMSE) ), n_quantiles = 100 ) |> group_by(.model) %>% summarise( ss_crps = mean(ss_crps) * 100, ss_rmse = mean(ss_rmse) * 100 )
额外提示:代码中tslm2和tslm3的公式完全一致,属于冗余模型,可删除其中一个以优化代码。
内容的提问来源于stack exchange,提问作者Mark_

