时间序列预测,如何处理已知的大订单

22

我有许多数据集,其中包含已知的异常值(大额订单)。

data <- matrix(c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","13Q4","14Q1","14Q2","14Q3","14Q4","15Q1", 155782698, 159463653.4, 172741125.6, 204547180, 126049319.8, 138648461.5, 135678842.1, 242568446.1, 177019289.3, 200397120.6, 182516217.1, 306143365.6, 222890269.2, 239062450.2, 229124263.2, 370575384.7, 257757410.5, 256125841.6, 231879306.6, 419580274, 268211059, 276378232.1, 261739468.7, 429127062.8, 254776725.6, 329429882.8, 264012891.6, 496745973.9, 284484362.55),ncol=2,byrow=FALSE)

这个特定系列的前11个异常值为:

outliers <- matrix(c("14Q4","14Q2","12Q1","13Q1","14Q2","11Q1","11Q4","14Q2","13Q4","14Q4","13Q1",20193525.68, 18319234.7, 12896323.62, 12718744.01, 12353002.09, 11936190.13, 11356476.28, 11351192.31, 10101527.85, 9723641.25, 9643214.018),ncol=2,byrow=FALSE)

有哪些方法可以考虑这些异常值来预测时间序列?

我已经尝试过用下一个最大的异常值替换(对数据集进行10次运行,每次用下一个最大值替换异常值,直到第10个数据集中所有异常值都被替换)。 我还尝试了简单地删除异常值(因此再次运行数据集10次,每次删除一个异常值,直到在第10个数据集中删除了所有10个异常值)。

我只想指出,删除这些大订单并不会完全删除数据点,因为该季度还会发生其他交易。

我的代码通过多个预测模型(ARIMA加权外样本、ARIMA加权内样本、ARIMA加权、ARIMA、加性Holt-Winters加权和乘性Holt-Winters加权)测试数据,因此需要一些可以适用于这些多个模型的东西。

这里还有几组我使用过的数据集,但我还没有这些系列的异常值。

data <- matrix(c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","13Q4","14Q1","14Q2","14Q3", 26393.99306, 13820.5037, 23115.82432,    25894.41036,    14926.12574,    15855.8857, 21565.19002,    49373.89675,    27629.10141,    43248.9778, 34231.73851,    83379.26027,    54883.33752,    62863.47728,    47215.92508,    107819.9903,    53239.10602,    71853.5,    59912.7624, 168416.2995,    64565.6211, 94698.38748,    80229.9716, 169205.0023,    70485.55409,    133196.032, 78106.02227), ncol=2,byrow=FALSE)

data <- matrix(c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","13Q4","14Q1","14Q2","14Q3",3311.5124,    3459.15634, 2721.486863,    3286.51708, 3087.234059,    2873.810071,    2803.969394,    4336.4792,  4722.894582,    4382.349583,    3668.105825,    4410.45429, 4249.507839,    3861.148928,    3842.57616, 5223.671347,    5969.066896,    4814.551389,    3907.677816,    4944.283864,    4750.734617,    4440.221993,    3580.866991,    3942.253996,    3409.597269,    3615.729974,    3174.395507),ncol=2,byrow=FALSE)

如果这太复杂了,那就解释一下如何在R中使用某些命令检测到异常值后处理数据进行预测。例如平滑等等,以及我如何编写代码来处理它(而不使用检测异常值的命令)。


1
你如何确定哪些点是异常值?你提到了所有这些加权方法,你的意思是要通过一些已知的其他方法确定的固定数量来降低已知的异常值吗?或者你会考虑一个提供平滑水平并因此“忽略”异常值而不需要告诉它们是哪些的模型吗? - konvas
我正在尝试预测数据系列。第一个数据系列中有已知的异常值,这是我需要帮助的方法类型。另外两个数据系列只是为了说明异常值并不总是季节性的,但我目前无法访问此系列中已知的异常值。这回答了你的问题吗? - Summer-Jade Gleek'away
我不明白你根据什么称它们为异常值。正如konvas所提到的,它们往往是Q4和Q1,可能有原因。你可以尝试使用月度数据,因为详细数据可以显示出聚合无法识别的模式。 - Jaehyeon Kim
我不确定为什么您在ARIMA建模中使用原始比例尺。最大似然估计基本上假定正态分布。虽然ML估计器渐近正常,但数据记录太少。在计量经济学中,这种类型的变量被转化为变化率。至少,您需要“对数转换”记录<-一些异常值可能不再是问题。 - Jaehyeon Kim
  1. 由于记录数量很少,平滑技术可能更好。霍尔特-温特斯、指数平滑、移动平均等方法比ARIMA建模更好。不过,我强烈建议使用月度数据,相信您能够获得它们。
  2. 总之,目前不确定您的数据是否有很多异常值,但模型和数据可能需要修订。
- Jaehyeon Kim
显示剩余6条评论
3个回答

6

您的异常值似乎是季节性变化,最大订单出现在第四季度。 您提到的许多预测模型都包括季节性调整功能。 例如,最简单的模型可能具有对年份的线性依赖性,并对所有季节进行修正。 代码如下:

df <- data.frame(period= c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3",
                       "10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2",
                       "13Q3","13Q4","14Q1","14Q2","14Q3","14Q4","15Q1"),
                 order= c(155782698, 159463653.4, 172741125.6, 204547180, 126049319.8, 138648461.5,
                        135678842.1, 242568446.1, 177019289.3, 200397120.6, 182516217.1, 306143365.6,
                        222890269.2, 239062450.2, 229124263.2, 370575384.7, 257757410.5, 256125841.6,
                        231879306.6, 419580274, 268211059, 276378232.1, 261739468.7, 429127062.8, 254776725.6,
                        329429882.8, 264012891.6, 496745973.9, 42748656.73))

seasonal <- data.frame(year=as.numeric(substr(df$period, 1,2)), qtr=substr(df$period, 3,4), data=df$order)
ord_model <- lm(data ~ year + qtr, data=seasonal)
seasonal <- cbind(seasonal, fitted=ord_model$fitted)
library(reshape2)
library(ggplot2)
plot_fit <- melt(seasonal,id.vars=c("year", "qtr"), variable.name = "Source", value.name="Order" )
ggplot(plot_fit, aes(x=year, y = Order, colour = qtr, shape=Source)) + geom_point(size=3)

以下是图表中显示的结果: 带季节性调整的线性拟合

具有季节性调整但年份非线性相关的模型可能会给出更好的拟合结果。


1
Q1 2015的数据点明显偏差了10倍。顺便说一下,分析得很好。 - mcheema

4

您已经说过你尝试了不同的Arima模型,但正如WaltS所提到的那样,您的时间序列似乎没有大的异常值,而是有一个季节性分量,这可以很好地被forecast包中的auto.arima()捕捉到:

myTs <- ts(as.numeric(data[,2]), start=c(2008, 1), frequency=4) 
myArima <- auto.arima(myTs, lambda=0)
myForecast <- forecast(myArima)
plot(myForecast)

输入图像描述

auto.arima()中的lambda=0参数会强制对数据进行转换(或者您可以取对数),方法是使用boxcox函数来考虑季节性分量的增大振幅。


感谢您的回答。这只是我使用的众多数据集之一。其他数据集有更大的异常值,而且没有季节性成分。然而,我使用的代码需要适用于所有具有异常值、季节性或非季节性的系列。 - Summer-Jade Gleek'away
1
啊,我明白了。也许你可以提供几个捕捉这种特定性质的系列,那么就更容易给出一个合格的解决方案了 :) - J.R.
我还没有其他数据集的异常值,但是现在我可以给你这些序列本身。 - Summer-Jade Gleek'away
1
我现在添加了几个数据集。 - Summer-Jade Gleek'away
当然不是,我完全没有打算给人留下那种印象。 - J.R.

4
您试图使用的方法来清理您的数据中的离群值不够强大,无法识别它们。我应该补充说,在R中有一个名为tsoutliers的免费离群值包,但它不会执行我即将展示给您的操作。
您拥有一个有趣的时间序列。随着上升趋势的减弱,趋势会随着时间变化而变化。如果引入两个时间趋势变量,第一个从1开始,另一个从周期14开始并向前,您将捕获这种变化。至于季节性,您可以使用虚拟变量捕获高四分之四。该模型是简洁的,因为其他3个季度与平均水平没有区别,也不需要AR12、季节性差异或3个季节性虚拟变量。您还可以使用两个虚拟变量捕获最后两个观察值作为异常值的影响。请忽略单词“趋势”上方的49,因为那只是被建模系列的名称。
(下面是一张图片)

4
结果看起来不错,但实际上你没有提供你使用的解决方案/算法... - patapouf_ai
2
请问您能否提供您所使用的R代码?我无法完全理解这个过程。 - Summer-Jade Gleek'away
我正在寻找的方法需要适应R代码。 - Summer-Jade Gleek'away
对于第三个数据集,17是一个异常值。从第7个时期(第三季度)开始,它显示出系统性低于其他季度,并被识别为“季节性脉冲”或“季节性变化”。 - Tom Reilly
第三数据集模型。一个AR1、水平偏移、离群值、水平变化和季节性脉冲。 Y(T) = 3253.6 +[X1(T)][(+1044.0)] : 偏移级别8 +[X2(T)][(-651.29)] : 季节性脉冲7 +[X3(T)][(+1021.8)] : 脉冲17 +[(1-.627B1)]-1[A(T)] - Tom Reilly
显示剩余3条评论

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