问:在 tidyverts/fable 预测框架中,有很多目标时间序列需要预测,如何为每个序列提供不同的目标变换参数?
特别是,我想对每个时间序列进行 Box-Cox 变换,但对每个序列使用“不同”的 lambda,例如,根据每个序列的 Guerrero 方法估计的 lambda。我如何在框架内做到这一点? 以下是我的几次尝试。我收到错误。
如果在框架内没有办法做到这一点,我可以使用一个好的技巧吗?理想情况下,它仍然可以处理分层时间序列。
下面,我提出了一个 hack。我不确定它是否仍然适用于分层时间序列。我应该检查一下。无论如何,我认为大多数人都有更好的方法来处理事情。
library(fpp3)
# construct data in transformed space directly
z1 <- arima.sim(n=104,list(ar=0.9))
z2 <- arima.sim(n=104,list(ma=0.5))
# inverse to get data in the untransformed space
y1 <- fabletools::inv_box_cox(z1, lambda=0.25)
y2 <- fabletools::inv_box_cox(z2, lambda=0.75)
# create tsibble for time series modeling
tibble(idx=1:104, y1=y1, y2=y2) %>%
pivot_longer(cols=c(y1,y2), names_to='series', values_to='value') %>%
tsibble(index=idx, key=series) ->
dat
# estimate optimal box-cox transform lambda for each series using guerrero
# method
dat %>%
fabletools::features(value, features='guerrero') ->
lambdas
# # A tibble: 2 × 2
# series lambda_guerrero
# <chr> <dbl>
# 1 y1 0.0991
# 2 y2 0.751
# set up the optimal lambdas as exogenous regressors?
dat %>% inner_join(lambdas, by=join_by(series)) -> dat.xrg
dat.xrg %>%
model(arima=ARIMA(box_cox(value,lambda=lambda))) ->
fit
# Error in `.g()`:
# ! Response variable transformation has incompatible lengths, all arguments must be the length of the data 104 or 1.
# Run `rlang::last_trace()` to see where the error occurred.
# Try defining lambda outside, and of the length desired?
lambdas %>% pull(lambda_guerrero) %>% rep(each=104) -> lambda
length(lambda)
# [1] 208
dat %>%
model(arima=ARIMA(box_cox(value, lambda=lambda))) ->
fit
# Error in `.g()`:
# ! Response variable transformation has incompatible lengths, all arguments must be the length of the data 208 or 1.
# Run `rlang::last_trace()` to see where the error occurred.
# just going with a tidy-hack
# is this the best one can do?
dat %>%
nest(.by=series) %>%
inner_join(lambdas, by = "series") %>%
mutate(
fit=map2(
data,
lambda_guerrero,
\(.dat,.lambda)
model(
.dat,
arima=ARIMA(box_cox(value, lambda=.lambda))
)
)
) %>%
unnest(cols=fit) %>%
select(series, arima) %>%
as_mable(key='series', model='arima') ->
fit
# looks right
fit
# # A mable: 2 x 2
# # Key: series [2]
# series arima
# <chr> <model>
# 1 y1 <ARIMA(1,0,2)>
# 2 y2 <ARIMA(0,0,1)>
# still get access to all the nice fable tools
fit %>% accuracy()
# # A tibble: 2 × 11
# series .model .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
# <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 y1 arima Training 0.311 3.97 1.91 -450. 512. 0.956 0.961 -0.123
# 2 y2 arima Training 0.269 1.16 0.918 -884. 1003. 0.879 0.840 0.00342
# can make a nice plot
fit %>%
augment() %>%
ggplot(aes(x=idx, y=value)) +
geom_point() +
geom_line(aes(y=.fitted),color='blue') +
facet_grid(rows=vars(series))
# The column name for the lambda parameter in dat.xrg is lambda_guerrero, not lambda
dat.xrg %>%
model(arima=ARIMA(box_cox(value,lambda=lambda_guerrero)))
但请注意,检测到的响应变量现在是
box_cox(value,lambda=lambda_guerrero)
而不是
value
,因此输出不会自动反向转换。这是因为 value
和 lambda_guerrero
具有相同的长度,因此响应变量检测算法不会将 value
识别为预期响应。您可以使用 resp()
:
明确说明什么变量是响应变量
dat.xrg %>%
model(arima=ARIMA(box_cox(resp(value), lambda=lambda_guerrero))) ->
fit
这种在数据集中提供与响应长度相同的
lambda_guerrero
的方法允许转换参数随时间变化。因此,这还要求您在预测时指定
lambda_guerrero
的未来值。如果您希望它不随时间变化,您可能想使用单个值 lambda
。如果在转换响应时使用长度为 1 的输入/变量,它将被缓存并重新用于预测。要在转换中使用 length-1 变量,您可以使用
first(lambda_guerrero)
:dat.xrg %>%
model(arima=ARIMA(box_cox(value, lambda=first(lambda_guerrero)))) ->
fit
或者也许是最简单和最简洁的,您可以直接在转换中计算
guerrero()
:
library(fpp3)
# construct data in transformed space directly
z1 <- arima.sim(n=104,list(ar=0.9))
z2 <- arima.sim(n=104,list(ma=0.5))
# inverse to get data in the untransformed space
y1 <- fabletools::inv_box_cox(z1, lambda=0.25)
y2 <- fabletools::inv_box_cox(z2, lambda=0.75)
# create tsibble for time series modeling
tibble(idx=1:104, y1=y1, y2=y2) %>%
pivot_longer(cols=c(y1,y2), names_to='series', values_to='value') %>%
tsibble(index=idx, key=series) ->
dat
dat |>
model(arima=ARIMA(box_cox(value, lambda=guerrero(value))))
#> # A mable: 2 x 2
#> # Key: series [2]
#> series arima
#> <chr> <model>
#> 1 y1 <ARIMA(1,0,0)>
#> 2 y2 <ARIMA(0,0,1)>
创建于 2024-05-14,使用