# 9 Predictive Modelling and Beyond

Learning Objectives

- How to use models’ predictions on new data
- Time series analysis
- Mixed models

In the dynamic landscape of public health, the ability to forecast and predict future trends is essential for effective decision-making and the implementation of timely interventions. This chapter provides an overview of **predictive modelling**, focusing on the challenges of applying predictions to new data, the use of **time series analysis**, and **mixed models** to anticipate the trajectory of infectious diseases and health metrics. By exploring the underlying patterns and analyzing historical data, we estimate the disease burden and evaluate the impact of interventions on population health. We demonstrate how time series analysis and mixed models can be tailored to address specific research questions, such as predicting disease outbreaks, estimating disease burden, and assessing the impact of interventions on population health.

## 9.1 Predictions About the Future

The previous chapters provided an attempt at estimating future outcomes based on the application of various type of statistical and machine learning techniques. Here we look at how to use these predictions on new data.

When making predictions on new data, it is important to consider the **generalizability** of the model. A model that performs well on the training data may not necessarily generalize well to new, unseen data. To evaluate the performance of the model we used the **cross-validation** technique, but there are more such as **hold-out validation**, **k-fold cross-validation**, **leave-one-out cross-validation**, and **bootstrapping**. These methods help assess the model’s ability to make accurate predictions on data not used during training, providing a more reliable estimate of the model’s performance in real-world scenarios.

Once the model has been trained and evaluated, it is used to make predictions on new data. This process involves applying the model to the new data to generate forecasts or estimates of the outcome of interest. For example, in the case of infectious diseases, predictive models can be used to forecast the trajectory of an outbreak, estimate the number of cases, or evaluate the impact of interventions on disease transmission. By leveraging historical data and the insights gained from the model, we can effectively evaluate the model performance and make informed decisions based on the predictions.

## 9.2 Example: Dengue Test Predictions for 2017-2021

**Predictive modelling** is a powerful tool for forecasting future trends. Here we test the Dengue’s model made with mlr3 meta-package in Chapter 8. The model was trained on data from 1990 to 2016 and now tested for years 2017 to 2021.

First we load the original data and name it `old_data`

.

Then, we load Dengue data from 2017 to 2021 and name it `new_data`

.

In the next step, we use the trained models from Chapter 8 to make predictions on the new data. The predictions are stored in `new_pred_regr.cv_glmnet`

and `new_pred_regr.xgboost`

. The resampling results: `rr1$learners`

and `rr2$learners`

, contain the trained models, in particular the first of 5 folds cross validation sample is used for the predictions.

```
new_pred_regr.cv_glmnet <-
rr1$learners[[1]]$predict_newdata(new_data, task = rr1$task)
```

We notice that the models are doing well, when old data is compared to the new data. The predictions are close to the actual values. Much more can be done to improve the models, such as **hyperparameter tuning**, **feature engineering**, and **model ensembles**, but this is a good point to start. We could also look at the confidence intervals of the predictions, to see how certain we are about the predictions, and so on.

This is the result of the `cv_glmnet`

application on new data:

```
regr.cv_glmnet_new <- as.data.table(new_pred_regr.cv_glmnet) %>%
mutate(learner = "regr.cv_glmnet") %>%
cbind(new_data)
regr.cv_glmnet_new %>%
ggplot(aes(x = year)) +
geom_line(data=old_data,aes(y = DALYs))+
geom_line(aes(y = DALYs),color="brown") +
geom_line(aes(y = response), linetype="dashed") +
facet_wrap(vars(location_id),
labeller = as_labeller(c(`182` = "Malawi",
`191` = "Zambia",
`169` = "Central African Republic")),
scales = "free_y") +
labs(title = "Dengue Predictions for 2017-2021: cv_glmnet")
```

The same steps are taken for the `xgboost`

, and the result is shown below.

```
new_pred_regr.xgboost <-
rr2$learners[[1]]$predict_newdata(new_data, task = rr2$task)
```

```
regr.xgboost_new <- as.data.table(new_pred_regr.xgboost) %>%
mutate(learner = "regr.xgboost") %>%
cbind(new_data)
regr.xgboost_new %>%
ggplot(aes(x = year)) +
geom_line(data=old_data,aes(y = DALYs))+
geom_line(aes(y = DALYs),color="brown") +
geom_line(aes(y = response), linetype="dashed") +
facet_wrap(vars(location_id),
labeller = as_labeller(c(`182` = "Malawi",
`191` = "Zambia",
`169` = "Central African Republic")),
scales = "free_y") +
labs(title = "Dengue Predictions for 2017-2021: xgboost")
```

In conclusion, predictive modelling is a valuable tool for forecasting future trends and making informed decisions based on historical data. By leveraging the insights gained from the models, we can anticipate the trajectory of infectious diseases, estimate disease burden, and evaluate the impact of interventions on population health. The models can be further refined and optimized to improve their predictive performance and provide more accurate forecasts. By combining predictive modelling with time series analysis and mixed models, we can gain a comprehensive understanding of the complex dynamics of public health and make data-driven decisions to improve population health outcomes.

## 9.3 Time Series Analysis

One important side of the analysis is that to consider the evolution of the phenomenon in time. We can do this by using time as a factor in the model. **Time series** analysis serves as a tool for understanding and forecasting temporal patterns. Techniques such as **ARIMA (AutoRegressive Integrated Moving Average)** models offer a systematic approach to modelling time-dependent data, capturing seasonal variations, trends, and irregularities to generate accurate forecasts.

**Mixed models**, on the other side, provide a versatile framework for incorporating various sources of variability and correlation within the data. Also known as **hierarchical models**, **multilevel models**, or **random effects models**, are a type of statistical model that include both fixed effects and random effects. By combining fixed effects with random effects, mixed models accommodate complex data structures, such as hierarchical or longitudinal data, while accounting for individual-level and group-level factors that may influence the outcome of interest.

To analyze temporal data, where observations are collected at regular intervals over time, time series analysis allows for studying the patterns, trends, and dependencies present in the data to make forecasts or infer relationships. Time series data often exhibit inherent characteristics such as trend, seasonality, cyclic patterns, and irregular fluctuations, which can be explored using various methods such as **decomposition**, **smoothing**, and **modelling**. This analysis is widely used in fields like economics, finance, epidemiology, and environmental science to understand and predict future trends, identify anomalies, and make informed decisions based on historical patterns.

**Decomposition methods** play a crucial role by pulling out the underlying structure of temporal data. The components of a time series are `trend`

, `seasonality`

, and `random fluctuations`

. Understanding the trend allows for the identification of long-term changes or shifts in the data, while detecting seasonal patterns helps uncover recurring fluctuations that may follow seasonal or cyclical patterns. By separating these components, through decomposition methods, it is possible to discover the temporal dynamics within the data, facilitating more accurate forecasting and predictive modelling. Moreover, decomposing time series data can aid in anomaly detection, trend analysis, and seasonal adjustment, making it fundamental tool for interpreting complex temporal phenomena.

Modelling time series data often requires a combination of techniques to capture its complex nature. **Mixed models**, **splines**, and **ARIMA** are powerful tools commonly used for this purpose. Splines provide a flexible way to capture nonlinear relationships and smooth out the data, which is particularly useful for capturing trends or seasonal patterns. ARIMA models, on the other hand, are adept at capturing the autocorrelation structure present in the data, including both short-term and long-term dependencies.

Time series analysis can also be performed on estimated values produced by a machine learning model. This involves using vectors of estimates, actual values (ground truth), and time (such as years) to apply a time series model. By incorporating these elements, the time series analysis can help identify trends, seasonal patterns, and other temporal structures within the data. This approach enhances the robustness and accuracy of the predictions by combining the strengths of machine learning models with traditional time series techniques.

## 9.4 Example: SDI Time Series Analysis with Mixed Effect Models

From forecasting the trajectory of emerging pathogens to evaluating the long-term implications of public health policies, predictive modelling offers valuable insights into the future of global health. As seen in Chapter 5, the consideration of other factors such as the **Social Demographic Index (SDI)** can provide a comprehensive understanding of the impact social and economic determinants can have on health outcomes.

As an index, SDI is composed of the geometric mean of the total fertility rate (TFR) for those younger than 25 years old (TFU25), the mean education for those 15 years old and older (EDU15+), and lag-distributed income (LDI) per capita. It ranges from 0 to 1 but it is usually multiplied by 100 for a scale of 0 to 100.

**Standard Calculation of TFR**

\text{TFR} = \sum (\text{ASFR}_i \times 5) \tag{9.1}

where \text{ASFR}_i represents the age-specific fertility rates for age group i , and the sum is typically calculated over all childbearing age groups (often 5-year intervals from ages 15-49).

**Standard Calculation of SDI**

The SDI is calculated as the geometric mean of these three components:

SDI = \sqrt[3]{TFU25 \times EDU15+ \times LDI} \tag{9.2}

Each component (TFU25, EDU15+, and LDI) is normalized before taking the geometric mean to ensure they are on a comparable scale.

In summary, the TFR formula is specific to calculating fertility rates, while the SDI formula incorporates a specific subset of the TFR (TFU25) along with education and income metrics to create a broader socio-demographic index.

In general, the level of this index helps identify key drivers in the development of health outcomes. SDI can be used as a predictor in predictive models to estimate the burden of diseases, mortality rates, and other health metrics. For example, the relationship between SDI and the incidence of a disease can be modeled using a logistic regression model:

\log \left( \frac{p}{1 - p} \right) = \beta_0 + \beta_1 \times \text{SDI} + \beta_2 \times X_2 + \cdots + \beta_k \times X_k \tag{9.3}

Where, p is the probability of the incidence of the disease, \log \left( \frac{p}{1 - p} \right) is the log-odds (logit) of the disease incidence, \beta_0 is the intercept term, \beta_1, \beta_2, \ldots, \beta_k are the coefficients for the predictor variables, and X_2, \ldots, X_k are other potential predictor variables that might influence the disease incidence.

To convert the `log-odds`

back to the probability of disease incidence given the value of SDI:

p = \frac{1}{1 + e^{-(\beta_0 + \beta_1 \times \text{SDI})}} \tag{9.4}

In this example we use the SDI values from 1990 to 2019, for 3 location plus the Global region and evaluate the difference in SDI average across the time.

```
sdi90_19 |>
filter(location %in% c("Global", "Italy",
"France", "Germany")) |>
ggplot(aes(x = year, y = value,
linetype = location)) +
geomtextpath::geom_textline(aes(label = location),
hjust = 0, vjust = 0) +
labs(title = "Social Demographic Index (SDI) from 1990 to 2019")+
theme(legend.position = "none")
```

Then selecting only France as location to analyze the time series using spline interpolation and ARIMA(1,0,0), we can decompose the time series into its components and analyze the autocorrelation function.

```
library(tsibble)
sdi_fr_ts <- tsibble::as_tsibble(sdi_fr, index = year)
sdi_fr_ts |> autoplot()
```

```
dcmp <- sdi_fr_ts |>
model(stl = STL(value))
components(dcmp) |> head()
#> # A dable: 6 x 6 [1Y]
#> # Key: .model [1]
#> # : value = trend + remainder
#> .model year value trend remainder season_adjust
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 stl 1990 0.738 0.738 -0.000400 0.738
#> 2 stl 1991 0.743 0.744 -0.000560 0.743
#> 3 stl 1992 0.75 0.749 0.00128 0.75
#> 4 stl 1993 0.755 0.754 0.00136 0.755
#> 5 stl 1994 0.759 0.758 0.000800 0.759
#> 6 stl 1995 0.763 0.762 0.000680 0.763
```

“…three types of time series patterns: trend, seasonality and cycles. When we decompose a time series into components, we usually combine the trend and cycle into a single trend-cycle component (often just called the trend for simplicity). Thus we can think of a time series as comprising three components: a trend-cycle component, a seasonal component, and a remainder component (containing anything else in the time series).

Rob J Hyndman”

y_t=S_t+T_t+R_t \tag{9.5} y_t=S_t*T_t*R_t \tag{9.6} log(y_t)=log(S_t)+log(T_t)+log(R_t) \tag{9.7}

The **remainder** component shown in the bottom panel is what is left over when the seasonal and trend-cycle components have been subtracted from the data.

```
components(dcmp) |> autoplot()
components(dcmp) |>
as_tsibble() |>
autoplot(value) +
geom_line(aes(y = trend),
linetype="dashed")+
labs(title = "Trend line of SDI in France")
```

### 9.4.1 Autocorrelation function

Time series that show *no autocorrelation* are called white noise. In this case we have autocorrelation. So, no white noise.

```
sdi_fr_ts |>
ACF(value) |>
autoplot()
```

```
sdi_fr_ts |>
features(value,
features = unitroot_kpss)
#> # A tibble: 1 × 2
#> kpss_stat kpss_pvalue
#> <dbl> <dbl>
#> 1 1.09 0.01
```

Seasonal difference is not required

```
sdi_fr_ts |>
features(value,
features = unitroot_nsdiffs)
#> # A tibble: 1 × 1
#> nsdiffs
#> <int>
#> 1 0
```

**Auto-ARIMA** model is used to establish the best fit:

if needed `install.packages("urca")`

```
fit <- sdi_fr_ts |>
model(ARIMA(value))
fit |> report()
#> Series: value
#> Model: ARIMA(1,1,0) w/ drift
#>
#> Coefficients:
#> ar1 constant
#> 0.5971 0.0013
#> s.e. 0.1562 0.0002
#>
#> sigma^2 estimated as 8.634e-07: log likelihood=162.46
#> AIC=-318.92 AICc=-317.96 BIC=-314.82
```

### 9.4.2 Partial Autocorrelations

```
sdi_fr_ts |>
PACF(value) |>
autoplot()
sdi_fr_ts |>
gg_tsdisplay(y = value, plot_type = "partial")
```

### 9.4.3 Model Ensembles

To improve the predictive performance, predictions of multiple single learners can be aggregated to a **model ensemble** by combining the forecasts of individual models.

**Ensemble learning** is a machine learning technique, that leverages the diversity of individual models to make more accurate predictions and reduce overfitting. Ensemble methods can reduce the variance and bias of the predictions, leading to more accurate and reliable results. Ensemble techniques such as bagging, boosting, and stacking leverage the diversity of individual models to create a stronger collective model that outperforms its components. These methods are widely used in machine learning and predictive modelling to enhance the predictive power of the model and achieve better generalization performance on unseen data.

In case is required install the `urca`

package:

`install.packages("urca")`

```
caf_fit <- sdi_fr_ts |>
model(
arima210 = ARIMA(value ~ pdq(2, 1, 0)),
arima013 = ARIMA(value ~ pdq(0, 1, 3)),
stepwise = ARIMA(value),
search = ARIMA(value, stepwise = FALSE)
)
```

```
caf_fit |>
pivot_longer(cols = everything(),
names_to = "Model name",
values_to = "Orders")
#> # A mable: 4 x 2
#> # Key: Model name [4]
#> `Model name` Orders
#> <chr> <model>
#> 1 arima210 <ARIMA(2,1,0) w/ drift>
#> 2 arima013 <ARIMA(0,1,3) w/ drift>
#> 3 stepwise <ARIMA(1,1,0) w/ drift>
#> 4 search <ARIMA(1,1,0) w/ drift>
```

```
glance(caf_fit) |>
arrange(AICc) |>
select(.model:BIC)
#> # A tibble: 4 × 6
#> .model sigma2 log_lik AIC AICc BIC
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 stepwise 0.000000863 162. -319. -318. -315.
#> 2 search 0.000000863 162. -319. -318. -315.
#> 3 arima210 0.000000896 162. -317. -315. -311.
#> 4 arima013 0.000000950 162. -314. -312. -308.
```

Best ARIMA model selected is ARIMA(1,1,0):

```
caf_fit |>
select(search) |>
gg_tsresiduals()
caf_fit |>
forecast(h = 5) |>
filter(.model == "search") |>
ggplot(aes(x = year, y = .mean)) +
geom_line(data = sdi_fr_ts,
aes(y = value)) +
geom_line(color = "purple", linetype = "dashed")
```

## 9.5 Mixed Models

Mixed models are a powerful statistical tool for analyzing data with a hierarchical or nested structure, where observations are grouped within higher-level units. By incorporating both fixed and random effects, mixed models can account for the variability within and between groups, providing a flexible framework for modelling complex data structures. Mixed models are widely used in various fields, and particularly useful in fields like healthcare and infectious diseases where data might be collected across different subjects or time points.

### 9.5.1 Mixed-Effects Models in Estimating YLDs

Mixed-effects models are particularly useful in estimating YLDs because they can handle data that is hierarchically structured (e.g., patients within clinics, repeated measures over time) and account for both fixed effects (e.g., age, gender) and random effects (e.g., variability between patients or clinics).

**Fixed Effects**: These are the primary effects of interest and include variables such as age, gender, year, and specific interventions or treatments.

**Random Effects**: These capture the variability that is not explained by the fixed effects, such as differences between patients, clinics, or regions.

By using mixed-effects models, we can better account for the within-subject and between-subject variability, providing more accurate estimates of YLDs.

### 9.5.2 Different Ratios Used in Forecasting Non-Fatal Disease Burden

When forecasting the non-fatal disease burden, different mortality ratios are used to assess the dynamics and progression of diseases. Here are three important ratios:

**MI Ratio (Mortality to Incidence Ratio)**: MI=M/I

This ratio compares the number of deaths due to a disease to the number of new cases of the disease in a specific time period. It is considered a **severity indicator** as it indicates the **lethality of the disease** after diagnosis. A high MI suggests that a higher proportion of diagnosed cases result in death, indicating a severe condition.

**MP Ratio (Mortality to Prevalence Ratio)**: MP=M/P

This ratio compares the number of deaths due to a disease to the total number of existing cases (both new and old) at a given time. It is used in the **Current Risk Assessment (CRA)** as it reflects the **current fatality risk** among those living with the disease. A high MP suggests a significant risk of death for those currently affected. It helps in understanding the long-term burden and survivability of a disease.

**PI Ratio (Prevalence to Incidence Ratio)**: PI=P/I

This ratio compares the total number of existing cases to the number of new cases in a specific time period. As **chronicity indicator**, it indicates how long individuals live with the disease. A high PI suggests that individuals live longer with the disease, indicating it is more chronic. It provides insight into the chronic nature of a disease and the duration that individuals typically live with the disease.

In R, mixed-effects models can integrated with Eigen, a C++ template library for linear algebra which significantly speed up the computations involved in fitting mixed-effects models.

## 9.6 Example: Tuberculosis YLDs Estimation Using Mixed-Effects Models

To estimate Years Lived with Disability (YLDs) using mixed-effects models in R, we can use the `lme4`

package which provides functions to fit linear and generalized linear mixed-effects models. We will create a hypothetical example of how to estimate YLDs with mixed-effects models. We use the **Respiratory infections and tuberculosis** dataset found in hmsidwR package containing YLDs, deaths, incidence and prevalence for 2010 and 2019 to demonstrate the estimation of YLDs using mixed-effects models.

```
library(lme4)
library(tidyverse)
data <- hmsidwR::g7_hmetrics %>%
filter(measure %in% c("Incidence",
"Prevalence",
"YLDs",
"Deaths"),
str_detect(cause, "tuberculosis"),
metric == "Rate",
sex == "both") %>%
select(-metric, -sex, -cause, -upper, -lower) %>%
pivot_wider(names_from = measure,
values_from = val)
data %>% head()
#> # A tibble: 6 × 6
#> location year Deaths YLDs Prevalence Incidence
#> <chr> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 Japan 2010 27.9 130. 23273. 309291.
#> 2 Germany 2010 11.9 116. 12019. 275991.
#> 3 Canada 2010 11.3 130. 13895. 322972.
#> 4 Global 2019 49.1 172. 26750. 237122.
#> 5 UK 2019 28.4 122. 11800. 289730.
#> 6 Germany 2019 11.3 115. 11040. 275703.
```

```
library(ggpattern)
ggplot(data,
aes(x = fct_reorder(location, YLDs),
y = YLDs, group = year)) +
ggpattern::geom_col_pattern(aes(pattern = factor(year)),
position = "dodge",
fill= 'white',
colour= 'black') +
labs(title="YLDs for Tuberculosis by Location and Year",
x = "Location", pattern = "Year")
```

```
hmsidwR::disweights %>%
filter(str_detect(sequela, "tuberculosis")) %>%
select(cause1, severity, dw)
#> # A tibble: 6 × 3
#> cause1 severity dw
#> <chr> <chr> <dbl>
#> 1 Tuberculosis mean 0.333
#> 2 Tuberculosis mean 0.333
#> 3 Tuberculosis mean 0.333
#> 4 Tuberculosis mean 0.333
#> 5 Tuberculosis mean 0.333
#> 6 Tuberculosis mean 0.333
```

The disability weights is 0.333 for tuberculosis, and the duration derived from the GBD 2021 was estimated based on a systematic review and adjusted it for treated and untreated cases. The duration of tuberculosis was estimated to be 3 years^{1} for untreated cases and 6 months for treated cases.

```
# Define the formula
formula <- YLDs ~ Prevalence + year + (1 | location)
# Fit the mixed-effects model
model <- lmer(formula, data = data)
model
#> Linear mixed model fit by REML ['lmerMod']
#> Formula: YLDs ~ Prevalence + year + (1 | location)
#> Data: data
#> REML criterion at convergence: 98.7233
#> Random effects:
#> Groups Name Std.Dev.
#> location (Intercept) 9.817
#> Residual 2.864
#> Number of obs: 14, groups: location, 7
#> Fixed Effects:
#> (Intercept) Prevalence year
#> -4.390e+02 2.652e-03 2.624e-01
#> fit warnings:
#> Some predictor variables are on very different scales: consider rescaling
```

```
# Extract fixed effects
fixed_effects <- fixef(model)
fixed_effects
#> (Intercept) Prevalence year
#> -4.389689e+02 2.652115e-03 2.623523e-01
```

```
# Extract random effects
random_effects <- ranef(model)
random_effects
#> $location
#> (Intercept)
#> Canada 3.9041842
#> Germany -4.4840878
#> Global 12.6329625
#> Italy -0.6497860
#> Japan -16.3490825
#> UK 0.9000282
#> US 4.0457814
#>
#> with conditional variances for "location"
```

```
# Create new data for prediction
new_data <- data.frame(Prevalence = c(25000, 12000, 50000),
year = c(2020, 2021, 2022),
location = c("Japan", "UK", "US"))
# Predict YLDs for new data
predictions <- predict(model,
new_data,
allow.new.levels = TRUE
)
```

```
# Predict YLDs for new data
predictions <- predict(model,
data,
allow.new.levels = TRUE
)
data$predicted_YLD <- predictions
ggplot(data %>% filter(year == 2019,
!location=="Global"),
aes(x = YLDs, y = predicted_YLD,
group = location)) +
geom_point(aes(shape = factor(location))) +
geom_abline() +
labs(title = "YLDs Predicted vs Estimated",
x = "YLDs",
y = "Predicted YLD",
shape = "Location")
```

## 9.7 Summary

Predictive modelling is a valuable tool for forecasting future trends and making informed decisions based on historical data. By leveraging the insights gained from the models, we can anticipate the trajectory of infectious diseases, estimate disease burden, and evaluate the impact of interventions on population health. The models can be further refined and optimized to improve their predictive performance and provide more accurate forecasts. By combining predictive modelling with time series analysis and mixed models, we can gain a comprehensive understanding of the complex dynamics of public health and make data-driven decisions to improve population health outcomes.