Unemployment Trends in the Netherlands: Forecasting Through 1983-2023 Monthly Data Analysis

Insights into Dutch Unemployment: Analyzing Monthly Data from 1983 to 2023

January 05, 2024
Unemployment trend in Nedherlands: Forcasting with 1983-2023 Monthly Data Analysis

This post focuses primarily on forecasting the monthly unemployment rate in the Netherlands beyond the sample period. Predicting the unemployment rate is pivotal for the economic and financial planning of a country and presents a significant challenge for policymakers. Traditional stochastic time series models, including seasonal adjustments, ARIMA, and ETS models, are employed for this purpose.

Pre-Analysis

You should use this chunk for renew memory.

if(!is.null(dev.list())) dev.off()
## null device 
##           1
cat("\014")
rm(list=ls(all=TRUE))

Installing require packages

Below, you need to install the packages.

# Install require packages:
# install.packages("readxl")
# install.packages("forecast")
# install.packages("seastests")
# install.packages("xts")
# install.packages("zoo")
# install.packages("stats")
# install.packages("graphics")
# install.packages("utils")
# install.packages("RJDemetra")
# install.packages("fpp2")

Calling libraries that we use

library(readxl)
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(seastests)
library(xts)
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(zoo)
library(stats)
library(graphics)
library(utils)
library(RJDemetra)
library(fpp2)
## ── Attaching packages ────────────────────────────────────────────── fpp2 2.5 ──
## ✔ ggplot2   3.4.4     ✔ expsmooth 2.3  
## ✔ fma       2.5
## 

Export data from excel file

From this IMF data source, you can get data which you would like to analysis. In this experiment, I am searching Netherlands unseasonal monthly unemployment rate from 1983-2023. I am going to look the labour market situation of the Netherlands for this period. Firstly, I extract data from IMF web page:

https://data.imf.org/?sk=4c514d48-b6ba-49ed-8ab9-52b0c1a0179b&sid=1390030341854

I also add raw data into my github page that you can easily take.

Secondly, I use read_excel function for import data from excel to R:

# Read the Excel file into R
data <- read_excel("unemp.xlsx", sheet = "Sheet1")

# View the imported data
print(data)
## # A tibble: 492 × 2
##    date                 unem
##    <dttm>              <dbl>
##  1 1983-01-01 00:00:00  10  
##  2 1983-02-01 00:00:00  10.2
##  3 1983-03-01 00:00:00  10.3
##  4 1983-04-01 00:00:00   9.7
##  5 1983-05-01 00:00:00   9.4
##  6 1983-06-01 00:00:00   9.7
##  7 1983-07-01 00:00:00   8.8
##  8 1983-08-01 00:00:00   8.8
##  9 1983-09-01 00:00:00   9.4
## 10 1983-10-01 00:00:00   9.5
## # ℹ 482 more rows

Let’s convert data time series format and plot this data

unemp <- data$unem
unemp <- ts(unemp,
            start = c(1983,1),
            frequency = 12)
plot(unemp)

The unemployment rate appears to demonstrate pronounced seasonality and a discernible downward trend over time. Additionally, notable fluctuations, marked by significant increases and decreases, are evident in various periods. Specifically, during the mid-1990s and 2010s, the unemployment rate experienced upward trajectories. Conversely, at the onset of the 2000s, there were discernible downturns in the unemployment rate. Notably, periods of stability seem to be lacking within the observed data. Let’s we start looking for seasonal effects with statistical tools.

Dummy variable approach for seasonality

Initially, I am employing a dummy variable approach to identify seasonality. This method draws from the teachings of the Basic Econometrics book by Gujarati, which I extensively studied during my undergraduate education at the University. The process involves generating seasonal dummies followed by the application of a linear regression model. To illustrate, I am presenting a simplified example focusing solely on a dummy variable representing January, assigned a value of 1 for each year.

Let \(D_t\) be the dummy variable representing a particular month \(t\), such that:

\[ D_t = \begin{cases} 1 & \text{if month \( t \) satisfies a certain condition (e.g., January)} \\ 0 & \text{otherwise} \end{cases} \]

Where the dummy variable, is defined is defined as 1 if a specific condition (such as being January) is met for month t, and 0 otherwise. You can customize the condition based on your specific context and requirements.

To do this, I use a for loop:

# Initialize an empty matrix to store dummy variables
dummy <- matrix(0, nrow = 492, ncol = 11)

# Create dummy variables using a for loop
for (i in 1:11) {
  dummy[, i] <- ifelse(seq_along(dummy[, i]) %% 11 == (i - 1), 1, 0)
}

# Convert the matrix to a data frame
dummy <- as.data.frame(dummy)

# Rename columns
colnames(dummy) <- paste0("d", 1:11)

# You can print the dummy variables:
# print(dummy)

Remove seasonality with Dummy variables

The next step is that I am removing seasonality with a regression model. So, first I convert my seasonal dummies to time-series format and regress unemployment rate this dummies as follows:

\[ unemp_{t}=X\beta+\varepsilon_{t} \] where \(X\) data matrix includes dummy variables. One more important thing is I have to remove constant since I do not want to be caught dummy variable trap.

# Convert dummy dataframe to a time series object
dummy_ts <- ts(dummy)

# Fit a linear regression model and remove constant term via -1
model <- lm(unemp ~ dummy_ts-1)

# Print the summary of the model
summary(model)
## 
## Call:
## lm(formula = unemp ~ dummy_ts - 1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.5600 -1.2544 -0.0318  1.2150  4.0400 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## dummy_tsd1    6.1477     0.2556   24.05   <2e-16 ***
## dummy_tsd2    6.1956     0.2528   24.51   <2e-16 ***
## dummy_tsd3    6.2311     0.2528   24.65   <2e-16 ***
## dummy_tsd4    6.2600     0.2528   24.77   <2e-16 ***
## dummy_tsd5    6.2422     0.2528   24.69   <2e-16 ***
## dummy_tsd6    6.1911     0.2528   24.49   <2e-16 ***
## dummy_tsd7    6.1511     0.2528   24.33   <2e-16 ***
## dummy_tsd8    6.0933     0.2528   24.11   <2e-16 ***
## dummy_tsd9    6.0644     0.2528   23.99   <2e-16 ***
## dummy_tsd10   6.1068     0.2556   23.89   <2e-16 ***
## dummy_tsd11   6.1318     0.2556   23.99   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.696 on 481 degrees of freedom
## Multiple R-squared:  0.9311, Adjusted R-squared:  0.9296 
## F-statistic: 591.3 on 11 and 481 DF,  p-value: < 2.2e-16

Overall, the regression model using dummy variables appears to be highly significant and explains a substantial portion of the variability in the unemployment rate. The coefficients of the dummy variables provide insights into the seasonality patterns observed in the data.

The next step is that I am going to look seasonal patterns of the data.

Seasonal Graphs: ggseasonplot

ggseasonplot(unemp)

What I am looking in here, on this seasonal plot what it is doing that each year gets its own line so I look at one year at a time across each month. It looks like the change from January to March the unemployment rate is clearly growing. In contrast, from March to June, it seems that there is usually drop. I also look another format of graph for detecting seasonality.

ggsubseriesplot(unemp)

What this plot is doing look for the averages. The average change in each months is different than each other.So, the mean of the data and the different months is very different depending on what month I am looking. However, these plots say something about seasonality, I need to do statistical perspective such as some tests that detect seasonality.

Seasonality Tests: Webel-Ollech (2019)

After looking graphically, while there are very pronounced seasonal effects, I observed a somewhat less distinct but still suspicious impression of seasonality. So I am looking for statistical evidences. Therefore, I use Webel-Ollech (2019) study to compiled tests related to seasonality, named after the initials of their own names. To do this:

sa_test <- combined_test(unemp, freq = 12)
summary(sa_test)
## Test used:  WO 
##  
## Test statistic:  1 
## P-value:  0 0 0 
##  
## The WO - test identifies seasonality

Test identifies seasonality.

In this case, it is necessary to perform deseasonalization. Since a series containing seasonal effects will yield a sinusoidal graph, it is not possible to detect the effects here.

Remove seasonality with tramoseasts

You can get more information with chunk as follows:

?tramoseats
## starting httpd help server ... done

To perform automatic deseasonalization, level determination within seasonality, outlier detection, calendar effects, and the ARIMA method altogether, the argument “RSAfull” should be entered. If you prefer to specify these yourself, you can consult the help menu within tramoseats.

unemp_tramo <- tramoseats(unemp, spec = "RSAfull")

# You can see four different components of the series via this function:
# unemp_tramo$decomposition$components

Let’s looking plot of the components:

plot(unemp_tramo$decomposition$components)

Graphs are

y_cmp means input data sa_cmp means seasonally adjusted data t_cmp means trend component s_cmp means seasonal component i_cmp means irregular component.

I am looking for seasonal adjusted part of the data. To do this,

unemp_sa <- unemp_tramo$decomposition$components[,2]
plot(unemp_sa)

Here is the the graph of the seasonally adjusted part of the series. I test again is there any seasonality remains:

summary(combined_test(unemp_sa, freq = 12))
## Test used:  WO 
##  
## Test statistic:  0 
## P-value:  1 1 0.9999503 
##  
## The WO - test does not identify  seasonality

The results show that there is not any seasonality of the new data. Last but not least, I am looking for forecasting seasonal adjusted unemployment rate for Netherlands.

fit_unemp_sa <- auto.arima(unemp_sa,d <- 1,D <- 0, stepwise = FALSE, approximation = FALSE, trace = TRUE)
## 
##  ARIMA(0,1,0)                               : -912.8945
##  ARIMA(0,1,0)            with drift         : -927.3722
##  ARIMA(0,1,0)(0,0,1)[12]                    : -923.2109
##  ARIMA(0,1,0)(0,0,1)[12] with drift         : -933.904
##  ARIMA(0,1,0)(0,0,2)[12]                    : -921.1943
##  ARIMA(0,1,0)(0,0,2)[12] with drift         : -932.2798
##  ARIMA(0,1,0)(1,0,0)[12]                    : -922.8133
##  ARIMA(0,1,0)(1,0,0)[12] with drift         : -933.1795
##  ARIMA(0,1,0)(1,0,1)[12]                    : -921.1905
##  ARIMA(0,1,0)(1,0,1)[12] with drift         : -932.0485
##  ARIMA(0,1,0)(1,0,2)[12]                    : Inf
##  ARIMA(0,1,0)(1,0,2)[12] with drift         : Inf
##  ARIMA(0,1,0)(2,0,0)[12]                    : -921.5177
##  ARIMA(0,1,0)(2,0,0)[12] with drift         : -933.0739
##  ARIMA(0,1,0)(2,0,1)[12]                    : -933.7669
##  ARIMA(0,1,0)(2,0,1)[12] with drift         : Inf
##  ARIMA(0,1,0)(2,0,2)[12]                    : Inf
##  ARIMA(0,1,0)(2,0,2)[12] with drift         : Inf
##  ARIMA(0,1,1)                               : -949.0465
##  ARIMA(0,1,1)            with drift         : -959.2135
##  ARIMA(0,1,1)(0,0,1)[12]                    : -949.0999
##  ARIMA(0,1,1)(0,0,1)[12] with drift         : -958.149
##  ARIMA(0,1,1)(0,0,2)[12]                    : -948.9792
##  ARIMA(0,1,1)(0,0,2)[12] with drift         : -960.6989
##  ARIMA(0,1,1)(1,0,0)[12]                    : -948.8332
##  ARIMA(0,1,1)(1,0,0)[12] with drift         : -957.9774
##  ARIMA(0,1,1)(1,0,1)[12]                    : Inf
##  ARIMA(0,1,1)(1,0,1)[12] with drift         : Inf
##  ARIMA(0,1,1)(1,0,2)[12]                    : -960.3917
##  ARIMA(0,1,1)(1,0,2)[12] with drift         : Inf
##  ARIMA(0,1,1)(2,0,0)[12]                    : -948.8518
##  ARIMA(0,1,1)(2,0,0)[12] with drift         : -959.5901
##  ARIMA(0,1,1)(2,0,1)[12]                    : -962.0203
##  ARIMA(0,1,1)(2,0,1)[12] with drift         : Inf
##  ARIMA(0,1,1)(2,0,2)[12]                    : -965.125
##  ARIMA(0,1,1)(2,0,2)[12] with drift         : Inf
##  ARIMA(0,1,2)                               : -1006.09
##  ARIMA(0,1,2)            with drift         : -1013.547
##  ARIMA(0,1,2)(0,0,1)[12]                    : -1004.197
##  ARIMA(0,1,2)(0,0,1)[12] with drift         : -1012.092
##  ARIMA(0,1,2)(0,0,2)[12]                    : -1006.998
##  ARIMA(0,1,2)(0,0,2)[12] with drift         : -1019.098
##  ARIMA(0,1,2)(1,0,0)[12]                    : -1004.17
##  ARIMA(0,1,2)(1,0,0)[12] with drift         : -1011.952
##  ARIMA(0,1,2)(1,0,1)[12]                    : -1018.493
##  ARIMA(0,1,2)(1,0,1)[12] with drift         : Inf
##  ARIMA(0,1,2)(1,0,2)[12]                    : -1020.055
##  ARIMA(0,1,2)(1,0,2)[12] with drift         : Inf
##  ARIMA(0,1,2)(2,0,0)[12]                    : -1005.407
##  ARIMA(0,1,2)(2,0,0)[12] with drift         : -1014.897
##  ARIMA(0,1,2)(2,0,1)[12]                    : -1020.562
##  ARIMA(0,1,2)(2,0,1)[12] with drift         : Inf
##  ARIMA(0,1,3)                               : -1033.262
##  ARIMA(0,1,3)            with drift         : -1039.241
##  ARIMA(0,1,3)(0,0,1)[12]                    : -1032.041
##  ARIMA(0,1,3)(0,0,1)[12] with drift         : -1038.803
##  ARIMA(0,1,3)(0,0,2)[12]                    : -1042.774
##  ARIMA(0,1,3)(0,0,2)[12] with drift         : -1056.739
##  ARIMA(0,1,3)(1,0,0)[12]                    : -1031.802
##  ARIMA(0,1,3)(1,0,0)[12] with drift         : -1038.275
##  ARIMA(0,1,3)(1,0,1)[12]                    : -1052.803
##  ARIMA(0,1,3)(1,0,1)[12] with drift         : Inf
##  ARIMA(0,1,3)(2,0,0)[12]                    : -1038.367
##  ARIMA(0,1,3)(2,0,0)[12] with drift         : -1047.09
##  ARIMA(0,1,4)                               : -1066.246
##  ARIMA(0,1,4)            with drift         : -1070.769
##  ARIMA(0,1,4)(0,0,1)[12]                    : -1067.604
##  ARIMA(0,1,4)(0,0,1)[12] with drift         : -1073.631
##  ARIMA(0,1,4)(1,0,0)[12]                    : -1066.476
##  ARIMA(0,1,4)(1,0,0)[12] with drift         : -1071.843
##  ARIMA(0,1,5)                               : -1080.169
##  ARIMA(0,1,5)            with drift         : -1083.458
##  ARIMA(1,1,0)                               : -980.8902
##  ARIMA(1,1,0)            with drift         : -986.758
##  ARIMA(1,1,0)(0,0,1)[12]                    : -980.9204
##  ARIMA(1,1,0)(0,0,1)[12] with drift         : -987.315
##  ARIMA(1,1,0)(0,0,2)[12]                    : -997.3862
##  ARIMA(1,1,0)(0,0,2)[12] with drift         : -1013.343
##  ARIMA(1,1,0)(1,0,0)[12]                    : -980.2145
##  ARIMA(1,1,0)(1,0,0)[12] with drift         : -986.3686
##  ARIMA(1,1,0)(1,0,1)[12]                    : Inf
##  ARIMA(1,1,0)(1,0,1)[12] with drift         : Inf
##  ARIMA(1,1,0)(1,0,2)[12]                    : -1008.341
##  ARIMA(1,1,0)(1,0,2)[12] with drift         : Inf
##  ARIMA(1,1,0)(2,0,0)[12]                    : -986.5868
##  ARIMA(1,1,0)(2,0,0)[12] with drift         : -993.9983
##  ARIMA(1,1,0)(2,0,1)[12]                    : -1008.298
##  ARIMA(1,1,0)(2,0,1)[12] with drift         : Inf
##  ARIMA(1,1,0)(2,0,2)[12]                    : Inf
##  ARIMA(1,1,0)(2,0,2)[12] with drift         : Inf
##  ARIMA(1,1,1)                               : -1116.2
##  ARIMA(1,1,1)            with drift         : -1114.9
##  ARIMA(1,1,1)(0,0,1)[12]                    : -1159.791
##  ARIMA(1,1,1)(0,0,1)[12] with drift         : -1158.658
##  ARIMA(1,1,1)(0,0,2)[12]                    : Inf
##  ARIMA(1,1,1)(0,0,2)[12] with drift         : Inf
##  ARIMA(1,1,1)(1,0,0)[12]                    : -1136.201
##  ARIMA(1,1,1)(1,0,0)[12] with drift         : -1134.844
##  ARIMA(1,1,1)(1,0,1)[12]                    : Inf
##  ARIMA(1,1,1)(1,0,1)[12] with drift         : Inf
##  ARIMA(1,1,1)(1,0,2)[12]                    : Inf
##  ARIMA(1,1,1)(1,0,2)[12] with drift         : Inf
##  ARIMA(1,1,1)(2,0,0)[12]                    : -1160.623
##  ARIMA(1,1,1)(2,0,0)[12] with drift         : -1159.377
##  ARIMA(1,1,1)(2,0,1)[12]                    : Inf
##  ARIMA(1,1,1)(2,0,1)[12] with drift         : Inf
##  ARIMA(1,1,2)                               : -1144.25
##  ARIMA(1,1,2)            with drift         : -1143.06
##  ARIMA(1,1,2)(0,0,1)[12]                    : -1190.859
##  ARIMA(1,1,2)(0,0,1)[12] with drift         : -1189.832
##  ARIMA(1,1,2)(0,0,2)[12]                    : Inf
##  ARIMA(1,1,2)(0,0,2)[12] with drift         : Inf
##  ARIMA(1,1,2)(1,0,0)[12]                    : -1165.718
##  ARIMA(1,1,2)(1,0,0)[12] with drift         : -1164.438
##  ARIMA(1,1,2)(1,0,1)[12]                    : Inf
##  ARIMA(1,1,2)(1,0,1)[12] with drift         : Inf
##  ARIMA(1,1,2)(2,0,0)[12]                    : -1190.558
##  ARIMA(1,1,2)(2,0,0)[12] with drift         : -1189.417
##  ARIMA(1,1,3)                               : -1142.265
##  ARIMA(1,1,3)            with drift         : -1141.075
##  ARIMA(1,1,3)(0,0,1)[12]                    : -1188.816
##  ARIMA(1,1,3)(0,0,1)[12] with drift         : -1187.779
##  ARIMA(1,1,3)(1,0,0)[12]                    : -1163.71
##  ARIMA(1,1,3)(1,0,0)[12] with drift         : -1162.429
##  ARIMA(1,1,4)                               : -1141.891
##  ARIMA(1,1,4)            with drift         : -1140.739
##  ARIMA(2,1,0)                               : -1078.269
##  ARIMA(2,1,0)            with drift         : -1079.423
##  ARIMA(2,1,0)(0,0,1)[12]                    : -1108.561
##  ARIMA(2,1,0)(0,0,1)[12] with drift         : -1109.915
##  ARIMA(2,1,0)(0,0,2)[12]                    : Inf
##  ARIMA(2,1,0)(0,0,2)[12] with drift         : Inf
##  ARIMA(2,1,0)(1,0,0)[12]                    : -1091.705
##  ARIMA(2,1,0)(1,0,0)[12] with drift         : -1092.806
##  ARIMA(2,1,0)(1,0,1)[12]                    : Inf
##  ARIMA(2,1,0)(1,0,1)[12] with drift         : Inf
##  ARIMA(2,1,0)(1,0,2)[12]                    : Inf
##  ARIMA(2,1,0)(1,0,2)[12] with drift         : Inf
##  ARIMA(2,1,0)(2,0,0)[12]                    : -1112.459
##  ARIMA(2,1,0)(2,0,0)[12] with drift         : -1113.719
##  ARIMA(2,1,0)(2,0,1)[12]                    : Inf
##  ARIMA(2,1,0)(2,0,1)[12] with drift         : Inf
##  ARIMA(2,1,1)                               : -1141.708
##  ARIMA(2,1,1)            with drift         : -1140.451
##  ARIMA(2,1,1)(0,0,1)[12]                    : -1188.912
##  ARIMA(2,1,1)(0,0,1)[12] with drift         : -1187.838
##  ARIMA(2,1,1)(0,0,2)[12]                    : Inf
##  ARIMA(2,1,1)(0,0,2)[12] with drift         : Inf
##  ARIMA(2,1,1)(1,0,0)[12]                    : -1163.348
##  ARIMA(2,1,1)(1,0,0)[12] with drift         : -1162.014
##  ARIMA(2,1,1)(1,0,1)[12]                    : Inf
##  ARIMA(2,1,1)(1,0,1)[12] with drift         : Inf
##  ARIMA(2,1,1)(2,0,0)[12]                    : -1188.217
##  ARIMA(2,1,1)(2,0,0)[12] with drift         : -1187.005
##  ARIMA(2,1,2)                               : -1142.307
##  ARIMA(2,1,2)            with drift         : -1141.125
##  ARIMA(2,1,2)(0,0,1)[12]                    : -1188.819
##  ARIMA(2,1,2)(0,0,1)[12] with drift         : -1187.782
##  ARIMA(2,1,2)(1,0,0)[12]                    : -1163.747
##  ARIMA(2,1,2)(1,0,0)[12] with drift         : -1162.471
##  ARIMA(2,1,3)                               : -1140.258
##  ARIMA(2,1,3)            with drift         : -1139.051
##  ARIMA(3,1,0)                               : -1115.112
##  ARIMA(3,1,0)            with drift         : -1114.905
##  ARIMA(3,1,0)(0,0,1)[12]                    : -1154.022
##  ARIMA(3,1,0)(0,0,1)[12] with drift         : -1153.963
##  ARIMA(3,1,0)(0,0,2)[12]                    : Inf
##  ARIMA(3,1,0)(0,0,2)[12] with drift         : Inf
##  ARIMA(3,1,0)(1,0,0)[12]                    : -1131.071
##  ARIMA(3,1,0)(1,0,0)[12] with drift         : -1130.804
##  ARIMA(3,1,0)(1,0,1)[12]                    : Inf
##  ARIMA(3,1,0)(1,0,1)[12] with drift         : Inf
##  ARIMA(3,1,0)(2,0,0)[12]                    : -1160.085
##  ARIMA(3,1,0)(2,0,0)[12] with drift         : -1159.849
##  ARIMA(3,1,1)                               : -1141.049
##  ARIMA(3,1,1)            with drift         : -1139.812
##  ARIMA(3,1,1)(0,0,1)[12]                    : -1187.816
##  ARIMA(3,1,1)(0,0,1)[12] with drift         : -1186.749
##  ARIMA(3,1,1)(1,0,0)[12]                    : -1162.363
##  ARIMA(3,1,1)(1,0,0)[12] with drift         : -1161.04
##  ARIMA(3,1,2)                               : -1145.856
##  ARIMA(3,1,2)            with drift         : -1145.192
##  ARIMA(4,1,0)                               : -1134.843
##  ARIMA(4,1,0)            with drift         : -1134.03
##  ARIMA(4,1,0)(0,0,1)[12]                    : -1180.344
##  ARIMA(4,1,0)(0,0,1)[12] with drift         : -1179.709
##  ARIMA(4,1,0)(1,0,0)[12]                    : -1154.252
##  ARIMA(4,1,0)(1,0,0)[12] with drift         : -1153.368
##  ARIMA(4,1,1)                               : -1140.51
##  ARIMA(4,1,1)            with drift         : -1139.296
##  ARIMA(5,1,0)                               : -1138.508
##  ARIMA(5,1,0)            with drift         : -1137.466
## 
## 
## 
##  Best model: ARIMA(1,1,2)(0,0,1)[12]

After running the ARIMA models, I take the summary results:

print(summary(fit_unemp_sa))
## Series: unemp_sa 
## ARIMA(1,1,2)(0,0,1)[12] 
## 
## Coefficients:
##          ar1      ma1     ma2     sma1
##       0.9776  -0.9587  0.2495  -0.5100
## s.e.  0.0106   0.0448  0.0410   0.0841
## 
## sigma^2 = 0.005069:  log likelihood = 600.49
## AIC=-1190.98   AICc=-1190.86   BIC=-1170
## 
## Training set error measures:
##                        ME       RMSE        MAE         MPE      MAPE
## Training set -0.002868487 0.07083754 0.05416599 -0.02389498 0.7635837
##                    MASE         ACF1
## Training set 0.07840791 -0.003407759

Statistical analysis shows that ARIMA(1,1,2)(0,0,1)[12] model is the best according to AIC criteria. I, then, look for residuals that show me the model robustness check:

checkresiduals(fit_unemp_sa)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,1,2)(0,0,1)[12]
## Q* = 64.088, df = 20, p-value = 1.629e-06
## 
## Model df: 4.   Total lags used: 24

Residuals seems to follow normal distribution and more stability ACF values. So, I can keep going forecast the series. But, I am wondering ETS calculation:

fit_ets <- ets(unemp_sa)
print(summary(fit_ets))
## ETS(A,Ad,N) 
## 
## Call:
##  ets(y = unemp_sa) 
## 
##   Smoothing parameters:
##     alpha = 0.7386 
##     beta  = 0.2715 
##     phi   = 0.9507 
## 
##   Initial states:
##     l = 12.0182 
##     b = -0.017 
## 
##   sigma:  0.0751
## 
##      AIC     AICc      BIC 
## 508.6542 508.8274 533.8451 
## 
## Training set error measures:
##                        ME      RMSE        MAE         MPE     MAPE       MASE
## Training set -0.002822835 0.0746825 0.05664773 -0.02241016 0.809953 0.08200035
##                     ACF1
## Training set 0.001264234
checkresiduals(fit_ets)

## 
##  Ljung-Box test
## 
## data:  Residuals from ETS(A,Ad,N)
## Q* = 68.914, df = 24, p-value = 3.189e-06
## 
## Model df: 0.   Total lags used: 24

After comparing ACF values, ARIMA model estimation seems more relevant for forecasting of unemployment rate.

Forecasting with ARIMA model

To do this, I use forecast function. I prefer that I need to forecast 2024 January, February and March seasonal adjusted unemployment rate of Netherlands. And also, I put last 10 observation for easily show the graph:

unemp_sa_forecast <- forecast(fit_unemp_sa,h=3)
autoplot(unemp_sa_forecast,include = 20)

Let’s get the point, 80% and 95% interval forecasts of the series:

print(summary(unemp_sa_forecast))
## 
## Forecast method: ARIMA(1,1,2)(0,0,1)[12]
## 
## Model Information:
## Series: unemp_sa 
## ARIMA(1,1,2)(0,0,1)[12] 
## 
## Coefficients:
##          ar1      ma1     ma2     sma1
##       0.9776  -0.9587  0.2495  -0.5100
## s.e.  0.0106   0.0448  0.0410   0.0841
## 
## sigma^2 = 0.005069:  log likelihood = 600.49
## AIC=-1190.98   AICc=-1190.86   BIC=-1170
## 
## Error measures:
##                        ME       RMSE        MAE         MPE      MAPE
## Training set -0.002868487 0.07083754 0.05416599 -0.02389498 0.7635837
##                    MASE         ACF1
## Training set 0.07840791 -0.003407759
## 
## Forecasts:
##          Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## Jan 2024       3.477566 3.386319 3.568813 3.338016 3.617116
## Feb 2024       3.457027 3.326760 3.587294 3.257800 3.656254
## Mar 2024       3.455141 3.279763 3.630518 3.186924 3.723357

Let’s discuss the results. I predict that first month point estimation is 3.47% and when %5 error rate is used, lower and higher interval predictions are 3.33% and 3.61%, respectively. When I compare this result with the actual observation of January unemployment rate, it is in the interval band that I provide. You can check the result from this web site:

https://www.cbs.nl/en-gb/figures/detail/80590eng