data <- parvob19_fi_1997_1998[order(parvob19_fi_1997_1998$age), ] %>%
rename(status = seropositive)
aggregated <- transform_data(data, stratum_col = "age", status_col="status")Generate models comparison data.frame
Function compare_models() is used for quickly computing
comparison metrics for a set of models on a given dataset.
The function takes the following arguments:
datathe dataset that will be fitted to the modelsmethodthe method to generate comparison metrics. It can be the name of one of the built-in methods, or a user-defined function.method_argsthe list of additional arguments for method function.…functions that take a data and return a fittedserosvmodel.
It will then return a data.frame with the following
columns
labelmodel identifier. Either user defined name or index based on the order provided.typetype of model (aserosvmodel class)metrics depending on the method selected
Built-in method
serosv currently provide 2 built-in metrics generating
methods
"AIC/BIC"which returns fitted model’s AIC, BIC and Log-likelihood (where applicable)"CV"which split the data into “train” and “test” set then return logloss and AUC from model’s prediction on the test set. Number of folds can be configured viakargument (see Sample usage below).
Sample usage
# ----- Return AIC, BIC -----
aic_bic_out <- compare_models(
data = data,
method = "AIC/BIC",
griffith = ~polynomial_model(.x, k=2),
penalized_spline = penalized_spline_model,
farrington = ~farrington_model(.x,
start=list(beta=0.12,gamma=0.05),
fixed=list(alpha=0.1)),
local_polynomial = lp_model # expect to not return any values
) %>% suppressWarnings()
# ----- Return Cross-validation metrics -----
cv_out <- compare_models(
data,
method = "CV",
griffith = ~polynomial_model(.x, k=2),
penalized_spline = penalized_spline_model,
farrington = ~farrington_model(.x,
start=list(beta=0.12,gamma=0.05),
fixed=list(alpha=0.1)),
local_polynomial = lp_model,
method_args = list(
k = 4 # adjust the fold k for the CV function
)
) %>% suppressWarnings()
aic_bic_out## # A tibble: 4 × 8
## label type AIC BIC logLik df mod_out plots
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <list> <list>
## 1 griffith polynomial_mo… 1353. 1363. -674. 2 <plynml_m> <ggplt2::>
## 2 penalized_spline penalized_spl… 1330. 1365. -658. 6.88 <pnlzd_s_> <ggplt2::>
## 3 farrington farrington_mo… 1358. NA -677. 2 <frrngtn_> <ggplt2::>
## 4 local_polynomial lp_model NA NA NA NA <lp_model> <ggplt2::>
cv_out## # A tibble: 4 × 6
## label logloss auc type mod_out plots
## <chr> <dbl> <dbl> <chr> <list> <list>
## 1 griffith 169. 0.701 polynomial_model <plynml_m> <ggplt2::>
## 2 penalized_spline 167. 0.684 penalized_spline_model <pnlzd_s_> <ggplt2::>
## 3 farrington 170. 0.702 farrington_model <frrngtn_> <ggplt2::>
## 4 local_polynomial 165. 0.702 lp_model <lp_model> <ggplt2::>
With aggregated data
# ----- Return AIC, BIC -----
aic_bic_out <- compare_models(
data = aggregated,
method = "AIC/BIC",
griffith = ~polynomial_model(.x, k=2),
penalized_spline = penalized_spline_model,
farrington = ~farrington_model(.x,
start=list(beta=0.1,gamma=0.03),
fixed=list(alpha=0.07)),
local_polynomial = lp_model # expect to not return any values
) %>% suppressWarnings()
# ----- Return Cross-validation metrics (default with 4 folds) -----
cv_out <- compare_models(
data = aggregated,
method = "CV",
griffith = ~polynomial_model(.x, k=2),
penalized_spline = penalized_spline_model,
farrington = ~farrington_model(.x,
start=list(beta=0.1,gamma=0.03),
fixed=list(alpha=0.07)),
local_polynomial = lp_model,
method_args = list(
k = 4 # adjust the fold k for the CV function
)
) %>% suppressWarnings()
aic_bic_out## # A tibble: 4 × 8
## label type AIC BIC logLik df mod_out plots
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <list> <list>
## 1 griffith polynomial_mo… 489. 496. -243. 2 <plynml_m> <ggplt2::>
## 2 penalized_spline penalized_spl… 467. 490. -227. 6.88 <pnlzd_s_> <ggplt2::>
## 3 farrington farrington_mo… 486. NA -241. 2 <frrngtn_> <ggplt2::>
## 4 local_polynomial lp_model NA NA NA NA <lp_model> <ggplt2::>
cv_out## # A tibble: 4 × 6
## label mse logloss type mod_out plots
## <chr> <dbl> <dbl> <chr> <list> <list>
## 1 griffith 0.110 61.7 polynomial_model <plynml_m> <ggplt2::>
## 2 penalized_spline 0.110 58.4 penalized_spline_model <pnlzd_s_> <ggplt2::>
## 3 farrington 0.107 60.5 farrington_model <frrngtn_> <ggplt2::>
## 4 local_polynomial 0.109 60.2 lp_model <lp_model> <ggplt2::>
Generate custom metrics
The users can also provide a custom function to generate the comparison metrics.
This function must accepts 2 parameters:
datthe input datamod_funca function that takes an input data and returns aserosvmodel
And it must returns a data frame with 1 row where each column represents one metric.
Example:
The following implements holdout validation and returns MAE:
generate_mae <- function(dat, mod_func){
n_train <- round(nrow(dat)*0.8)
train <- dat[1:n_train,]
test <- dat[n_train:nrow(dat),]
fit <- mod_func(dat)
pred <- predict(fit, test[, 1, drop=FALSE])
# handle error differently depending on datatype
mae <- if(fit$datatype == "linelisting"){
sum(abs(test$status - pred), na.rm=TRUE)/nrow(test)
}else{
sum(abs(test$pos/test$tot - pred), na.rm=TRUE)/nrow(test)
}
data.frame(
mae = mae
)
}We can then run compare_models with the custom metrics
function
compare_models(
data = aggregated,
method = generate_mae,
griffith = ~polynomial_model(.x, k=2),
penalized_spline = penalized_spline_model,
farrington = ~farrington_model(.x, start=list(alpha=0.07,beta=0.1,gamma=0.03)),
local_polynomial = lp_model
) %>% suppressWarnings()## label mae
## 1 griffith 0.3774195
## 2 penalized_spline 0.3249623
## 3 farrington 0.3710685
## 4 local_polynomial 0.3285755
compare_models(
data = data,
method = generate_mae,
griffith = ~polynomial_model(.x, k=2),
penalized_spline = penalized_spline_model,
farrington = ~farrington_model(.x, start=list(alpha=0.07,beta=0.1,gamma=0.03)),
local_polynomial = lp_model
) %>% suppressWarnings()## label mae
## 1 griffith 0.4603812
## 2 penalized_spline 0.4540285
## 3 farrington 0.4636040
## 4 local_polynomial 0.4536016