使用forecast包如何对时间序列进行去日志化处理?

4

你好,我使用预测包来进行时间序列预测。我想知道如何在最终的预测图中取消对数转换。使用预测包时,我不知道如何取消我的序列的对数转换。以下是一个示例:

library(forecast)
data <- AirPassengers
data <- log(data) #with this AirPassengers data not nessesary to LOG but with my private data it is...because of some high picks...
ARIMA <- arima(data, order = c(1, 0, 1), list(order = c(12,0, 12), period = 1)) #Just a fake ARIMA in this case... 
plot(forecast(ARIMA, h=24)) #but my question is how to get a forecast plot according to the none log AirPassenger data

输入图像描述

因此,该图像已记录。我希望使用非对数数据拥有相同的ARIMA模型。


指数函数是对数函数的反函数。 - ndoogan
@ndoogan 这是真的,但并不实用。 - Matthew Lundberg
3个回答

11

没有必要使用@ndoogan提出的hack。 forecast.Arima内置了撤消转换的功能。以下代码将完成所需操作:

fc <- forecast(ARIMA, h=24, lambda=0)
更好的做法是将转换嵌入到模型本身中:
ARIMA <- Arima(data, order=c(1,0,1), list(order=c(1,0,1),period=12)), lambda=0)
fc <- forecast(ARIMA, h=24)

请注意,您需要使用forecast包中的Arima函数来完成此操作,而不是stats包中的arima函数。

@Hemmo正确指出,此反变换不会给出预测分布的均值,因此不是最优MSE预测。但是,它将给出预测分布的中位数,因此将给出最优MAE预测。

最后,@Swiss12000使用的虚假模型没有多少意义,因为季节部分的频率为1,因此与非季节部分混淆了。我认为您可能是指上面代码中使用的模型。


我不确定这里是否有一个好的答案。ARIMA预测返回原始比例尺下的预测结果 - 因此返回的是以log(Airlinepassengers)为基础的预测结果,因为这是传递给ARIMA的内容。挑战在于如何将log(Airlinepassengers)的预测结果转换回Airlinepassengers。我本以为只需要使用exp(logAirlinepassengers)就可以了,但是正如你们中的一些人指出的那样,我认为这并不正确。现在我面临着这个问题 - 距离这篇文章发表已经过去了2年。如果有人有额外的见解,我会非常感激。 - Windstorm1981
1
在预测包的v7版本中会有一个选项来返回平均值 -- 现在已经放在Github上了。 - Rob Hyndman

8
@ndoogan的答案存在问题,因为对数不是线性变换。这意味着E[exp(y)] != exp(E[y]). Jensen's inequality实际上给出了E[exp(y)] >= exp(E[y])。下面是一个简单的演示:
set.seed(1)
x<-rnorm(1000)
mean(exp(x))
[1] 1.685356
exp(mean(x))
[1] 0.9884194

这是一个涉及预测的案例:
# Simulate AR(1) process
set.seed(1)
y<-10+arima.sim(model=list(ar=0.9),n=100)

# Fit on logarithmic scale
fit<-arima(log(y),c(1,0,0))

#Simulate one step ahead
set.seed(123)
y_101_log <- fit$coef[2]*(1-fit$coef[1]) + 
             fit$coef[1]*log(y[100]) + rnorm(n=1000,sd=sqrt(fit$sigma2))

y_101<-exp(y_101_log) #transform to natural scale

exp(mean(y_101_log)) # This is exp(E(log(y_101)))
[1] 5.86717          # Same as exp(predict(fit,n.ahead=1)$pred) 
                     # differs bit because simulation

mean(y_101)          # This is E(exp(log(y_101)))=E(y_101)
[1] 5.904633

# 95% Prediction intervals:

#Naive way:
pred<-predict(fit,n.ahead=1)
c(exp(pred$pred-1.96*pred$se),exp(pred$pred+1.96*pred$se))
pred$pred pred$pred 
 4.762880  7.268523 

# Correct ones:
quantile(y_101,probs=c(0.025,0.975))
    2.5%    97.5% 
4.772363 7.329826 

这也提供了一个通用的解决方案:
  1. 拟合您的模型
  2. 从该模型中模拟多个样本(例如上面的一步预测)
  3. 对于每个模拟样本,进行逆变换以获得原始尺度上的值
  4. 从这些模拟样本中,可以计算期望值作为普通均值,或者如果您需要置信区间,则计算经验分位数。

3

这种方法有些取巧,但它似乎可以实现你的目标。基于你拟合的模型 ARIMA

fc<-forecast(ARIMA,h=24)
fc$mean<-exp(fc$mean)
fc$upper<-exp(fc$upper)
fc$lower<-exp(fc$lower)
fc$x<-exp(fc$x)

现在将其绘制出来。
plot(fc)

enter image description here


非常感谢您。正是我想要的。;) - S12000
2
请注意,log(E(y))不等于E(log(y)),即如果您仅使用上述转换,则您的预测会略带偏差。 - Jouni Helske
@hemmo 在 Stack Overflow 的精神下,你能否为 OP 提供一个新的更好的答案?或者,修改我发布的答案。另外,你能否提供一个例子说明 log(exp(y)) != exp(log(y)) 是什么意思?这是精度问题吗?还是有更深层次的原因? - ndoogan
1
@ndoogan,我已添加了相关答案。 - Jouni Helske

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接