Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting seasonality without two full periods of data

Tags:

r

time-series

I have the following dataset (df) with 20 months:

price
2735.869
2857.105
2725.971
2734.809
2761.314
2828.224
2830.284
2758.149
2774.943
2782.801
2861.970
2878.688
3049.229
3029.340
3099.041
3071.151
3075.576
3146.372
3005.671
3149.381

There should be seasonality, and I want to estimate this and remove it. I attempted this using the below code:

df <- ts(df$price, frequency = 12, start = c(2016,8))
decompose_df <- decompose( , "additive")
adjust_df<- df- decompose_df $seasonal
plot(adjust_df)

But as I only have 20 months and not two full periods of data, I get the below error:

Error in decompose(df, "additive") : 
time series has no or less than 2 periods

Is there a way I can test and remove this seasonality? Even though I only have 20 periods when I need 24.

like image 215
PMc Avatar asked Jul 13 '18 16:07

PMc


People also ask

How do you find seasonality without plots?

Use the Kruskal function by using the array and series as parameters. The function returns the p-value. If the p-value is less than 0.05 (5 % significance level) the hypothesis that the series is not seasonal is rejected. Similarly, for Quarterly, arrange the array from 0–2, repeated until the end of the series.

How do you evaluate seasonality?

We can use the ACF to determine if seasonality is present in a time series. For example, Yt = γ · St + ϵt. The larger the amplitude of seasonal fluctuations, the more pronounced the oscillations are in the ACF.

How do you test for seasonality in a time series?

Seasonality testseasonal_decompose() tests whether a time series has a seasonality or not by removing the trend and identify the seasonality by calculating the autocorrelation(acf). The output includes the number of period, type of model(additive/multiplicative) and acf of the period.


1 Answers

It's not possible using the usual methods of decomposition because they estimate seasonality using at least as many degrees of freedom as there are seasonal periods. As @useR has pointed out, you need at least two observations per seasonal period to be able to distinguish seasonality from noise.

However, if you are willing to assume that the seasonality is relatively smooth, then you can estimate it using fewer degrees of freedom. For example, you can approximate the seasonal pattern using Fourier terms with a few parameters.

df <- ts(c(
2735.869,2857.105,2725.971,2734.809,2761.314,2828.224,2830.284,2758.149,
2774.943,2782.801,2861.970,2878.688,3049.229,3029.340,3099.041,3071.151,
3075.576,3146.372,3005.671,3149.381), start=c(2016,8), frequency=12)

library(forecast)
library(ggplot2)
decompose_df <- tslm(df ~ trend + fourier(df, 2))
trend <- coef(decompose_df)[1] + coef(decompose_df)['trend']*seq_along(df)
components <- cbind(
  data = df,
  trend = trend,  
  season = df - trend - residuals(decompose_df),
  remainder = residuals(decompose_df)
)
autoplot(components, facet=TRUE)

enter image description here

You can adjust the order of the Fourier terms as required. I've used 2 here. For monthly data, the maximum you can use is 6, but that will give a model with 13 degrees of freedom which is way too many with only 20 observations. If you don't know about Fourier terms for seasonality, see https://otexts.org/fpp2/useful-predictors.html#fourier-series.

Now we can remove the seasonal component to get the seasonally adjusted data.

adjust_df <- df - components[,'season']
autoplot(df, series="Data") + autolayer(adjust_df, series="Seasonally adjusted")

enter image description here

like image 171
Rob Hyndman Avatar answered Oct 27 '22 05:10

Rob Hyndman