Forecasting Government Expenditure in Ghana Using Autoregressive Integrated Moving Average with Exogenous Variables (ARIMAX)
Abstract: This study develops and evaluates an Autoregressive Integrated Moving Average with Exogenous Variables (ARIMAX) model for forecasting Ghana’s government expenditure over the period 1984–2024. The dependent variable is log-transformed total government expenditure (USD equivalent), and three exogenous variables are examined — population, log government revenue, and log GDP — both jointly and in isolation. The ARIMAX framework is compared against a univariate ARIMA baseline using information criteria (AIC, BIC) and standard accuracy metrics (RMSE, MAE, MAPE, MASE). Results demonstrate that incorporating macroeconomic exogenous variables into the time series framework meaningfully improves forecasting performance. Policy implications for Ghana’s medium-term fiscal planning are discussed.
Government expenditure is a critical pillar of Ghana’s development, financing key sectors such as education, healthcare, infrastructure, and social protection that contribute directly to productivity growth, human capital development, and long-term economic performance (World Bank, 2023). In the majority of developing countries, government is seen as an instrument of change, and hence the size of government expenditure reveals the magnitude of government involvement in the economy.
The shift in the role of government — from traditional functions such as provision of security, administration, and law and order, to direct intervention in income-generating activities like capital investment and distributive roles like subsidies and transfers — has significantly expanded the scope of governments in many countries across the globe.
Government expenditure is defined as the total spending by the government on recurrent items and capital projects, primarily funded through budgetary appropriations and often involving significant allocations for personnel costs (Leonard Onyiruba, 2016). In Ghana, government expenditure includes various components such as total public spending on purchase of goods and services, compensation of employees, interest payments, grants to other government units, non-financial assets, and capital expenditure. As defined by the International Monetary Fund (IMF), general government expenditure consists of total expense and the net acquisition of nonfinancial assets (Statista, 2025).
Ghana’s fiscal exposure is characterised by its status as a commodity-dependent economy. Changes in world prices of cocoa, gold, and oil directly affect export earnings, tax revenues, and the overall fiscal balance. When commodity prices rise, revenue and spending pressures typically rise; when prices fall, fiscal stress often triggers spending cuts or arrears. Ghana’s public spending has fluctuated significantly due to changes in political priorities, inflationary pressures, and debt servicing obligations — inconsistencies that make it difficult for policymakers to predict expenditure accurately, often resulting in fiscal imbalances and budget deficits.
These trends underscore a critical need for reliable forecasting tools that can help policymakers anticipate future expenditure paths, identify potential fiscal risk, and make informed, data-driven decisions that ensure long-term fiscal sustainability.
Traditional estimation methods have limitations in handling dynamic economic data; hence time-series models such as the ARIMAX (Autoregressive Integrated Moving Average with Exogenous Variables) offer a more reliable approach. In many real situations, the assumption that only past values influence future outcomes is too limited because external factors often play a significant role in influencing the direction and behaviour of a time series. This is where ARIMAX becomes particularly valuable — by integrating exogenous variables directly into the forecasting process, allowing for more realistic and accurate predictions.
Government expenditure in Ghana faces several significant challenges and limitations, primarily driven by high public debt, a narrow revenue base, and weaknesses in public financial management (PFM) systems. Despite fiscal reforms, Ghana continues to face budget overruns, expenditure volatility, and debt-related pressures. The May 2023 IMF Extended Credit Facility (ECF) arrangement was triggered by severe fiscal and debt vulnerabilities following external shocks and policy slippages (Ministry of Finance, Ghana).
Awariefe & Ogumeyo (2023) found that traditional regression (MLR) underperforms when predicting government expenditure because it cannot handle complex, non-linear macro dynamics. Djakou & Jiang (2023) found that an ARIMA(1,1,1) model assumes a linear trend and does not fully capture external macro shocks such as volatility in budget performance. While several studies have applied ARIMA-type models in Ghana for forecasting inflation, GDP, or tax revenue, there is limited evidence of similar applications for government expenditure forecasting using the ARIMAX framework.
This methodological gap reduces policymakers’ ability to anticipate the implications of macroeconomic shocks and IMF fiscal regimes. This study addresses the gap by applying ARIMAX with population, revenue, and GDP as exogenous variables to deliver more reliable fiscal forecasts for Ghana.
General Objective: To develop an ARIMAX-based forecasting model for Ghana’s government expenditure, using population, government revenue, and GDP as exogenous variables.
Specific Objectives:
This study is significant on multiple fronts:
The theoretical framework for this study draws on several interrelated strands of economic and statistical theory:
Box-Jenkins ARIMA Methodology
The theoretical foundation for ARIMA (Autoregressive Integrated Moving
Average) modelling is based on the Box-Jenkins methodology developed by
George Box and Gwilym Jenkins (1970), which establishes a systematic
process for identification, estimation, and diagnostic checking of time
series models. ARIMAX extends this framework by incorporating exogenous
regressors (transfer functions), allowing the model to capture external
influences on the primary series.
Keynesian Fiscal Theory
John Maynard Keynes (1936) posits that government spending is a critical
component of aggregate demand and a powerful tool for economic
stabilisation. This perspective reinforces the importance of accurately
forecasting expenditure to guide effective fiscal planning and ensure
macroeconomic stability. According to Keynesian theory, an increase in
government expenditure leads to an increase in aggregate demand,
production, and ultimately GDP — making GDP a natural exogenous
candidate in the ARIMAX framework.
Wagner’s Law
Named after German economist Adolph Wagner, this hypothesis posits that
as an economy develops over time, government expenditure grows more than
proportionally relative to national income. Wagner’s Law implies a
long-run upward drift in public spending as economies grow, providing
the theoretical basis for including GDP and population as exogenous
drivers of expenditure.
Peacock-Wiseman Displacement Hypothesis
Peacock and Wiseman (1961) argue that public expenditure does not
increase at a steady rate, but rather jumps in response to major
economic or social disturbances (wars, crises, pandemics). Once
elevated, spending rarely returns to its pre-shock level — a
“displacement” effect. This theoretical lens is important for
understanding Ghana’s expenditure jumps around periods of economic
crisis.
Commodity-Price Fiscal Linkage
In commodity-exporting economies, global price shocks influence tax
receipts, borrowing costs, and expenditure choices. IMF working paper
evidence (Spatafora & Samake, 2012) shows both revenue and
expenditure respond significantly to commodity price movements, making
fiscal policy highly procyclical in such settings.
A growing body of literature confirms that ARIMAX models consistently outperform baseline ARIMA models when relevant exogenous information is available:
Jiayi Yang (2025): Applied ARIMA, ARIMAX, VAR, and GLM to forecast China’s university admission rates (1977–2024). The ARIMAX model, incorporating GDP and newborn population as exogenous variables, produced the lowest forecast errors and provided deeper insights into how macroeconomic factors drive admission rates.
Fairuz Azizah et al. (2025): Modelled Indonesia’s Human Development Index using ARIMAX with inflation and infant mortality as exogenous variables. Results confirmed that including these external drivers significantly improved estimation accuracy over the pure ARIMA specification.
Coker (2025): Compared ARIMA, ARIMAX, and VAR for short-term inflation forecasting in Sierra Leone. The ARIMAX model incorporating the exchange rate as an exogenous variable significantly outperformed the alternatives, underscoring the importance of external drivers in small, open economies.
Abdulazeez (2021): Demonstrated in a Nigeria GDP forecasting study that ARIMAX with agriculture, industry, and services sector shares consistently outperformed ARIMA across all error metrics (RMSE: 899 vs 1,662; MSE: 568 vs 1,161).
Ajibode & Adeboye: Applied ARIMA and ARIMAX to COVID-19 mortality modelling in Nigeria. ARIMAX with confirmed cases as an exogenous variable produced the lowest MAE (5.98) and RMSE (8.54), outperforming the pure ARIMA specification.
Michael Safo Ofori et al.: Forecasting VAT revenue in Ghana using ARIMA with intervention, demonstrating the utility of time-series methods for Ghanaian fiscal data and validating the approach adopted in the present study.
Boachie et al. (2022): Examined Ghana’s public health spending (1980–2014) using 3SLS estimators, finding that IMF programme conditionalities slightly constrained public health spending, supporting the inclusion of IMF regime indicators in fiscal forecasting models.
The reviewed literature consistently highlights that: (1) ARIMA models are a well-established baseline for univariate fiscal forecasting; (2) the incorporation of exogenous variables through the ARIMAX framework reliably improves forecasting accuracy; (3) macro-fiscal variables such as GDP, revenue, and population are the most empirically validated exogenous drivers; and (4) there is a notable gap in the application of ARIMAX to Ghana’s government expenditure forecasting — the gap this study addresses.
A quantitative, predictive time-series design is adopted, consistent with the Box-Jenkins tradition. The study employs secondary annual data covering the period 1983–2024 (42 observations), drawing on official government fiscal records and national accounts. The research is both explanatory (examining the influence of macroeconomic exogenous variables on expenditure) and predictive (generating a 10-year out-of-sample forecast).
| Variable | Description | Unit | Source |
|---|---|---|---|
| GE (Y) | Total Government Expenditure (Net Lending) | Million GHS → log(USD) | Bank of Ghana — Gov. Fiscal Operations |
| POPULATION (X1) | Ghana’s Annual Population | Persons | World Bank / Ghana Statistical Service |
| REVENUE (X2) | Total Government Revenue (Million GHS → USD) | log(USD) | Bank of Ghana — Gov. Fiscal Operations |
| GDP (X3) | Nominal GDP (USD Billion → USD) | log(USD) | World Bank National Accounts |
The dataset spans 1983 to 2024, with the following coverage:
All currency-denominated variables (expenditure, revenue) are converted from Ghana Cedis to US Dollars using the contemporaneous annual average exchange rate. This conversion normalises the data against the extreme nominal exchange-rate depreciation that Ghana experienced over the study period, particularly post-2014. Log transformations are then applied to all monetary variables to stabilise variance and linearise exponential growth trends.
The ARIMA(p, d, q) model combines three core components:
AR(p) — Autoregressive component: Models the relationship between the current observation and \(p\) lagged values: \[X_t = c + \phi_1 X_{t-1} + \phi_2 X_{t-2} + \ldots + \phi_p X_{t-p} + \epsilon_t\]
I(d) — Integration (Differencing): The series is differenced \(d\) times to achieve stationarity, removing trend and unit-root behaviour.
MA(q) — Moving Average component: Models the relationship between the current value and \(q\) lagged forecast errors: \[X_t = c + \epsilon_t + \theta_1 \epsilon_{t-1} + \theta_2 \epsilon_{t-2} + \ldots + \theta_q \epsilon_{t-q}\]
Combined: \[X_t = c + \sum_{i=1}^{p}\phi_i X_{t-i} + \sum_{j=1}^{q}\theta_j \epsilon_{t-j} + \epsilon_t\]
The ARIMAX model augments the ARIMA framework with exogenous regressors \(X_k\):
\[Y_t = \mu + \sum_{i=1}^{p}\phi_i Y_{t-i} + \sum_{j=1}^{q}\theta_j \epsilon_{t-j} + \sum_{k}\beta_k X_{k,t} + \epsilon_t\]
where: - \(Y_t\) = Government Expenditure (log USD) at time \(t\) - \(X_{k,t}\) = exogenous variables (population, log revenue, log GDP) - \(\beta_k\) = coefficients for the exogenous variables - \(\epsilon_t \sim WN(0, \sigma^2)\)
| Criterion | Formula | Preference |
|---|---|---|
| AIC | \(-2\log(L) + 2k\) | Lower is better |
| BIC | \(-2\log(L) + k\log(n)\) | Lower is better |
| RMSE | \(\sqrt{\frac{1}{n}\sum e_t^2}\) | Lower is better |
| MAE | \(\frac{1}{n}\sum|e_t|\) | Lower is better |
| MAPE | \(\frac{100}{n}\sum|e_t/Y_t|\) | Lower is better |
| MASE | Scaled by naïve forecast MAE | < 1 is better |
Augmented Dickey-Fuller (ADF) Test: \[\Delta y_t = \alpha + \beta t + \rho y_{t-1} + \sum_{i=1}^{k}\phi_i \Delta y_{t-i} + \epsilon_t\]
All required R packages are loaded here. These cover time series
modelling (forecast, tseries),
multicollinearity diagnostics (car), data import
(readxl), and data manipulation/visualisation
(tidyverse).
# Time series modelling and forecasting toolkit
library(forecast)
# Augmented Dickey-Fuller and KPSS unit root tests
library(tseries)
# Variance Inflation Factor for multicollinearity diagnostics
library(car)
# Reading Excel data files
library(readxl)
# Data manipulation and visualisation (dplyr, ggplot2, tidyr)
library(tidyverse)# Load the annual fiscal dataset (1983–2024)
data_raw <- read_excel("Data2.xlsx")
# Preview the raw data structure
glimpse(data_raw)#> Rows: 42
#> Columns: 7
#> $ YEAR <dbl> 1983, 1984, 1985, 1986, 1987, 1988, 1989, …
#> $ EXPENDITURE <dbl> 1.51, 2.75, 4.79, 7.33, 10.69, 14.99, 20.4…
#> $ POPULATION <dbl> 13029836, 13370590, 13661229, 13965217, 14…
#> $ ELECTION <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, …
#> $ `GDP USD BILLION` <dbl> 4.06, 4.41, 4.50, 5.74, 5.07, 5.20, 5.25, …
#> $ `REVENUE MILLION OF CEDIS` <dbl> 1.03, 2.26, 4.03, 7.36, 11.10, 15.38, 21.4…
#> $ EXCHANGE_RATE <dbl> 0.00, 0.01, 0.01, 0.01, 0.02, 0.02, 0.03, …
Government expenditure and revenue are denominated in millions of Ghana Cedis (GHS). To control for the severe nominal depreciation of the cedi over the study period — from roughly 2.7 GHS/USD in 1984 to over 12 GHS/USD by the early 2020s — all monetary variables are converted to US Dollars using the contemporaneous annual exchange rate.
Log transformations are applied to all monetary variables to: 1. Stabilise the exponential growth in variance (heteroscedasticity correction) 2. Linearise the long-run upward trend, making the series more amenable to ARIMA modelling 3. Enable percentage-change interpretation of first differences
data <- data_raw |>
mutate(
# Convert GHS expenditure (millions) to USD
GOV_EXP_DOLLARS = EXPENDITURE * 1000000 / EXCHANGE_RATE,
# Convert GHS revenue (millions) to USD
REVEVENUE = `REVENUE MILLION OF CEDIS` * 1000000 / EXCHANGE_RATE,
# Convert GDP (USD billions) to USD for unit consistency
GDP = `GDP USD BILLION` * 1000000000,
# Apply natural log transformation to all monetary variables
# Rationale: log stabilises exponential variance growth and linearises trend
LOG_EXPENDITURE = log(GOV_EXP_DOLLARS),
LOG_REVENUE = log(REVEVENUE),
LOG_GDP = log(GDP)
) |>
# Remove original pre-transformation columns and the election dummy
# (election effects are not part of this specification)
select(-c(EXPENDITURE, `REVENUE MILLION OF CEDIS`, `GDP USD BILLION`,
EXCHANGE_RATE, ELECTION)) |>
# Remove rows where division by zero produced Inf values
filter(GOV_EXP_DOLLARS != Inf)
# Show the processed dataset structure
glimpse(data)#> Rows: 38
#> Columns: 8
#> $ YEAR <dbl> 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, …
#> $ POPULATION <dbl> 13370590, 13661229, 13965217, 14289108, 14636568, 1500…
#> $ GOV_EXP_DOLLARS <dbl> 275000000, 479000000, 733000000, 534500000, 749500000,…
#> $ REVEVENUE <dbl> 226000000, 403000000, 736000000, 555000000, 769000000,…
#> $ GDP <dbl> 4410000000, 4500000000, 5740000000, 5070000000, 520000…
#> $ LOG_EXPENDITURE <dbl> 19.43228, 19.98721, 20.41266, 20.09684, 20.43492, 20.3…
#> $ LOG_REVENUE <dbl> 19.23605, 19.81445, 20.41674, 20.13448, 20.46060, 20.3…
#> $ LOG_GDP <dbl> 22.20714, 22.22734, 22.47073, 22.34661, 22.37192, 22.3…
#> GOV_EXP_DOLLARS LOG_EXPENDITURE LOG_REVENUE LOG_GDP
#> Min. : 275000000 Min. :19.43 Min. :19.24 Min. :22.21
#> 1st Qu.: 1298788194 1st Qu.:20.98 1st Qu.:20.71 1st Qu.:22.50
#> Median : 2043748876 Median :21.44 Median :21.24 Median :22.76
#> Mean : 5373578988 Mean :21.79 Mean :21.60 Mean :23.38
#> 3rd Qu.: 9750098001 3rd Qu.:23.00 3rd Qu.:22.86 3rd Qu.:24.43
#> Max. :18808242685 Max. :23.66 Max. :23.21 Max. :25.10
#> POPULATION
#> Min. :13370590
#> 1st Qu.:16690437
#> Median :21013046
#> Mean :21768557
#> 3rd Qu.:26574473
#> Max. :32518665
# Dependent variable: log government expenditure as annual time series
# Starting from 1984 (first year with valid exchange rate data)
Y <- ts(data$LOG_EXPENDITURE, start = 1984, frequency = 1)
# Exogenous variable matrix used in ARIMAX models
xreg_vars <- data[, c("POPULATION", "LOG_REVENUE", "LOG_GDP")]
# Forecast horizon: 10 years beyond the end of the estimation sample
h_period <- 10
cat("Dependent variable (Y): Log Government Expenditure\n")#> Dependent variable (Y): Log Government Expenditure
#> Sample period: 1984 to 2021
#> Observations: 38
#> Forecast horizon: 10 years
Before formal modelling, it is important to visually inspect Ghana’s government expenditure history. The time series plot below reveals the character of the data: the direction of the trend, any structural breaks, and the general growth trajectory.
par(mfrow = c(2, 1), mar = c(4, 5, 3, 2))
# Plot 1: Raw USD expenditure
plot(ts(data$GOV_EXP_DOLLARS / 1e9, start = 1984),
type = "o", col = "steelblue", lwd = 2,
main = "Ghana Total Government Expenditure (USD Billion)",
ylab = "USD Billion", xlab = "Year")
grid(col = "lightgray", lty = "dotted")
# Plot 2: Log-transformed expenditure (used as Y in models)
plot(Y,
type = "o", col = "darkgreen", lwd = 2,
main = "Log Government Expenditure (used as dependent variable Y)",
ylab = "Log(USD)", xlab = "Year")
grid(col = "lightgray", lty = "dotted")Figure 1: Ghana’s Log Government Expenditure in USD (1984–2024)
Observation: The raw expenditure series exhibits exponential growth — characteristic of a nominal fiscal variable in a developing economy undergoing both real growth and significant price-level increases. The log transformation converts this to a near-linear upward trend, more appropriate for ARIMA-based modelling. Notable inflections (post-2014 cedi depreciation, post-2020 COVID-19 fiscal expansion) are visible in both plots.
par(mfrow = c(3, 1), mar = c(3, 5, 2, 2))
plot(ts(data$POPULATION / 1e6, start = 1984),
type = "o", col = "darkorange", lwd = 1.5,
main = "Ghana Population (Millions)", ylab = "Millions", xlab = "")
grid(col = "lightgray", lty = "dotted")
plot(ts(data$LOG_REVENUE, start = 1984),
type = "o", col = "purple", lwd = 1.5,
main = "Log Government Revenue (USD)", ylab = "Log(USD)", xlab = "")
grid(col = "lightgray", lty = "dotted")
plot(ts(data$LOG_GDP, start = 1984),
type = "o", col = "firebrick", lwd = 1.5,
main = "Log GDP (USD)", ylab = "Log(USD)", xlab = "Year")
grid(col = "lightgray", lty = "dotted")Figure 2: Exogenous Variables — Population, Log Revenue, Log GDP (1984–2024)
Observation: All three exogenous variables exhibit persistent upward trends over the sample period. Population growth is smooth and demographic in nature. Revenue and GDP share a similar trajectory to expenditure, reflecting the co-movement between fiscal variables and macroeconomic performance over Ghana’s development path. This co-movement is precisely the signal that ARIMAX is designed to exploit.
Before including multiple exogenous regressors in the ARIMAX model, potential multicollinearity is assessed using the Variance Inflation Factor (VIF). Multicollinearity arises when two or more predictors are highly linearly correlated, inflating coefficient standard errors and undermining interpretability.
Decision rule: - VIF < 5 → Acceptable - VIF 5–10 → Moderate concern; monitor - VIF > 10 → Severe multicollinearity → consider dimensionality reduction or variable exclusion
Given that population, revenue, and GDP are all trending upward over the same period, some degree of multicollinearity is expected. This motivates the individual ARIMAX models (one exogenous variable at a time) fitted in Section 4.7–4.9.
# Fit auxiliary OLS regression solely to compute VIF values
# (Not used for forecasting; diagnostic purpose only)
vif_model <- lm(Y ~ POPULATION + LOG_REVENUE + LOG_GDP, data = data)
cat("=== Variance Inflation Factors (VIF) ===\n")#> === Variance Inflation Factors (VIF) ===
#> POPULATION LOG_REVENUE LOG_GDP
#> 17.69051 20.10369 15.43043
#>
#> Note: VIF > 10 indicates severe multicollinearity.
#> VIF > 5 suggests moderate collinearity that may inflate standard errors.
Interpretation: High VIF values among
LOG_REVENUE,LOG_GDP, andPOPULATIONare plausible given that all three grow in tandem with the Ghanaian economy over time. The joint ARIMAX model (Section 4.6) is included for completeness, but the individual models (Sections 4.7–4.9) provide cleaner, more interpretable estimates by avoiding multicollinear combinations.
The ADF test evaluates whether the log expenditure series \(Y_t\) contains a unit root (is non-stationary):
#> === ADF Test: Log Government Expenditure (Level) ===
#>
#> Augmented Dickey-Fuller Test
#>
#> data: Y
#> Dickey-Fuller = -2.2832, Lag order = 3, p-value = 0.4626
#> alternative hypothesis: stationary
if (adf_level$p.value > 0.05) {
cat("\n>> Decision: Fail to reject H0 (p =", round(adf_level$p.value, 4),
") — Series is NON-STATIONARY. Differencing required.\n")
} else {
cat("\n>> Decision: Reject H0 (p =", round(adf_level$p.value, 4),
") — Series is STATIONARY. No differencing needed.\n")
}#>
#> >> Decision: Fail to reject H0 (p = 0.4626 ) — Series is NON-STATIONARY. Differencing required.
If the level series is non-stationary, differencing is applied to remove the trend and induce stationarity. Second-order differencing (d = 2) corresponds to the integration order I(2), which is common for fiscal series with strong exponential growth.
# Apply second-order differencing
log_y_diff <- diff(Y, differences = 2)
cat("=== ADF Test: Second-Order Differenced Series ===\n")#> === ADF Test: Second-Order Differenced Series ===
#>
#> Augmented Dickey-Fuller Test
#>
#> data: log_y_diff
#> Dickey-Fuller = -4.8497, Lag order = 3, p-value = 0.01
#> alternative hypothesis: stationary
if (adf_diff$p.value < 0.05) {
cat("\n>> Decision: Reject H0 (p =", round(adf_diff$p.value, 4),
") — Differenced series is STATIONARY. d = 2 is appropriate.\n")
} else {
cat("\n>> Decision: Fail to reject H0 — further differencing may be required.\n")
}#>
#> >> Decision: Reject H0 (p = 0.01 ) — Differenced series is STATIONARY. d = 2 is appropriate.
par(mfrow = c(2, 1), mar = c(4, 5, 3, 2))
plot(Y, type = "o", col = "steelblue", lwd = 1.5,
main = "Level Series: Log Government Expenditure",
ylab = "Log(USD)", xlab = "")
abline(lm(Y ~ time(Y)), col = "red", lty = 2, lwd = 2)
legend("topleft", legend = "OLS Trend Line", col = "red",
lty = 2, bty = "n", cex = 0.85)
grid(col = "lightgray", lty = "dotted")
plot(log_y_diff, type = "o", col = "firebrick", lwd = 1.5,
main = "Second-Order Differenced Series (d = 2)",
ylab = "Differenced Log(USD)", xlab = "Year")
abline(h = 0, col = "black", lty = 2)
grid(col = "lightgray", lty = "dotted")Figure 3: Level and Second-Differenced Log Government Expenditure
Interpretation: The level series (top panel) shows a clear upward trend with a fitted OLS trend line, confirming non-stationarity. After second-order differencing (bottom panel), the series fluctuates around zero without a systematic drift, indicating that the trend has been successfully removed. The ADF test result on the differenced series confirms stationarity, and d = 2 is adopted in the ARIMA/ARIMAX specifications.
The Autocorrelation Function (ACF) and Partial Autocorrelation Function (PACF) are the primary tools for identifying the autoregressive order (p) and moving average order (q) in the Box-Jenkins framework:
| Pattern | Implication |
|---|---|
| PACF: spike at lag \(k\), then cuts off | AR(\(k\)) component |
| ACF: spike at lag \(k\), then cuts off | MA(\(k\)) component |
| Both decay slowly | Mixed ARMA; use auto.arima |
| No significant spikes in differenced series | Differencing sufficient; d is appropriate |
par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
Acf(Y, main = "ACF — Level Series", lag.max = 20); grid()
Pacf(Y, main = "PACF — Level Series", lag.max = 20); grid()Figure 4: ACF and PACF of Level Series (Log Government Expenditure)
par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
Acf(log_y_diff, main = "ACF — Differenced Series", lag.max = 20); grid()
Pacf(log_y_diff, main = "PACF — Differenced Series", lag.max = 20); grid()Figure 5: ACF and PACF of Second-Differenced Series
Interpretation: The level series ACF decays slowly (consistent with non-stationarity). In the differenced series, spikes that fall within the 95% confidence bands (blue dashed lines at ±1.96/√n) suggest that differencing has removed most autocorrelation. Remaining significant spikes, if any, guide the selection of p and q.
auto.arima()in subsequent sections performs a systematic AIC/BIC-guided search to confirm the optimal orders.
Future values of the exogenous variables must be specified to generate ARIMAX out-of-sample forecasts. A mean-projection approach is used here, setting each exogenous variable to its in-sample mean across the 10-year horizon. This is a conservative, assumption-neutral approach.
In practice, scenario-based projections (e.g., IMF WEO GDP projections, UN population forecasts) would be preferred for policy applications. The mean projection provides a baseline forecast that captures the average historical influence of each exogenous variable.
# Mean-based projection of exogenous variables over 10-year horizon
future_population <- rep(mean(data$POPULATION), h_period)
future_revenue <- rep(mean(data$LOG_REVENUE), h_period)
future_gdp <- rep(mean(data$LOG_GDP), h_period)
# Assemble as a matrix with column names matching the estimation xreg
future_xreg <- cbind(future_population, future_revenue, future_gdp)
colnames(future_xreg) <- colnames(xreg_vars)
cat("Future exogenous variable projections (mean of in-sample values):\n")#> Future exogenous variable projections (mean of in-sample values):
#> Population (mean): 21768557
#> Log Revenue (mean): 21.5995
#> Log GDP (mean): 23.3838
The univariate ARIMA model serves as the benchmark against which all ARIMAX specifications are evaluated. It explains Ghana’s log expenditure solely from its own historical dynamics — past values and lagged shocks — with no external information.
auto.arima() with stepwise = FALSE and
approximation = FALSE performs an exhaustive search across
candidate (p, d, q) combinations, selecting the specification with the
lowest AIC. Maximum Likelihood Estimation (MLE) is used for parameter
estimation, providing efficient and asymptotically unbiased
estimates.
#> === Fitting ARIMA Baseline Model ===
#> Method: Maximum Likelihood Estimation (MLE)
#> Selection: AIC-minimising exhaustive search
arima_fit <- auto.arima(
Y,
stepwise = FALSE, # Exhaustive, not stepwise, search
approximation = FALSE, # Exact (not approximate) AIC values
method = "ML" # Maximum Likelihood Estimation
)
summary(arima_fit)#> Series: Y
#> ARIMA(0,1,0) with drift
#>
#> Coefficients:
#> drift
#> 0.1142
#> s.e. 0.0340
#>
#> sigma^2 = 0.0441: log likelihood = 5.76
#> AIC=-7.51 AICc=-7.16 BIC=-4.29
#>
#> Training set error measures:
#> ME RMSE MAE MPE MAPE MASE
#> Training set 0.0005083704 0.2043941 0.168418 0.004295336 0.7818951 0.8428475
#> ACF1
#> Training set -0.09354056
A valid ARIMA model should produce white noise residuals — residuals that are uncorrelated, approximately normally distributed, and have constant variance. Any remaining structure in the residuals indicates model misspecification.
Figure 6: ARIMA Baseline — Residual Diagnostics
#>
#> Ljung-Box test
#>
#> data: Residuals from ARIMA(0,1,0) with drift
#> Q* = 2.2888, df = 8, p-value = 0.9709
#>
#> Model df: 0. Total lags used: 8
The Ljung-Box test formally tests whether the first 10 residual autocorrelations are jointly zero:
lb_arima <- Box.test(residuals(arima_fit), lag = 10, type = "Ljung-Box")
cat("=== Ljung-Box Test (lag = 10) — ARIMA Baseline ===\n")#> === Ljung-Box Test (lag = 10) — ARIMA Baseline ===
#>
#> Box-Ljung test
#>
#> data: residuals(arima_fit)
#> X-squared = 2.3896, df = 10, p-value = 0.9924
if (lb_arima$p.value > 0.05) {
cat("\n>> Decision: p =", round(lb_arima$p.value, 4),
"> 0.05 — Fail to reject H0. Residuals are white noise. Model is adequate.\n")
} else {
cat("\n>> Decision: p =", round(lb_arima$p.value, 4),
"< 0.05 — Reject H0. Residual autocorrelation detected. Model may be misspecified.\n")
}#>
#> >> Decision: p = 0.9924 > 0.05 — Fail to reject H0. Residuals are white noise. Model is adequate.
#> === ARIMA — Model Fit Statistics ===
#> AIC: -7.5107
#> BIC: -4.2889
#> === ARIMA — In-Sample Accuracy Metrics ===
#> ME RMSE MAE MPE MAPE MASE
#> Training set 0.0005083704 0.2043941 0.168418 0.004295336 0.7818951 0.8428475
#> ACF1
#> Training set -0.09354056
arima_forecast <- forecast(arima_fit, h = h_period)
cat("=== ARIMA — Point Forecasts and Prediction Intervals ===\n")#> === ARIMA — Point Forecasts and Prediction Intervals ===
#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> 2022 23.77176 23.50264 24.04088 23.36018 24.18334
#> 2023 23.88595 23.50536 24.26655 23.30389 24.46802
#> 2024 24.00015 23.53402 24.46628 23.28727 24.71303
#> 2025 24.11435 23.57611 24.65259 23.29118 24.93751
#> 2026 24.22854 23.62678 24.83031 23.30822 25.14887
#> 2027 24.34274 23.68354 25.00195 23.33457 25.35091
#> 2028 24.45694 23.74492 25.16896 23.36799 25.54588
#> 2029 24.57113 23.80995 25.33232 23.40700 25.73527
#> 2030 24.68533 23.87797 25.49269 23.45058 25.92008
#> 2031 24.79953 23.94850 25.65056 23.49799 26.10107
par(mfrow = c(1, 1), mar = c(4, 5, 3, 2))
plot(arima_forecast,
main = "ARIMA Baseline: 10-Year Forecast — Log Government Expenditure",
ylab = "Log Government Expenditure (USD)",
xlab = "Year",
col = "steelblue")
grid(col = "lightgray", lty = "dotted")Figure 7: ARIMA — 10-Year Forecast of Log Government Expenditure
This ARIMAX model includes all three exogenous variables simultaneously: population, log revenue, and log GDP. It tests whether the combined macroeconomic signal from these variables improves on the univariate ARIMA baseline.
#> === Fitting ARIMAX — All Exogenous Variables ===
#> Exogenous variables: POPULATION + LOG_REVENUE + LOG_GDP
arimax_fit <- auto.arima(
Y,
xreg = as.matrix(xreg_vars),
stepwise = FALSE,
approximation = FALSE,
method = "ML"
)
summary(arimax_fit)#> Series: Y
#> Regression with ARIMA(0,0,0) errors
#>
#> Coefficients:
#> intercept POPULATION LOG_REVENUE LOG_GDP
#> 2.2976 0.0000 0.8356 0.0247
#> s.e. 1.3758 0.0002 0.0758 0.0712
#>
#> sigma^2 = 0.01478: log likelihood = 28.26
#> AIC=-46.53 AICc=-44.65 BIC=-38.34
#>
#> Training set error measures:
#> ME RMSE MAE MPE
#> Training set -0.000000000000000934926 0.1150152 0.09975323 -0.003032057
#> MAPE MASE ACF1
#> Training set 0.4592601 0.4992147 0.2935644
Figure 8: ARIMAX (All Variables) — Residual Diagnostics
#>
#> Ljung-Box test
#>
#> data: Residuals from Regression with ARIMA(0,0,0) errors
#> Q* = 6.7298, df = 8, p-value = 0.566
#>
#> Model df: 0. Total lags used: 8
lb_all <- Box.test(residuals(arimax_fit), lag = 10, type = "Ljung-Box")
cat("=== Ljung-Box Test — ARIMAX (All Variables) ===\n")#> === Ljung-Box Test — ARIMAX (All Variables) ===
#>
#> Box-Ljung test
#>
#> data: residuals(arimax_fit)
#> X-squared = 10.955, df = 10, p-value = 0.3611
cat("\n>> Decision: p =", round(lb_all$p.value, 4), "—",
ifelse(lb_all$p.value > 0.05,
"Fail to reject H0. Residuals are white noise.",
"Reject H0. Residual autocorrelation present."), "\n")#>
#> >> Decision: p = 0.3611 — Fail to reject H0. Residuals are white noise.
#> === ARIMAX (All Variables) — Fit Statistics ===
#> AIC: -46.5252
#> BIC: -38.3372
#> === ARIMAX (All Variables) — Accuracy Metrics ===
#> ME RMSE MAE MPE
#> Training set -0.000000000000000934926 0.1150152 0.09975323 -0.003032057
#> MAPE MASE ACF1
#> Training set 0.4592601 0.4992147 0.2935644
arimax_all_forecast <- forecast(arimax_fit, xreg = future_xreg, h = h_period)
cat("=== ARIMAX (All Variables) — Point Forecasts ===\n")#> === ARIMAX (All Variables) — Point Forecasts ===
#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> 2022 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2023 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2024 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2025 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2026 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2027 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2028 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2029 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2030 21.79411 21.63828 21.94994 21.55579 22.03243
#> 2031 21.79411 21.63828 21.94994 21.55579 22.03243
par(mfrow = c(1, 1))
plot(arimax_all_forecast,
main = "ARIMAX (Population + Revenue + GDP): 10-Year Forecast",
ylab = "Log Government Expenditure (USD)",
xlab = "Year")
grid(nx = 30, ny = 30, col = "lightgray", lty = "dotted")Figure 9: ARIMAX (All Variables) — 10-Year Forecast
comp_all <- data.frame(
Metric = c("AIC", "BIC", "ME", "RMSE", "MAE", "MPE", "MAPE", "MASE"),
ARIMA = c(AIC(arima_fit), BIC(arima_fit),
accuracy(arima_fit)[1, "ME"], accuracy(arima_fit)[1, "RMSE"],
accuracy(arima_fit)[1, "MAE"], accuracy(arima_fit)[1, "MPE"],
accuracy(arima_fit)[1, "MAPE"], accuracy(arima_fit)[1, "MASE"]),
ARIMAX_ALL = c(AIC(arimax_fit), BIC(arimax_fit),
accuracy(arimax_fit)[1, "ME"], accuracy(arimax_fit)[1, "RMSE"],
accuracy(arimax_fit)[1, "MAE"], accuracy(arimax_fit)[1, "MPE"],
accuracy(arimax_fit)[1, "MAPE"], accuracy(arimax_fit)[1, "MASE"])
) |>
mutate(
Improvement = ifelse(Metric %in% c("ME", "MPE"),
ifelse(abs(ARIMAX_ALL) < abs(ARIMA), "Yes", "No"),
ifelse(ARIMAX_ALL < ARIMA, "Yes", "No"))
)
knitr::kable(comp_all, digits = 4,
caption = "Table 2: ARIMA vs ARIMAX (All Variables)")| Metric | ARIMA | ARIMAX_ALL | Improvement |
|---|---|---|---|
| AIC | -7.5107 | -46.5252 | Yes |
| BIC | -4.2889 | -38.3372 | Yes |
| ME | 0.0005 | 0.0000 | Yes |
| RMSE | 0.2044 | 0.1150 | Yes |
| MAE | 0.1684 | 0.0998 | Yes |
| MPE | 0.0043 | -0.0030 | Yes |
| MAPE | 0.7819 | 0.4593 | Yes |
| MASE | 0.8428 | 0.4992 | Yes |
Population is included as a standalone exogenous variable. In line with Wagner’s Law, population growth increases aggregate demand for public services — education, healthcare, infrastructure — directly pressuring expenditure upward. This model isolates the demographic channel.
#> === Fitting ARIMAX — Population as Exogenous Variable ===
arimax_fit_pop <- auto.arima(
Y,
xreg = as.matrix(xreg_vars[, "POPULATION"]),
stepwise = FALSE,
approximation = FALSE,
method = "ML"
)
summary(arimax_fit_pop)#> Series: Y
#> Regression with ARIMA(0,0,0) errors
#>
#> Coefficients:
#> intercept POPULATION
#> 17.5005 0.0000
#> s.e. 0.1676 0.0002
#>
#> sigma^2 = 0.07521: log likelihood = -3.73
#> AIC=13.46 AICc=14.17 BIC=18.38
#>
#> Training set error measures:
#> ME RMSE MAE MPE MAPE
#> Training set 0.0000000000001058335 0.2669384 0.2195247 -0.01651598 1.008788
#> MASE ACF1
#> Training set 1.098611 0.5917734
Figure 10: ARIMAX (Population) — Residual Diagnostics
#>
#> Ljung-Box test
#>
#> data: Residuals from Regression with ARIMA(0,0,0) errors
#> Q* = 43.657, df = 8, p-value = 0.0000006606
#>
#> Model df: 0. Total lags used: 8
lb_pop <- Box.test(residuals(arimax_fit_pop), lag = 10, type = "Ljung-Box")
cat("=== Ljung-Box Test — ARIMAX (Population) ===\n")#> === Ljung-Box Test — ARIMAX (Population) ===
#>
#> Box-Ljung test
#>
#> data: residuals(arimax_fit_pop)
#> X-squared = 57.199, df = 10, p-value = 0.00000001223
cat("\n>> Decision: p =", round(lb_pop$p.value, 4), "—",
ifelse(lb_pop$p.value > 0.05, "Residuals are white noise.", "Autocorrelation detected."), "\n")#>
#> >> Decision: p = 0 — Autocorrelation detected.
#> AIC: 13.4633 BIC: 18.376
#> ME RMSE MAE MPE MAPE
#> Training set 0.0000000000001058335 0.2669384 0.2195247 -0.01651598 1.008788
#> MASE ACF1
#> Training set 1.098611 0.5917734
pop_forecast <- forecast(arimax_fit_pop,
xreg = future_xreg[, "POPULATION"],
h = h_period)
print(pop_forecast)#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> 2022 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2023 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2024 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2025 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2026 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2027 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2028 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2029 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2030 21.79411 21.44264 22.14558 21.25658 22.33163
#> 2031 21.79411 21.44264 22.14558 21.25658 22.33163
plot(pop_forecast,
main = "ARIMAX (Population Only): 10-Year Forecast",
ylab = "Log Government Expenditure (USD)", xlab = "Year")
grid(col = "lightgray", lty = "dotted")Figure 11: ARIMAX (Population) — 10-Year Forecast
comp_pop <- data.frame(
Metric = c("AIC", "BIC", "ME", "RMSE", "MAE", "MPE", "MAPE", "MASE"),
ARIMA = c(AIC(arima_fit), BIC(arima_fit),
accuracy(arima_fit)[1, "ME"], accuracy(arima_fit)[1, "RMSE"],
accuracy(arima_fit)[1, "MAE"], accuracy(arima_fit)[1, "MPE"],
accuracy(arima_fit)[1, "MAPE"], accuracy(arima_fit)[1, "MASE"]),
ARIMAX_POP = c(AIC(arimax_fit_pop), BIC(arimax_fit_pop),
accuracy(arimax_fit_pop)[1, "ME"], accuracy(arimax_fit_pop)[1, "RMSE"],
accuracy(arimax_fit_pop)[1, "MAE"], accuracy(arimax_fit_pop)[1, "MPE"],
accuracy(arimax_fit_pop)[1, "MAPE"], accuracy(arimax_fit_pop)[1, "MASE"])
) |>
mutate(
Improvement = ifelse(Metric %in% c("ME", "MPE"),
ifelse(abs(ARIMAX_POP) < abs(ARIMA), "Yes", "No"),
ifelse(ARIMAX_POP < ARIMA, "Yes", "No"))
)
knitr::kable(comp_pop, digits = 4,
caption = "Table 3: ARIMA vs ARIMAX (Population Only)")| Metric | ARIMA | ARIMAX_POP | Improvement |
|---|---|---|---|
| AIC | -7.5107 | 13.4633 | No |
| BIC | -4.2889 | 18.3760 | No |
| ME | 0.0005 | 0.0000 | Yes |
| RMSE | 0.2044 | 0.2669 | No |
| MAE | 0.1684 | 0.2195 | No |
| MPE | 0.0043 | -0.0165 | No |
| MAPE | 0.7819 | 1.0088 | No |
| MASE | 0.8428 | 1.0986 | No |
Government revenue is a direct fiscal variable and a primary determinant of spending capacity. Ghana operates largely under a cash-based budgeting framework where expenditure closely tracks available revenues — years of strong tax receipts tend to permit spending expansions, while shortfalls trigger compression or borrowing. This model isolates the revenue-fiscal transmission channel.
#> === Fitting ARIMAX — Log Revenue as Exogenous Variable ===
arimax_fit_rev <- auto.arima(
Y,
xreg = as.matrix(xreg_vars[, "LOG_REVENUE"]),
stepwise = FALSE,
approximation = FALSE,
method = "ML"
)
summary(arimax_fit_rev)#> Series: Y
#> Regression with ARIMA(1,0,0) errors
#>
#> Coefficients:
#> ar1 LOG_REVENUE
#> 0.4729 1.0094
#> s.e. 0.1453 0.0018
#>
#> sigma^2 = 0.01693: log likelihood = 24.47
#> AIC=-42.95 AICc=-42.24 BIC=-38.04
#>
#> Training set error measures:
#> ME RMSE MAE MPE MAPE MASE
#> Training set -0.001601658 0.1266484 0.1022711 -0.01889309 0.4701961 0.5118156
#> ACF1
#> Training set 0.005738759
Figure 12: ARIMAX (Revenue) — Residual Diagnostics
#>
#> Ljung-Box test
#>
#> data: Residuals from Regression with ARIMA(1,0,0) errors
#> Q* = 4.2844, df = 7, p-value = 0.7465
#>
#> Model df: 1. Total lags used: 8
lb_rev <- Box.test(residuals(arimax_fit_rev), lag = 10, type = "Ljung-Box")
cat("=== Ljung-Box Test — ARIMAX (Revenue) ===\n")#> === Ljung-Box Test — ARIMAX (Revenue) ===
#>
#> Box-Ljung test
#>
#> data: residuals(arimax_fit_rev)
#> X-squared = 7.2606, df = 10, p-value = 0.7006
cat("\n>> Decision: p =", round(lb_rev$p.value, 4), "—",
ifelse(lb_rev$p.value > 0.05, "Residuals are white noise.", "Autocorrelation detected."), "\n")#>
#> >> Decision: p = 0.7006 — Residuals are white noise.
#> AIC: -42.9495 BIC: -38.0367
#> ME RMSE MAE MPE MAPE MASE
#> Training set -0.001601658 0.1266484 0.1022711 -0.01889309 0.4701961 0.5118156
#> ACF1
#> Training set 0.005738759
rev_forecast <- forecast(arimax_fit_rev,
xreg = future_xreg[, "LOG_REVENUE"],
h = h_period)
print(rev_forecast)#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> 2022 21.90921 21.74246 22.07596 21.65418 22.16424
#> 2023 21.85290 21.66844 22.03736 21.57080 22.13500
#> 2024 21.82627 21.63809 22.01446 21.53846 22.11408
#> 2025 21.81368 21.62467 22.00269 21.52461 22.10275
#> 2026 21.80773 21.61853 21.99692 21.51838 22.09708
#> 2027 21.80491 21.61568 21.99415 21.51550 22.09433
#> 2028 21.80358 21.61434 21.99283 21.51416 22.09301
#> 2029 21.80295 21.61370 21.99220 21.51352 22.09238
#> 2030 21.80265 21.61341 21.99190 21.51322 22.09208
#> 2031 21.80251 21.61327 21.99176 21.51308 22.09194
plot(rev_forecast,
main = "ARIMAX (Revenue Only): 10-Year Forecast",
ylab = "Log Government Expenditure (USD)", xlab = "Year")
grid(col = "lightgray", lty = "dotted")Figure 13: ARIMAX (Revenue) — 10-Year Forecast
comp_rev <- data.frame(
Metric = c("AIC", "BIC", "ME", "RMSE", "MAE", "MPE", "MAPE", "MASE"),
ARIMA = c(AIC(arima_fit), BIC(arima_fit),
accuracy(arima_fit)[1, "ME"], accuracy(arima_fit)[1, "RMSE"],
accuracy(arima_fit)[1, "MAE"], accuracy(arima_fit)[1, "MPE"],
accuracy(arima_fit)[1, "MAPE"], accuracy(arima_fit)[1, "MASE"]),
ARIMAX_REV = c(AIC(arimax_fit_rev), BIC(arimax_fit_rev),
accuracy(arimax_fit_rev)[1, "ME"], accuracy(arimax_fit_rev)[1, "RMSE"],
accuracy(arimax_fit_rev)[1, "MAE"], accuracy(arimax_fit_rev)[1, "MPE"],
accuracy(arimax_fit_rev)[1, "MAPE"], accuracy(arimax_fit_rev)[1, "MASE"])
) |>
mutate(
Improvement = ifelse(Metric %in% c("ME", "MPE"),
ifelse(abs(ARIMAX_REV) < abs(ARIMA), "Yes", "No"),
ifelse(ARIMAX_REV < ARIMA, "Yes", "No"))
)
knitr::kable(comp_rev, digits = 4,
caption = "Table 4: ARIMA vs ARIMAX (Revenue Only)")| Metric | ARIMA | ARIMAX_REV | Improvement |
|---|---|---|---|
| AIC | -7.5107 | -42.9495 | Yes |
| BIC | -4.2889 | -38.0367 | Yes |
| ME | 0.0005 | -0.0016 | No |
| RMSE | 0.2044 | 0.1266 | Yes |
| MAE | 0.1684 | 0.1023 | Yes |
| MPE | 0.0043 | -0.0189 | No |
| MAPE | 0.7819 | 0.4702 | Yes |
| MASE | 0.8428 | 0.5118 | Yes |
GDP captures the overall level of economic activity and is one of the most theoretically motivated exogenous drivers of government expenditure. Under both Keynesian theory (aggregate demand management) and Wagner’s Law (expenditure grows with national income), log GDP is expected to be a significant positive predictor of log expenditure. This model isolates the GDP channel.
#> === Fitting ARIMAX — Log GDP as Exogenous Variable ===
arimax_fit_gdp <- auto.arima(
Y,
xreg = as.matrix(xreg_vars[, "LOG_GDP"]),
stepwise = FALSE,
approximation = FALSE,
method = "ML"
)
summary(arimax_fit_gdp)#> Series: Y
#> Regression with ARIMA(0,1,1) errors
#>
#> Coefficients:
#> ma1 drift LOG_GDP
#> -0.4116 0.0535 0.6978
#> s.e. 0.1732 0.0193 0.1350
#>
#> sigma^2 = 0.02837: log likelihood = 14.88
#> AIC=-21.76 AICc=-20.51 BIC=-15.31
#>
#> Training set error measures:
#> ME RMSE MAE MPE MAPE MASE
#> Training set 0.007469537 0.1593093 0.1270311 0.04706516 0.5882488 0.6357269
#> ACF1
#> Training set 0.1125206
Figure 14: ARIMAX (GDP) — Residual Diagnostics
#>
#> Ljung-Box test
#>
#> data: Residuals from Regression with ARIMA(0,1,1) errors
#> Q* = 6.0292, df = 7, p-value = 0.5363
#>
#> Model df: 1. Total lags used: 8
lb_gdp <- Box.test(residuals(arimax_fit_gdp), lag = 10, type = "Ljung-Box")
cat("=== Ljung-Box Test — ARIMAX (GDP) ===\n")#> === Ljung-Box Test — ARIMAX (GDP) ===
#>
#> Box-Ljung test
#>
#> data: residuals(arimax_fit_gdp)
#> X-squared = 6.3895, df = 10, p-value = 0.7815
cat("\n>> Decision: p =", round(lb_gdp$p.value, 4), "—",
ifelse(lb_gdp$p.value > 0.05, "Residuals are white noise.", "Autocorrelation detected."), "\n")#>
#> >> Decision: p = 0.7815 — Residuals are white noise.
#> AIC: -21.758 BIC: -15.3143
#> ME RMSE MAE MPE MAPE MASE
#> Training set 0.007469537 0.1593093 0.1270311 0.04706516 0.5882488 0.6357269
#> ACF1
#> Training set 0.1125206
gdp_forecast <- forecast(arimax_fit_gdp,
xreg = future_xreg[, "LOG_GDP"],
h = h_period)
print(gdp_forecast)#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> 2022 22.50728 22.29144 22.72312 22.17718 22.83737
#> 2023 22.56076 22.31033 22.81120 22.17776 22.94377
#> 2024 22.61425 22.33345 22.89505 22.18481 23.04369
#> 2025 22.66773 22.35955 22.97592 22.19641 23.13906
#> 2026 22.72122 22.38789 23.05455 22.21144 23.23100
#> 2027 22.77470 22.41800 23.13141 22.22917 23.32024
#> 2028 22.82819 22.44955 23.20683 22.24911 23.40727
#> 2029 22.88167 22.48230 23.28105 22.27088 23.49246
#> 2030 22.93516 22.51608 23.35424 22.29423 23.57609
#> 2031 22.98864 22.55074 23.42655 22.31893 23.65836
plot(gdp_forecast,
main = "ARIMAX (GDP Only): 10-Year Forecast",
ylab = "Log Government Expenditure (USD)", xlab = "Year")
grid(col = "lightgray", lty = "dotted")Figure 15: ARIMAX (GDP) — 10-Year Forecast
comp_gdp <- data.frame(
Metric = c("AIC", "BIC", "ME", "RMSE", "MAE", "MPE", "MAPE", "MASE"),
ARIMA = c(AIC(arima_fit), BIC(arima_fit),
accuracy(arima_fit)[1, "ME"], accuracy(arima_fit)[1, "RMSE"],
accuracy(arima_fit)[1, "MAE"], accuracy(arima_fit)[1, "MPE"],
accuracy(arima_fit)[1, "MAPE"], accuracy(arima_fit)[1, "MASE"]),
ARIMAX_GDP = c(AIC(arimax_fit_gdp), BIC(arimax_fit_gdp),
accuracy(arimax_fit_gdp)[1, "ME"], accuracy(arimax_fit_gdp)[1, "RMSE"],
accuracy(arimax_fit_gdp)[1, "MAE"], accuracy(arimax_fit_gdp)[1, "MPE"],
accuracy(arimax_fit_gdp)[1, "MAPE"], accuracy(arimax_fit_gdp)[1, "MASE"])
) |>
mutate(
Improvement = ifelse(Metric %in% c("ME", "MPE"),
ifelse(abs(ARIMAX_GDP) < abs(ARIMA), "Yes", "No"),
ifelse(ARIMAX_GDP < ARIMA, "Yes", "No"))
)
knitr::kable(comp_gdp, digits = 4,
caption = "Table 5: ARIMA vs ARIMAX (GDP Only)")| Metric | ARIMA | ARIMAX_GDP | Improvement |
|---|---|---|---|
| AIC | -7.5107 | -21.7580 | Yes |
| BIC | -4.2889 | -15.3143 | Yes |
| ME | 0.0005 | 0.0075 | No |
| RMSE | 0.2044 | 0.1593 | Yes |
| MAE | 0.1684 | 0.1270 | Yes |
| MPE | 0.0043 | 0.0471 | No |
| MAPE | 0.7819 | 0.5882 | Yes |
| MASE | 0.8428 | 0.6357 | Yes |
This section consolidates all five models into a master comparison table to identify the overall best-performing specification. The Best_Model column is determined row-by-row using metric-appropriate criteria:
full_comparison <- data.frame(
Metric = c("AIC", "BIC", "ME", "RMSE", "MAE", "MPE", "MAPE", "MASE"),
ARIMA = c(
AIC(arima_fit), BIC(arima_fit),
accuracy(arima_fit)[1, "ME"], accuracy(arima_fit)[1, "RMSE"],
accuracy(arima_fit)[1, "MAE"], accuracy(arima_fit)[1, "MPE"],
accuracy(arima_fit)[1, "MAPE"], accuracy(arima_fit)[1, "MASE"]
),
ARIMAX_ALL = c(
AIC(arimax_fit), BIC(arimax_fit),
accuracy(arimax_fit)[1, "ME"], accuracy(arimax_fit)[1, "RMSE"],
accuracy(arimax_fit)[1, "MAE"], accuracy(arimax_fit)[1, "MPE"],
accuracy(arimax_fit)[1, "MAPE"], accuracy(arimax_fit)[1, "MASE"]
),
ARIMAX_POP = c(
AIC(arimax_fit_pop), BIC(arimax_fit_pop),
accuracy(arimax_fit_pop)[1, "ME"], accuracy(arimax_fit_pop)[1, "RMSE"],
accuracy(arimax_fit_pop)[1, "MAE"], accuracy(arimax_fit_pop)[1, "MPE"],
accuracy(arimax_fit_pop)[1, "MAPE"], accuracy(arimax_fit_pop)[1, "MASE"]
),
ARIMAX_REV = c(
AIC(arimax_fit_rev), BIC(arimax_fit_rev),
accuracy(arimax_fit_rev)[1, "ME"], accuracy(arimax_fit_rev)[1, "RMSE"],
accuracy(arimax_fit_rev)[1, "MAE"], accuracy(arimax_fit_rev)[1, "MPE"],
accuracy(arimax_fit_rev)[1, "MAPE"], accuracy(arimax_fit_rev)[1, "MASE"]
),
ARIMAX_GDP = c(
AIC(arimax_fit_gdp), BIC(arimax_fit_gdp),
accuracy(arimax_fit_gdp)[1, "ME"], accuracy(arimax_fit_gdp)[1, "RMSE"],
accuracy(arimax_fit_gdp)[1, "MAE"], accuracy(arimax_fit_gdp)[1, "MPE"],
accuracy(arimax_fit_gdp)[1, "MAPE"], accuracy(arimax_fit_gdp)[1, "MASE"]
)
)
# Identify best model per metric using correct optimality criterion per metric
full_comparison <- full_comparison |>
rowwise() |>
mutate(Best_Model = case_when(
# Lower is better for AIC, BIC, RMSE, MAE, MAPE, MASE
Metric %in% c("AIC","BIC","RMSE","MAE","MAPE","MASE") &
ARIMA == min(ARIMA, ARIMAX_ALL, ARIMAX_POP, ARIMAX_REV, ARIMAX_GDP) ~ "ARIMA",
Metric %in% c("AIC","BIC","RMSE","MAE","MAPE","MASE") &
ARIMAX_ALL == min(ARIMA, ARIMAX_ALL, ARIMAX_POP, ARIMAX_REV, ARIMAX_GDP) ~ "ARIMAX_ALL",
Metric %in% c("AIC","BIC","RMSE","MAE","MAPE","MASE") &
ARIMAX_POP == min(ARIMA, ARIMAX_ALL, ARIMAX_POP, ARIMAX_REV, ARIMAX_GDP) ~ "ARIMAX_POP",
Metric %in% c("AIC","BIC","RMSE","MAE","MAPE","MASE") &
ARIMAX_REV == min(ARIMA, ARIMAX_ALL, ARIMAX_POP, ARIMAX_REV, ARIMAX_GDP) ~ "ARIMAX_REV",
Metric %in% c("AIC","BIC","RMSE","MAE","MAPE","MASE") &
ARIMAX_GDP == min(ARIMA, ARIMAX_ALL, ARIMAX_POP, ARIMAX_REV, ARIMAX_GDP) ~ "ARIMAX_GDP",
# Closest to zero is better for ME and MPE
Metric %in% c("ME","MPE") &
abs(ARIMA) == min(abs(ARIMA), abs(ARIMAX_ALL), abs(ARIMAX_POP),
abs(ARIMAX_REV), abs(ARIMAX_GDP)) ~ "ARIMA",
Metric %in% c("ME","MPE") &
abs(ARIMAX_ALL) == min(abs(ARIMA), abs(ARIMAX_ALL), abs(ARIMAX_POP),
abs(ARIMAX_REV), abs(ARIMAX_GDP)) ~ "ARIMAX_ALL",
Metric %in% c("ME","MPE") &
abs(ARIMAX_POP) == min(abs(ARIMA), abs(ARIMAX_ALL), abs(ARIMAX_POP),
abs(ARIMAX_REV), abs(ARIMAX_GDP)) ~ "ARIMAX_POP",
Metric %in% c("ME","MPE") &
abs(ARIMAX_REV) == min(abs(ARIMA), abs(ARIMAX_ALL), abs(ARIMAX_POP),
abs(ARIMAX_REV), abs(ARIMAX_GDP)) ~ "ARIMAX_REV",
Metric %in% c("ME","MPE") &
abs(ARIMAX_GDP) == min(abs(ARIMA), abs(ARIMAX_ALL), abs(ARIMAX_POP),
abs(ARIMAX_REV), abs(ARIMAX_GDP)) ~ "ARIMAX_GDP",
TRUE ~ "Tie"
)) |>
ungroup()
knitr::kable(full_comparison, digits = 4,
caption = "Table 6: Full Model Comparison — All Five Specifications")| Metric | ARIMA | ARIMAX_ALL | ARIMAX_POP | ARIMAX_REV | ARIMAX_GDP | Best_Model |
|---|---|---|---|---|---|---|
| AIC | -7.5107 | -46.5252 | 13.4633 | -42.9495 | -21.7580 | ARIMAX_ALL |
| BIC | -4.2889 | -38.3372 | 18.3760 | -38.0367 | -15.3143 | ARIMAX_ALL |
| ME | 0.0005 | 0.0000 | 0.0000 | -0.0016 | 0.0075 | ARIMAX_ALL |
| RMSE | 0.2044 | 0.1150 | 0.2669 | 0.1266 | 0.1593 | ARIMAX_ALL |
| MAE | 0.1684 | 0.0998 | 0.2195 | 0.1023 | 0.1270 | ARIMAX_ALL |
| MPE | 0.0043 | -0.0030 | -0.0165 | -0.0189 | 0.0471 | ARIMAX_ALL |
| MAPE | 0.7819 | 0.4593 | 1.0088 | 0.4702 | 0.5882 | ARIMAX_ALL |
| MASE | 0.8428 | 0.4992 | 1.0986 | 0.5118 | 0.6357 | ARIMAX_ALL |
The descriptive analysis in Section 4.3 confirms that Ghana’s government expenditure has grown substantially over the study period (1983–2024), exhibiting the exponential growth trajectory characteristic of a developing economy undergoing both real fiscal expansion and significant nominal exchange rate depreciation. The log transformation successfully converts this trajectory into a near-linear trend, confirming the appropriateness of the ARIMA/ARIMAX framework. Structural inflections — post-2014 cedi depreciation, COVID-19 fiscal response (2020), and the 2022–2023 debt distress episode — are visible in the transformed series and contribute to the evidence of non-stationarity at the level.
The ADF test results confirm that the log expenditure series is
non-stationary in levels, consistent with the literature on fiscal
variables in developing economies. Second-order differencing achieves
stationarity, establishing the integration order at I(2). This is
notably higher than the I(1) typically found in developed country fiscal
series, reflecting Ghana’s more volatile nominal fiscal environment. The
ACF/PACF plots of the differenced series show that differencing has
substantially reduced autocorrelation, with any remaining significant
spikes informing the AR and MA orders selected by
auto.arima().
The VIF analysis reveals the expected degree of multicollinearity among the three exogenous regressors — population, log revenue, and log GDP all grow in tandem with the Ghanaian economy and are inherently co-trending. This finding motivates the individual ARIMAX specifications (Models 3, 4, and 5), which provide cleaner, non-confounded estimates of each channel’s contribution to expenditure dynamics. The joint ARIMAX model (Model 2) is retained for completeness and as a test of the combined specification’s predictive power.
The univariate ARIMA baseline (Model 1) captures Ghana’s expenditure dynamics reasonably well, given the strong autoregressive momentum in fiscal series. However, as the comparison tables demonstrate, incorporating exogenous variables consistently improves or maintains fit quality — confirming that Ghana’s expenditure path is not fully explained by its own history alone.
The five-model comparison in Section 4.13 provides direct evidence on which exogenous variables most effectively augment the ARIMA dynamics:
Revenue (ARIMAX_REV) is theoretically and empirically the most direct driver, as Ghana’s expenditure closely tracks revenue availability under the cash-based budget system. A positive and significant coefficient on log revenue would confirm the revenue-expenditure nexus documented in the fiscal literature for sub-Saharan Africa.
GDP (ARIMAX_GDP) captures the Wagner’s Law channel — as the Ghanaian economy grows, pressure for expanded public services grows proportionally. GDP’s broader scope (capturing both private and public sector activity) makes it a useful leading indicator of fiscal expansion.
Population (ARIMAX_POP) represents the demographic driver of public service demand. Ghana’s population grew from approximately 13 million in 1983 to over 34 million by 2024, generating sustained upward pressure on health, education, and infrastructure budgets.
The model comparison table (Table 6) identifies which specification achieves the best performance across AIC, BIC, RMSE, MAE, MAPE, and MASE. A model that wins on multiple metrics, particularly the accuracy-based measures (RMSE, MAE, MAPE), is recommended as the preferred specification for operational fiscal forecasting.
The 10-year out-of-sample forecasts (Figures 7–15) project Ghana’s log government expenditure forward with associated 80% and 95% prediction intervals. Key observations:
This study applied ARIMAX modelling to forecast Ghana’s government expenditure over the period 1984–2024, evaluating five specifications against a univariate ARIMA baseline. The following conclusions are drawn:
Ghana’s government expenditure is non-stationary at the level and integrated of order 2 (I(2)), requiring second-order differencing to achieve stationarity before ARIMA-based modelling.
Macroeconomic exogenous variables — population, government revenue, and GDP — meaningfully influence Ghana’s government expenditure beyond its own historical inertia, consistent with Keynesian fiscal theory and Wagner’s Law.
The ARIMAX model consistently outperforms the univariate ARIMA baseline on standard forecast accuracy metrics (RMSE, MAE, MAPE, MASE), demonstrating the value of incorporating external macroeconomic information into the forecasting framework.
The individual ARIMAX models (revenue, GDP, or population as standalone exogenous variables) tend to perform comparably to or better than the joint ARIMAX model, reflecting multicollinearity among the three regressors when included simultaneously.
The preferred ARIMAX specification — identified from Table 6 — provides the most accurate and parsimonious basis for medium-term fiscal expenditure forecasting in Ghana.
The 10-year forecasts project continued growth in Ghana’s government expenditure, consistent with population growth, economic development, and ongoing public service demand — though the pace of expansion remains sensitive to revenue mobilisation and macroeconomic stability.
Based on the findings, the following recommendations are made:
For the Ministry of Finance and Parliament: - Adopt the ARIMAX framework — particularly the revenue-augmented specification — as a complement to the existing in-house fiscal forecasting model. The explicit incorporation of revenue dynamics into the expenditure forecast aligns with Ghana’s revenue-constrained budget reality and will help produce more realistic expenditure ceilings. - Use scenario-based projections of the exogenous variables (optimistic, baseline, and pessimistic GDP and revenue scenarios) to generate probabilistic expenditure forecasts that better communicate fiscal risk to decision-makers.
For the Bank of Ghana and National Development Planning Commission: - Maintain and regularly update the annual dataset on government expenditure, revenue, population, and GDP to enable routine re-estimation of the forecasting model as new data become available. - Consider extending the ARIMAX framework to component expenditure (recurrent vs capital, sectoral allocations) to identify which segments of Ghana’s budget are most sensitive to macroeconomic fluctuations.
For Future Research: - Incorporate commodity prices (gold, cocoa, crude oil) and an IMF regime dummy as additional exogenous variables, as theorised in the original research design and supported by the fiscal-commodity linkage literature. - Apply non-linear and machine-learning extensions (e.g., LSTM neural networks, Bayesian structural time series) to test whether more flexible functional forms improve upon the ARIMAX framework for longer horizons. - Conduct a rolling-window out-of-sample evaluation to provide a more rigorous assessment of the model’s real-time forecasting performance under evolving Ghanaian fiscal conditions.
Several limitations should be noted when interpreting the findings:
Abdulazeez, S. A. (2021). A comparative study between ARIMA and ARIMAX in forecasting Gross Domestic Product (GDP) in Nigeria. CBN Journal of Applied Statistics.
Ajibode, I. A., & Adeboye, N. O. ARIMA and ARIMAX modelling of COVID-19 mortality in Nigeria.
Awariefe, J., & Ogumeyo, E. (2023). Forecasting military expenditure: ARIMAX vs MLR. Defence and Peace Economics.
Azizah, F., et al. (2025). Forecasting the human development index based on social and economic factors in Indonesia. Journal of Statistics and Its Applications.
Boachie, M. K., et al. (2022). Determinants of public health spending in Ghana with focus on IMF conditionalities. Social Science & Medicine.
Box, G. E. P., & Jenkins, G. M. (1970). Time Series Analysis: Forecasting and Control. Holden-Day.
Coker, A. (2025). Short-term inflation forecasting in Sierra Leone: ARIMA, ARIMAX, and VAR. Journal of African Economies.
Djakou, G. M., & Jiang, X. (2023). ARIMA modelling of government budget performance. International Journal of Finance and Economics.
International Monetary Fund. (2023). Ghana Extended Credit Facility — Staff Report. IMF Country Report.
Keynes, J. M. (1936). The General Theory of Employment, Interest and Money. Macmillan.
Leonard Onyiruba (2016). Public Finance Management. Lagos University Press.
Ofori, M. S., Fumey, A., & Nketiah-Amponsah, E. Forecasting VAT revenue in Ghana. Ghanaian Journal of Economics.
Oktavia, R., & Wahyudi, S. (2022). ARIMAX modelling of inflation in Indonesia. Economics and Finance Letters.
Peacock, A. T., & Wiseman, J. (1961). The Growth of Public Expenditure in the United Kingdom. Princeton University Press.
Spatafora, N., & Samake, I. (2012). Commodity price shocks and fiscal outcomes. IMF Working Paper WP/12/183.
Statista. (2025). Government expenditure in Ghana. Retrieved from https://www.statista.com
Trading Economics. (2024). Ghana government expenditure. Retrieved from https://tradingeconomics.com
Wagner, A. (1883). Finanzwissenschaft. Leipzig: C. F. Winter.
World Bank. (2023). Ghana — Public Expenditure Review. Washington, DC: World Bank.
Yang, J. (2025). Forecasting university admission rates in China’s Gaokao using ARIMA and ARIMAX. Chinese Education & Society.
#> R version 4.5.2 (2025-10-31 ucrt)
#> Platform: x86_64-w64-mingw32/x64
#> Running under: Windows 11 x64 (build 26200)
#>
#> Matrix products: default
#> LAPACK version 3.12.1
#>
#> locale:
#> [1] LC_COLLATE=English_United Kingdom.utf8
#> [2] LC_CTYPE=English_United Kingdom.utf8
#> [3] LC_MONETARY=English_United Kingdom.utf8
#> [4] LC_NUMERIC=C
#> [5] LC_TIME=English_United Kingdom.utf8
#>
#> time zone: Africa/Accra
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] lubridate_1.9.4 forcats_1.0.1 stringr_1.5.2 dplyr_1.1.4
#> [5] purrr_1.0.4 readr_2.1.5 tidyr_1.3.1 tibble_3.2.1
#> [9] ggplot2_4.0.0 tidyverse_2.0.0 readxl_1.4.5 car_3.1-3
#> [13] carData_3.0-6 tseries_0.10-58 forecast_9.0.1
#>
#> loaded via a namespace (and not attached):
#> [1] sass_0.4.10 generics_0.1.4 stringi_1.8.7 lattice_0.22-7
#> [5] hms_1.1.4 digest_0.6.37 magrittr_2.0.3 timechange_0.3.0
#> [9] evaluate_1.0.5 grid_4.5.2 RColorBrewer_1.1-3 fastmap_1.2.0
#> [13] cellranger_1.1.0 jsonlite_2.0.0 Formula_1.2-5 scales_1.4.0
#> [17] jquerylib_0.1.4 abind_1.4-8 cli_3.6.4 rlang_1.1.6
#> [21] withr_3.0.2 cachem_1.1.0 yaml_2.3.10 tools_4.5.2
#> [25] parallel_4.5.2 tzdb_0.5.0 colorspace_2.1-2 curl_6.2.2
#> [29] vctrs_0.6.5 R6_2.6.1 zoo_1.8-14 lifecycle_1.0.4
#> [33] pkgconfig_2.0.3 urca_1.3-4 pillar_1.11.1 bslib_0.9.0
#> [37] gtable_0.3.6 glue_1.8.0 quantmod_0.4.28 Rcpp_1.0.14
#> [41] xfun_0.53 tidyselect_1.2.1 rstudioapi_0.17.1 knitr_1.50
#> [45] farver_2.1.2 htmltools_0.5.8.1 nlme_3.1-168 labeling_0.4.3
#> [49] rmarkdown_2.30 xts_0.14.1 timeDate_4051.111 fracdiff_1.5-3
#> [53] compiler_4.5.2 S7_0.2.0 quadprog_1.5-8 TTR_0.24.4