I have daily sales data for a department store for the past 850 days. I have indicators on the major holidays and the days leading up to the major holidays. The number of days before the holidays that are included was chosen by AIC. The issue I'm having is that there are outliers throughout the data that I'm not sure how to handle. Or, at least that's what I think is happening since I don't seem to get accurate forecasts. I'm using a CV to calculate the MAPE of forecasts two weeks out, using the first 450 days as the initial training set and the rest to see how well the model forecasts the data.

I've used tso() from the tsoutliers package and tsoutliers from the forecast package to find outliers. They both give different results.

tsoutliers(data$Sales)

$index
[1] 230 270 271 328 635

$replacements
[1] 2222.160 2088.573 2231.577 1812.380 2138.655

train = 454
trainingdata = data$Sales[1:train]
trainingdata = ts(trainingdata,frequency = 7)
tso(trainingdata,types = c("AO", "LS", "TC"))

Series: trainingdata 
ARIMA(2,1,1)(2,0,0)[7]                    

Coefficients:
     ar1     ar2      ma1    sar1    sar2      AO52      TC68       TC80      AO86
  0.2872  0.1331  -0.9717  0.3567  0.4607  885.2061  890.3690  -863.4296  836.8638
s.e.  0.0508  0.0480   0.0107  0.0436  0.0429  169.2521  163.4243   166.0282  169.8535
     AO111     AO121      TC229     AO259      TC270     AO328     AO416
  754.1791  691.0849  1236.8523  711.3954  1790.0292  764.9712  920.1783
s.e.  169.2042  167.7273   163.1458  167.9835   163.9663  170.0103  168.9235

sigma^2 estimated as 44080:  log likelihood=-3064.92
AIC=6152.24   AICc=6153.65   BIC=6222.21

Outliers:
type ind  time coefhat  tstat
1    AO  52  8:03   885.2  5.230
2    TC  68 10:05   890.4  5.448
3    TC  80 12:03  -863.4 -5.200
4    AO  86 13:02   836.9  4.927
5    AO 111 16:06   754.2  4.457
6    AO 121 18:02   691.1  4.120
7    TC 229 33:05  1236.9  7.581
8    AO 259 37:07   711.4  4.235
9    TC 270 39:04  1790.0 10.917
10   AO 328 47:06   765.0  4.500
11   AO 416 60:03   920.2  5.447

Running BoxCox on the data it recommends a transform of the data

lambda <- BoxCox.lambda(data$Sales)
trainingdata = BoxCox(trainingdata,lambda)
tso(trainingdata,types = c("AO", "LS", "TC"))
Series: trainingdata 
ARIMA(3,1,1)(2,0,0)[7]                    

Coefficients:
     ar1     ar2      ar3      ma1    sar1    sar2      LS3    AO52     AO53    TC68
  0.3918  0.0993  -0.0587  -0.9856  0.3632  0.4144  13.5805  5.7218  -7.7957  6.3960
s.e.  0.0383  0.0418   0.0416   0.0142  0.0361  0.0341   1.3201  1.2980   1.3041  1.2763
      AO80   AO121   TC229   TC270   AO416     AO445   TC634   AO780
  -23.3707  5.5352  5.8088  7.0446  7.9304  -23.6372  5.5475  6.7194
s.e.    1.2376  1.2307  1.2594  1.2640  1.2476    1.2393  1.2598  1.2353

sigma^2 estimated as 2.332:  log likelihood=-1482.63
AIC=3003.26   AICc=3004.23   BIC=3092.34

Outliers:
type ind   time coefhat   tstat
1    LS   3   1:03  13.581  10.287
2    AO  52   8:03   5.722   4.408
3    AO  53   8:04  -7.796  -5.978
4    TC  68  10:05   6.396   5.012
5    AO  80  12:03 -23.371 -18.883
6    AO 121  18:02   5.535   4.498
7    TC 229  33:05   5.809   4.612
8    TC 270  39:04   7.045   5.573
9    AO 416  60:03   7.930   6.356
10   AO 445  64:04 -23.637 -19.073
11   TC 634  91:04   5.547   4.404
12   AO 780 112:03   6.719   5.439

Some of these outliers are already taken care of since they're the holidays. I'm not sure how to handle the rest of the outliers when fitting the model and in the CV.

What is the best way to go about taking care of the outliers? I can reset the values of the training data where it's predicted as an outliers to the recommended value if it's not a holiday for fitting the model and then still calculate the MAPE off of the original data. However, there's a LS at index 3 so I'm not sure that would make sense for that.

  • Post your dataset. Specify the country and the beginning date. – Tom Reilly Apr 5 '16 at 16:16

http://www.autobox.com/cms/index.php/afs-university/intro-to-forecasting/doc_download/53-capabilities-presentation starting at slide 40 presents a fully worked out example that you might want to follow. You are on the right path using indicators before and after the holidays. I don't necessarily believe that a simple AIC will identify the parsimonious set of indicators. We have found that particular days of the month and particular weeks of the month can often be very important in clarifying structure. Additionally there can be weekly effects , daily effects , monthly effects which if untreated will "blur your vision" so to speak . While daily effects are very important they can change over time so one has to incorporate/test for these. If you would like to post your data (coded or otherwise) I will present an analysis that you might find relevant. Specify the nature of the data, starting date and the country of origin and post it as a column oriented excel file. It is always interesting to get different analyses from the list members as they can then be compared. If you have possible explanatory variables you can also include them and their importance can be assessed.

Outliers need to be detected if they exist and incorporated into a useful model. Care should be taken to allow for outliers (including pulses) to be incorporated into the forecast as more realistic confidence limits can be generated.

  • Thanks for the response. I actually can't share the data and need to do the analysis on my own. I'm finishing up my MS in statistics right now and this is my final project. I have never taken a time series class though so there's a bit of a learning curve for me here. Do you know of a better method than AIC for choosing how many days before/after holidays to estimate? Or do you know of any good resources for learning about handling outliers in the dataset? – Kristofersen Mar 21 '16 at 0:32

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.