tidyverts模型识别预测变量变换的时机及查询方法
Tidyverts框架预测问题答疑
问题1:ARIMA模型是否识别并反变换目标变量的box_cox变换?
如何判断tidyverts模型(如dat %>% model(arima=ARIMA(y)) %>% forecast(h=12)这类ARIMA模型)会识别并对经过变换的目标变量y进行反变换?已知fable::ETS()支持fabletools::box_cox(y, lambda)的识别与反变换,fable::STL()支持sqrt(y)的识别与反变换,但使用ARIMA(box_cox(val,0.5))建模后,预测结果出现负值——理论上反变换(近似平方)不应产生负值,因此疑惑ARIMA是否识别该变换。
问题2:如何查看模型支持的所有变换?
更通用地,如何快速查看各模型支持哪些变换及对应的反变换?是否有相关文档?或是否有简单函数可查询ARIMA等模型的可用变换?已通过pluck('garima', 1, 'transformation')看到ARIMA识别了box_cox变换,但希望能像查看specials那样查询所有可用变换。
演示代码及注释
# 模拟数据 set.seed(10) len=36 aa <- exp(-0.1*(1:len) + rnorm(len,sd=0.1)) ab <- exp(-0.2*(1:len) + rnorm(len,sd=0.1)) tibble(aa=aa,ab=ab) %>% mutate(ym=make_yearmonth(year=2021,month=1)+0:(len-1)) %>% pivot_longer(cols=c('aa','ab'),names_to='key', values_to='val') %>% as_tsibble(index=ym, key=key) -> dat # 拟合模型并预测 dat %>% model( garima=ARIMA(box_cox(val,0.5)), gets=ETS(box_cox(val,0.5)), ) -> fit fit %>% forecast(h=36) -> fcs fcs %>% autoplot(level=NULL) fcs %>% filter(.mean<0) %>% distinct(key, .model) # 难道ARIMA没有进行反变换? # 结果: # A tibble: 1 × 2 # key .model # <chr> <chr> # 1 aa garima fit %>% pluck('garima', 1, 'transformation') #[[1]] #Transformation: box_cox(val, 0.5) #Backtransformation: inv_box_cox(val, 0.5) ## 看起来ARIMA识别了box_cox变换? ## 但它还支持哪些其他变换? ## 我有哪些可选的变换? fit %>% pluck('garima', 1, 'model', 'specials') #<environment: 0x00000203ba8c0058> #attr("required_specials") #[1] "pdq" "PDQ" #attr("xreg_specials") #[1] "trend" "season" "fourier" ## 这个能显示所有可用的specials,即使我没用到 ## 是否有类似方法查看所有可用但未使用的变换?
问题1解答
- 从
pluck('garima', 1, 'transformation')的输出可以直接确认:ARIMA模型已经识别了box_cox(val,0.5)变换,并且配置了对应的反变换函数inv_box_cox(val,0.5)。 - 预测结果出现负值的原因是非线性变换的均值计算特性:ARIMA在变换后的变量空间生成预测分布,由于变换(此处为平方根)是非线性的,变换后预测均值的反变换不等于原始空间的预测均值。模型会计算原始空间的预测均值(考虑变换的非线性偏差),但当变换后的预测分布存在极端左偏时,可能会出现原始空间均值为负的情况,这并非未执行反变换。
- 验证方法:可以手动对比变换空间和原始空间的预测值:
# 模拟变换空间的预测值并手动反变换 fit %>% forecast(h=36, simulate=TRUE, times=1000) %>% mutate(trans_val = box_cox(val, 0.5)) %>% group_by(key, .model, ym) %>% summarise( trans_mean = mean(trans_val), manual_backtrans = inv_box_cox(trans_mean, 0.5), fable_mean = first(.mean) )
对比manual_backtrans和fable_mean,可以看到模型确实执行了反变换,只是非线性变换导致均值出现负值。
问题2解答
目前没有专门的函数直接列出模型支持的所有变换,但可以通过以下方式查询:
- 查看模型官方文档:比如执行
?ARIMA,在文档的「Details」或「Transformations」章节会明确说明支持的变换类型。tidyverts主流模型(ARIMA、ETS、STL等)普遍支持box_cox()、log()、sqrt()、logit()等常见变换,且均能自动识别并应用反变换。 - 查看模型specials定义:通过
getS3method("specials", "ARIMA")可以查看ARIMA模型的所有specials配置,其中包含变换相关的处理逻辑;也可以直接查看模型构造函数的源代码(如fable::ARIMA),找到变换处理的部分。 - 参考fabletools的变换函数:所有
fabletools包提供的变换函数(如box_cox()、log()、inv_box_cox()等)都能被tidyverts模型识别,此外通过fabletools::new_transformation()自定义的符合规范的变换,也能被模型自动处理。
内容的提问来源于stack exchange,提问作者lowndrul
相关产品推荐
相关产品推荐

