Different authors have developed a multiplicity of test for seasonality of a given time series. In Ollech and Webel (forthcoming) and Webel and Ollech (forthcoming) we analysed many of these tests and showed a) which tests are the most reliable ones and b) how to combine a small set of tests, to reduce the misclassification rates of the single tests.
We’ll simulated simple non-seasonal and a seasonal series.
set.seed(5)
x1 = 1:96/20 + ts(rnorm(96, 100, 1), start=c(2015,1), frequency=12)
x2 = 1:96/20 + ts(rnorm(96, 100, 1) + ts(sin((2*pi*rep(1:12, 8))/12), frequency=12), start=c(2015,1), frequency=12)
ts.plot(x1,x2, col=c("darkblue", "darkred"), main="Some simple seasonal series")
legend("topleft", c("Non seasonal series", "Seasonal series"), col=c("darkblue", "darkred"), lty=1)
Then, we can test, whether these series are seasonal or not, using the WO-test, i.e. the overall seasonality test developed in Webel and Ollech (2019).
library(seastests)
print("Testing the non-seasonal series")
#> [1] "Testing the non-seasonal series"
summary(wo(x1))
#> Test used: WO
#>
#> Test statistic: 0
#> P-value: 1 1 0.179945
#>
#> The WO - test does not identify seasonality
print("")
#> [1] ""
print("Testing the seasonal series")
#> [1] "Testing the seasonal series"
summary(wo(x2))
#> Test used: WO
#>
#> Test statistic: 1
#> P-value: 1 0.005145348 0.001151393
#>
#> The WO - test identifies seasonality
The WO-test gives out a TRUE if the series is seasonal and FALSE otherwise. The p-values indicate the p-values of the underlying test, i.e. the QS-test, the QS-R test and the KW-R-test.
If we are only interested in knowing, whether a series is seasonal or not, e.g. for further use in our analysis, the function isSeasonal() can be called.
print("Test using the non-seasonal series")
#> [1] "Test using the non-seasonal series"
isSeasonal(x1)
#> [1] FALSE
print("Test using the seasonal series")
#> [1] "Test using the seasonal series"
isSeasonal(x2)
#> [1] TRUE
This can then for example be used in the forecast packages auto.arima() function. For the non-seasonal series:
if (!require("forecast")) install.packages("forecast")
#> Loading required package: forecast
#> Warning: package 'forecast' was built under R version 3.5.1
mod1 <- auto.arima(x1, seasonal=isSeasonal(x1))
summary(mod1)
#> Series: x1
#> ARIMA(0,1,1)
#>
#> Coefficients:
#> ma1
#> -0.7597
#> s.e. 0.0656
#>
#> sigma^2 estimated as 1.085: log likelihood=-138.6
#> AIC=281.2 AICc=281.33 BIC=286.31
#>
#> Training set error measures:
#> ME RMSE MAE MPE MAPE MASE
#> Training set 0.2288794 1.030769 0.8455547 0.2146113 0.824723 0.6940177
#> ACF1
#> Training set -0.05882107
plot(forecast(mod1, h=12))
and for the seasonal series:
mod2 <- auto.arima(x2, seasonal=isSeasonal(x2))
summary(mod2)
#> Series: x2
#> ARIMA(0,1,1)(1,0,0)[12]
#>
#> Coefficients:
#> ma1 sar1
#> -0.8642 0.3531
#> s.e. 0.0502 0.1052
#>
#> sigma^2 estimated as 1.585: log likelihood=-157.09
#> AIC=320.17 AICc=320.43 BIC=327.83
#>
#> Training set error measures:
#> ME RMSE MAE MPE MAPE MASE
#> Training set 0.2134882 1.239136 0.9547015 0.1950671 0.9304067 0.777594
#> ACF1
#> Training set 0.03000515
plot(forecast(mod2, h=12))
Ollech, Daniel and Webel, Karsten (forthcoming). A random forest-based approach to identifying the most informative seasonality tests. Bundesbank Discussion Paper Webel, Karsten and Ollech, Daniel (forthcoming). An overall seasonality test. Bundesbank Discussion Paper