Skip to content

Commit 278a1eb

Browse files
gvegayonpre-commit-ci[bot]Copilot
authored
Fixing vignette of LFMCMC (#186)
* Fixing vignette of LFMCMC * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Removing extra citation message * Bump version to 0.15.1-1 and add NEWS.md entry for LFMCMC vignette fix Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com>
1 parent 88c9448 commit 278a1eb

5 files changed

Lines changed: 35 additions & 20 deletions

File tree

.devcontainer/Containerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM ghcr.io/rocker-org/devcontainer/r-ver:4.5
1+
FROM ghcr.io/rocker-org/devcontainer/r-ver:4.6
22

33
# Architecture-specific variable (built in Docker BuildKit)
44
ARG TARGETARCH

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: epiworldR
22
Type: Package
33
Title: Fast Agent-Based Epi Models
4-
Version: 0.15.1-0
4+
Version: 0.15.1-1
55
Depends: R (>= 4.1.0)
66
Authors@R: c(
77
person(given="George", family="Vega Yon", role=c("aut", "cre"),

NEWS.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# epiworldR 0.15.1-1
2+
3+
## User-visible changes
4+
5+
* Updated LFMCMC vignette example parameters for improved reliability. Users
6+
should be aware that LFMCMC results are sensitive to parameter choices, and
7+
incorporating informative priors is strongly recommended for real analyses.
8+
19
# epiworldR 0.15.1-0
210

311
## User-visible changes

R/zzz.R

Lines changed: 0 additions & 5 deletions
This file was deleted.

vignettes/likelihood-free-mcmc.qmd

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Our SIR model will have the following characteristics:
3232
* **Virus Name:** COVID-19
3333
* **Initial Virus Prevalence:** 0.01
3434
* **Recovery Rate:** 1/7 (0.14)
35-
* **Transmission Rate:** 0.02
35+
* **Transmission Rate:** 0.04
3636
* **Number of Agents:** 2,000
3737

3838
We use the `ModelSIR` and `agents_smallworld` functions to construct the model in epiworldR.
@@ -41,12 +41,12 @@ We use the `ModelSIR` and `agents_smallworld` functions to construct the model i
4141
#| label: setup-sir
4242
library(epiworldR)
4343
44-
model_seed <- 122
44+
model_seed <- 221
4545
4646
model_sir <- ModelSIR(
4747
name = "COVID-19",
4848
prevalence = .01,
49-
transmission_rate = .02,
49+
transmission_rate = .04,
5050
recovery_rate = 1 / 7
5151
)
5252
@@ -72,13 +72,17 @@ run(
7272
)
7373
7474
summary(model_sir)
75+
plot_incidence(model_sir)
7576
```
7677

77-
Note the "Model parameters" and the "Distribution of the population at time 50" from the above output. Our goal is to recover the model parameters (Recovery and Transmission rates) through LFMCMC. We accomplish this by comparing the population distribution from each simulation run to the "observed" distribution from our model. We get this distribution using the `get_today_total` function in epiworldR.
78+
Note the "Model parameters" and the "Distribution of the population at time 50" from the above output. Our goal is to recover the model parameters (Recovery and Transmission rates) through LFMCMC. We accomplish this by comparing each simulation run to the "observed" data from our model. In addition to the end-of-run population counts from `get_today_total`, we include the mean number of active cases over time using `get_active_cases`. This extra summary statistic provides additional information about the epidemic trajectory and improves the fit.
7879

7980
```{r}
8081
#| label: get-sir-model-data
81-
model_sir_data <- get_today_total(model_sir)
82+
model_sir_data <- c(
83+
get_today_total(model_sir),
84+
mean(get_active_cases(model_sir)$active_cases)
85+
)
8286
```
8387

8488
For practical cases, you would use observed data, instead of a model simulation. We use a simulation in our example to show the accuracy of LFMCMC in recovering the model parameters. Whenever we use the term "observed data" below, we are referring to the model distribution (`model_sir_data`).
@@ -87,7 +91,7 @@ For practical cases, you would use observed data, instead of a model simulation.
8791

8892
In epiworldR, LFMCMC requires four functions:
8993

90-
The **simulation function** runs a model with a given set of parameters and produces output that matches the structure of our observed data. For our example, we set the Recovery and Transmission rate parameters, run an SIR model for 50 days, and return the distribution of the population at the end of the run.
94+
The **simulation function** runs a model with a given set of parameters and produces output that matches the structure of our observed data. For our example, we set the Recovery and Transmission rate parameters, run an SIR model for 50 days, and return both the end-of-run population distribution and the mean number of active cases.
9195

9296
```{r}
9397
#| label: simfun
@@ -101,13 +105,17 @@ simulation_fun <- function(params, lfmcmc_obj) {
101105
ndays = 50
102106
)
103107
104-
get_today_total(model_sir)
108+
c(
109+
get_today_total(model_sir),
110+
mean(get_active_cases(model_sir)$active_cases)
111+
)
112+
105113
106114
}
107115
```
108116

109117
The **summary function** extracts summary statistics from the given data.
110-
This should produce the same output format for both the observed data and the simulated data from `simulation_fun`. For our example, since the population distribution is already a summary of the data, our summary function simply passes that data through. With more complicated use cases, you might instead compute summary statistics such as the mean or standard deviation.
118+
This should produce the same output format for both the observed data and the simulated data from `simulation_fun`. For our example, the output already contains summary quantities (state totals plus mean active cases), so our summary function simply passes that data through. With more complicated use cases, you might instead compute summary statistics such as the mean or standard deviation.
111119

112120
```{r}
113121
#| label: sumfun
@@ -121,7 +129,7 @@ The **proposal function** returns a new set of parameters, which it is "proposin
121129
```{r}
122130
#| label: propfun
123131
proposal_fun <- function(old_params, lfmcmc_obj) {
124-
res <- plogis(qlogis(old_params) + rnorm(length(old_params), sd = .1))
132+
res <- plogis(qlogis(old_params) + rnorm(length(old_params), sd = .25))
125133
return(res)
126134
}
127135
```
@@ -154,15 +162,16 @@ lfmcmc_model <- LFMCMC(model_sir) |>
154162

155163
# Run LFMCMC Simulation
156164

157-
To run LFMCMC, we need to set the initial model parameters. For our example, we use an initial Recovery rate of 0.3 and an initial Transmission rate of 0.3. We set the kernel epsilon to 1.0 and run the simulation for 2,000 samples (iterations) using the `run_lfmcmc` function.
165+
To run LFMCMC, we need to set the initial model parameters. For our example, we use an initial Recovery rate of 0.3 and an initial Transmission rate of 0.3. We set the kernel epsilon to 0.25 and run the simulation for 2,000 samples (iterations) using the `run_lfmcmc` function.
158166

159167
```{r}
160168
#| label: lfmcmc-run
161169
initial_params <- c(0.3, 0.3)
162-
epsilon <- 1.0
170+
epsilon <- 0.25
163171
n_samples <- 2000
164172
165173
# Run the LFMCMC simulation
174+
set.seed(333)
166175
run_lfmcmc(
167176
lfmcmc = lfmcmc_model,
168177
params_init = initial_params,
@@ -178,7 +187,10 @@ To make the printed results easier to read, we use the `set_params_names` and `s
178187
```{r}
179188
#| label: lfmcmc-print
180189
set_params_names(lfmcmc_model, c("Recovery rate", "Transmission rate"))
181-
set_stats_names(lfmcmc_model, get_states(model_sir))
190+
set_stats_names(
191+
lfmcmc_model,
192+
c(get_states(model_sir), "Average active cases")
193+
)
182194
183195
print(lfmcmc_model, burnin = 1500)
184196
```
@@ -211,4 +223,4 @@ legend(
211223
)
212224
```
213225

214-
Recall that the observed data came from a model with a Recovery rate of 0.3 and a Transmission rate of 0.3. As the above output shows, LFMCMC made a close approximation of the parameters, which resulted in a close approximation of the observed population distribution. This example highlights the effectiveness of using LFMCMC for highly complex models.
226+
Recall that the observed data came from a model with a Recovery rate of 1/7 and a Transmission rate of 0.04. As the above output shows, LFMCMC makes a close approximation of the parameters, which results in a close match to both the observed population distribution and the average number of active cases. This example highlights how adding informative summary statistics can improve likelihood-free inference in complex models.

0 commit comments

Comments
 (0)