+
| minratings | outcome | yearpublished | rmse | mae | mape | rsq | ccc |
diff --git a/index.qmd b/index.qmd
index a39db2e..4a24d1c 100644
--- a/index.qmd
+++ b/index.qmd
@@ -45,11 +45,14 @@ tar_source("src/visualizations/tables.R")
tar_load(valid_predictions)
tar_load(valid_metrics)
tar_load(details)
+tar_load(tuning_plots)
games =
get_games_from_gcp(
bucket = "bgg_data"
)
+
+theme_set(bggUtils::theme_bgg())
```
@@ -127,6 +130,107 @@ targets_tracking_details(metrics = valid_metrics,
```
+## Tuning
+
+::: {.panel-tabset}
+
+### Average Weight
+
+```{r}
+#| fig-height: 7
+#| results: asis
+#| echo: false
+tuning_plots[[1]]+
+ labs(title = 'Average Weight')
+
+```
+
+### Average Rating
+
+```{r}
+#| fig-height: 7
+#| results: asis
+#| echo: false
+tuning_plots[[2]]+
+ labs(title = 'Average Rating')
+
+```
+
+
+### Users Rated
+
+```{r}
+#| fig-height: 7
+#| results: asis
+#| echo: false
+tuning_plots[[3]]+
+ labs(title = 'Users Rated')
+
+```
+
+:::
+
+## Features
+
+```{r}
+#| message: false
+#| warning: false
+average_plot =
+ average_fit |>
+ extract_vetiver_features() |>
+ plot_model_features()+
+ labs(title = 'Average Rating')
+
+averageweight_plot =
+ averageweight_fit |>
+ extract_vetiver_features() |>
+ plot_model_features()+
+ labs(title = 'Average Weight')
+
+usersrated_plot =
+ usersrated_fit |>
+ extract_vetiver_features() |>
+ plot_model_features()+
+ labs(title = 'Users Rated')
+
+```
+
+::: {.panel-tabset}
+
+### Average Weight
+
+```{r}
+#| fig-height: 7
+#| results: asis
+#| echo: false
+
+averageweight_plot
+
+```
+
+### Average
+
+```{r}
+#| fig-height: 7
+#| results: asis
+#| echo: false
+average_plot
+
+```
+
+### Users Rated
+
+```{r}
+#| fig-height: 7
+#| results: asis
+#| echo: false
+usersrated_plot
+
+```
+
+:::
+
+# Predictions
```{r}
#| message: false
@@ -148,7 +252,6 @@ upcoming_games =
```
-# Predictions
```{r}
predictions =
diff --git a/renv.lock b/renv.lock
index 7e1bd6e..ada17bb 100644
--- a/renv.lock
+++ b/renv.lock
@@ -266,6 +266,13 @@
],
"Hash": "0cf10dab0d023d5b46a5a14387556891"
},
+ "SnowballC": {
+ "Package": "SnowballC",
+ "Version": "0.7.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "46da3912f69e3e6258a033802c4af32e"
+ },
"SparseM": {
"Package": "SparseM",
"Version": "1.81",
@@ -469,6 +476,25 @@
"Repository": "CRAN",
"Hash": "b7d8d8ee39869c18d8846a184dd8a1af"
},
+ "bonsai": {
+ "Package": "bonsai",
+ "Version": "0.2.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "cli",
+ "dials",
+ "dplyr",
+ "glue",
+ "parsnip",
+ "purrr",
+ "rlang",
+ "stats",
+ "tibble",
+ "utils"
+ ],
+ "Hash": "c086fa23dfeac2d2b95f758dfa917c3d"
+ },
"boot": {
"Package": "boot",
"Version": "1.3-30",
@@ -1317,6 +1343,18 @@
],
"Hash": "16a4974681fc751a09a1250431361896"
},
+ "git2r": {
+ "Package": "git2r",
+ "Version": "0.33.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "graphics",
+ "utils"
+ ],
+ "Hash": "cdec9964efeda730d1b2cd3d5dd27747"
+ },
"globals": {
"Package": "globals",
"Version": "0.16.2",
@@ -1703,6 +1741,16 @@
],
"Hash": "8954069286b4b2b0d023d1b288dce978"
},
+ "janeaustenr": {
+ "Package": "janeaustenr",
+ "Version": "1.0.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R"
+ ],
+ "Hash": "26f391e42073877818f2d4f0470dca24"
+ },
"jquerylib": {
"Package": "jquerylib",
"Version": "0.1.4",
@@ -3165,6 +3213,29 @@
],
"Hash": "79540e5fcd9e0435af547d885f184fd5"
},
+ "tidytext": {
+ "Package": "tidytext",
+ "Version": "0.4.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "Matrix",
+ "R",
+ "cli",
+ "dplyr",
+ "generics",
+ "janeaustenr",
+ "lifecycle",
+ "methods",
+ "purrr",
+ "rlang",
+ "stringr",
+ "tibble",
+ "tokenizers",
+ "vctrs"
+ ],
+ "Hash": "eb8386c938a086eb3216595eba76831d"
+ },
"timeDate": {
"Package": "timeDate",
"Version": "4032.109",
@@ -3200,6 +3271,19 @@
],
"Hash": "5ac22900ae0f386e54f1c307eca7d843"
},
+ "tokenizers": {
+ "Package": "tokenizers",
+ "Version": "0.3.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "Rcpp",
+ "SnowballC",
+ "stringi"
+ ],
+ "Hash": "76d35ebfaaf291e08c15696c9f2ec96d"
+ },
"tune": {
"Package": "tune",
"Version": "1.1.2",
@@ -3328,6 +3412,22 @@
],
"Hash": "b9a6f592769dc2b70a0a7bd1478741f2"
},
+ "vip": {
+ "Package": "vip",
+ "Version": "0.4.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Requirements": [
+ "R",
+ "foreach",
+ "ggplot2",
+ "stats",
+ "tibble",
+ "utils",
+ "yardstick"
+ ],
+ "Hash": "4bfee1f7181f71d552a4b63485f8fc25"
+ },
"viridisLite": {
"Package": "viridisLite",
"Version": "0.4.2",
diff --git a/src/models/training.R b/src/models/training.R
index 0ddb62c..a913e7c 100644
--- a/src/models/training.R
+++ b/src/models/training.R
@@ -531,6 +531,33 @@ glmnet_grid = function() {
)
}
+lightgbm_spec = function(trees = 500, ...) {
+
+
+ require(bonsai)
+
+ parsnip::boost_tree(
+ mode = "regression",
+ trees = trees,
+ min_n = tune(),
+ tree_depth = tune(),
+ ...) |>
+ set_engine("lightgbm")
+}
+
+lightgbm_grid =
+ function(size = 15) {
+
+ grid_max_entropy(
+ x = dials::parameters(
+ min_n(), # 2nd important
+ tree_depth() # 3rd most important
+ ),
+ size = size
+ )
+ }
+
+
# function to build a recipe and apply series of steps given an outcome
build_outcome_recipe =
function(data,
diff --git a/src/visualizations/models.R b/src/visualizations/models.R
index 11fa63c..43b7c9f 100644
--- a/src/visualizations/models.R
+++ b/src/visualizations/models.R
@@ -1,40 +1,156 @@
+get_tuning_plots = function(results) {
+
+ results |>
+ select(outcome, wflow_id, result) |>
+ mutate(plot = map2(result, outcome, ~ .x |>
+ autoplot() +
+ labs(title = .y) +
+ theme_bw())) |>
+ pull(plot)
+}
+
+extract_vetiver_features = function(v) {
+
+ v |>
+ extract_vetiver_model() |>
+ extract_model_features()
+}
+
+extract_vetiver_model = function(vetiver_obj) {
+
+ vetiver_obj |>
+ pluck("model") |>
+ bundle::unbundle()
+}
+
+extract_model_type = function(wflow) {
+
+ wflow |>
+ extract_fit_parsnip() |>
+ pluck("spec") |>
+ pluck("engine")
+
+}
+
+extract_model_features = function(wflow) {
+
+ # check type
+ engine = wflow |>
+ extract_model_type()
+
+ if (engine == 'lightgbm') {
+
+ features = map_df(
+ c('frequency', 'cover', 'gain'),
+ ~ wflow|>
+ vip::vi_model(.x,
+ percentage = T) |>
+ mutate(type = .x)
+ )
+
+ } else if (engine == 'glmnet') {
+
+ features = wflow |>
+ get_coefs.glmnet()
+ } else {
+
+ features = wflow |>
+ vip::vi_model()
+ }
+
+ features |>
+ add_column(engine = engine) |>
+ select(engine, everything())
+
+}
+
+plot_features.lightgbm = function(features,
+ top_n = 25,
+ minlength = 50) {
+
+ features |>
+ group_by(type) |>
+ slice_max(Importance, n = top_n) |>
+ mutate(Variable = bggUtils::present_bgg_text(Variable, minlength = minlength)) |>
+ ggplot(aes(x=Importance,
+ y = reorder(Variable, Importance)))+
+ geom_col()+
+ facet_wrap(~type, scales = "free_x", ncol = 3) +
+ tidytext::scale_y_reordered()+
+ ylab("Feature")
+}
+
+plot_features.default = function(features,
+ top_n = 25,
+ minlength = 50) {
+ features |>
+ slice_max(Importance, n = top_n) |>
+ mutate(Variable = bggUtils::present_bgg_text(Variable, minlength = minlength)) |>
+ ggplot(aes(x=Importance,
+ y = reorder(Variable, Importance)))+
+ geom_col()+
+ tidytext::scale_y_reordered()+
+ ylab("Feature")
+
+}
+
+plot_model_features = function(features,
+ ...) {
+
+ engine = unique(features$engine)
+
+ # check engine
+ if (engine == 'lightgbm') {
+ features |>
+ plot_features.lightgbm(...)
+ } else if (engine == 'glmnet') {
+
+ features |>
+ coef_plot.glmnet(...)
+ } else {
+
+ features |>
+ plot_features.default()
+ }
+}
+
get_glmnet_objs =
- function(glmnet_wflow) {
-
- # extract engine
- glmnet_engine =
- glmnet_wflow %>%
- extract_fit_engine()
-
- # extract parsnip
- glmnet_parsnip =
- glmnet_wflow %>%
- extract_fit_parsnip()
-
-
- # return both
- list("engine" = glmnet_engine,
- "parsnip" = glmnet_parsnip)
-
- }
+ function(glmnet_wflow) {
+
+ # extract engine
+ glmnet_engine =
+ glmnet_wflow %>%
+ extract_fit_engine()
+
+ # extract parsnip
+ glmnet_parsnip =
+ glmnet_wflow %>%
+ extract_fit_parsnip()
+
+
+ # return both
+ list("engine" = glmnet_engine,
+ "parsnip" = glmnet_parsnip)
+
+ }
get_glmnet_coefs = function(glmnet_objs,
type = 'parsnip',
remove_intercept = T,
return_zeroes = T) {
-
- coefs =
- glmnet_objs |>
- pluck(type) |>
- tidy(return_zeroes = return_zeroes)
-
- if (remove_intercept == T) {
- coefs =
- coefs |>
- filter(term != "(Intercept)")
- }
-
- coefs
+
+ coefs =
+ glmnet_objs |>
+ pluck(type) |>
+ tidy(return_zeroes = return_zeroes)
+
+ if (remove_intercept == T) {
+ coefs =
+ coefs |>
+ filter(term != "(Intercept)")
+ }
+
+ coefs
}
color_fill_gradient = function(plot,
@@ -44,72 +160,72 @@ color_fill_gradient = function(plot,
mid_color = "grey80",
high_color = "deepskyblue1",
oob = scales::squish) {
-
- plot +
- scale_fill_gradient2(low = low_color,
- mid = mid_color,
- high = high_color,
- midpoint = 0,
- limits = limits,
- oob = oob) +
- scale_fill_gradient2(low = low_color,
- mid = mid_color,
- high = high_color,
- midpoint = 0,
- limits = limits,
- oob = oob)
+
+ plot +
+ scale_fill_gradient2(low = low_color,
+ mid = mid_color,
+ high = high_color,
+ midpoint = 0,
+ limits = limits,
+ oob = oob) +
+ scale_fill_gradient2(low = low_color,
+ mid = mid_color,
+ high = high_color,
+ midpoint = 0,
+ limits = limits,
+ oob = oob)
}
fill_colorbar = function(plot) {
-
- plot +
- guides(fill = guide_colorbar(barheight = 0.5,
- barwidth = 15,
- title.position = 'top')
- )
-
+
+ plot +
+ guides(fill = guide_colorbar(barheight = 0.5,
+ barwidth = 15,
+ title.position = 'top')
+ )
+
}
color_colorbar = function(plot) {
-
- plot +
- guides(color = guide_colorbar(barheight = 0.5,
- barwidth = 15,
- title.position = 'top')
- )
-
+
+ plot +
+ guides(color = guide_colorbar(barheight = 0.5,
+ barwidth = 15,
+ title.position = 'top')
+ )
+
}
get_coefs.glmnet = function(workflow,
remove_intercept = T) {
-
- glmnet_objs = get_glmnet_objs(workflow)
-
- coefs =
- get_glmnet_coefs(glmnet_objs,
- type = 'parsnip',
- remove_intercept = remove_intercept)
-
- if (remove_intercept == T) {
- coefs =
- coefs |>
- filter(term != "(Intercept)")
- }
-
- coefs
+
+ glmnet_objs = get_glmnet_objs(workflow)
+
+ coefs =
+ get_glmnet_coefs(glmnet_objs,
+ type = 'parsnip',
+ remove_intercept = remove_intercept)
+
+ if (remove_intercept == T) {
+ coefs =
+ coefs |>
+ filter(term != "(Intercept)")
+ }
+
+ coefs
}
top_coefs_by_sign = function(coefs,
n = 25) {
-
- coefs |>
- mutate(sign = case_when(estimate > 0 ~ 'increases probability',
- estimate < 0 ~ 'decreases probability')) |>
- mutate(sign = factor(sign, levels = c("increases probability", "decreases probability"))) |>
- group_by(sign) |>
- slice_max(abs(estimate),
- n =n)
+
+ coefs |>
+ mutate(sign = case_when(estimate > 0 ~ 'increases probability',
+ estimate < 0 ~ 'decreases probability')) |>
+ mutate(sign = factor(sign, levels = c("increases probability", "decreases probability"))) |>
+ group_by(sign) |>
+ slice_max(abs(estimate),
+ n =n)
}
coef_plot.glmnet = function(coefs,
@@ -118,39 +234,39 @@ coef_plot.glmnet = function(coefs,
midpoint = 0,
facet_by_sign = F,
...) {
+
+ present_coefs =
+ coefs |>
+ mutate(tidy_term = bggUtils::present_bgg_text(term, minlength = minlength))
+
+ plot = present_coefs |>
+ ggplot(aes(x=estimate,
+ fill = estimate,
+ y= reorder(tidy_term, estimate))) +
+ geom_col(color = 'white')+
+ theme_bgg()+
+ labs(y = "Feature",
+ x = "Effect on Outcome")
+
+ suppressMessages({
+ p =
+ plot |>
+ color_fill_gradient(midpoint = midpoint,
+ limits = limits,
+ oob = scales::squish)
+ })
+
+ if (facet_by_sign == T) {
- present_coefs =
- coefs |>
- mutate(tidy_term = bggUtils::present_bgg_text(term, minlength = minlength))
-
- plot = present_coefs |>
- ggplot(aes(x=estimate,
- fill = estimate,
- y= reorder(tidy_term, estimate))) +
- geom_col(color = 'white')+
- theme_bgg()+
- labs(y = "Feature",
- x = "Effect on Outcome")
-
- suppressMessages({
- p =
- plot |>
- color_fill_gradient(midpoint = midpoint,
- limits = limits,
- oob = scales::squish)
- })
-
- if (facet_by_sign == T) {
-
- p = plot +
- facet_wrap(sign ~.,
- scales = "free")+
- theme(strip.text.x = element_text(size = 10))
- }
-
- p |>
- fill_colorbar()
-
+ p = plot +
+ facet_wrap(sign ~.,
+ scales = "free")+
+ theme(strip.text.x = element_text(size = 10))
+ }
+
+ p |>
+ fill_colorbar()
+
}
trace_plot.glmnet = function(workflow,
@@ -158,68 +274,68 @@ trace_plot.glmnet = function(workflow,
lower_estimate = -0.5,
minlength = 50,
max.overlaps = 25) {
-
-
- glmnet_objs =
- workflow |>
- get_glmnet_objs()
-
- # get lambda
- lambda =
- glmnet_objs|>
- pluck("parsnip") |>
- tidy() |>
- pull(penalty) |>
- unique()
-
- coefs =
- glmnet_objs |>
- get_glmnet_coefs(
- type = 'engine'
- )
-
- plot_coefs =
- coefs |>
- mutate(label_left =
- case_when(
- lambda == min(lambda) & abs(estimate) > upper_estimate ~
- bggUtils::present_bgg_text(term, minlength = minlength))) %>%
- group_by(term) %>%
- mutate(label_right =
- case_when(
- lambda == max(lambda) & estimate > lower_estimate ~
- bggUtils::present_bgg_text(term, minlength = minlength))) %>%
- ungroup()
-
- plot_coefs |>
- ggplot(aes(x=log(lambda),
- y=estimate,
- group = term))+
- geom_line(alpha = 0.5,
- color = 'grey60')+
- geom_vline(xintercept = log(lambda),
- linetype = 'dotted',
- alpha = 0.5)+
- guides(color = 'none')+
- theme_minimal()+
- ggrepel::geom_text_repel(
- aes(label = label_left),
- max.overlaps = max.overlaps,
- size = 2,
- direction = "y",
- hjust =1.5,
- segment.size = .5,
- segment.alpha = .5,
- segment.linetype = "dashed",
- box.padding = .5,
- segment.curvature = 0.2,
- segment.ncp = 3,
- segment.angle = 20)+
- coord_cartesian(xlim = c(min(log(glmnet_objs$engine$lambda)-2), 0))+
- theme(panel.grid.major = element_blank())+
- geom_hline(yintercept = 0,
- linetype = 'dotted',
- alpha = 0.5)
+
+
+ glmnet_objs =
+ workflow |>
+ get_glmnet_objs()
+
+ # get lambda
+ lambda =
+ glmnet_objs|>
+ pluck("parsnip") |>
+ tidy() |>
+ pull(penalty) |>
+ unique()
+
+ coefs =
+ glmnet_objs |>
+ get_glmnet_coefs(
+ type = 'engine'
+ )
+
+ plot_coefs =
+ coefs |>
+ mutate(label_left =
+ case_when(
+ lambda == min(lambda) & abs(estimate) > upper_estimate ~
+ bggUtils::present_bgg_text(term, minlength = minlength))) %>%
+ group_by(term) %>%
+ mutate(label_right =
+ case_when(
+ lambda == max(lambda) & estimate > lower_estimate ~
+ bggUtils::present_bgg_text(term, minlength = minlength))) %>%
+ ungroup()
+
+ plot_coefs |>
+ ggplot(aes(x=log(lambda),
+ y=estimate,
+ group = term))+
+ geom_line(alpha = 0.5,
+ color = 'grey60')+
+ geom_vline(xintercept = log(lambda),
+ linetype = 'dotted',
+ alpha = 0.5)+
+ guides(color = 'none')+
+ theme_minimal()+
+ ggrepel::geom_text_repel(
+ aes(label = label_left),
+ max.overlaps = max.overlaps,
+ size = 2,
+ direction = "y",
+ hjust =1.5,
+ segment.size = .5,
+ segment.alpha = .5,
+ segment.linetype = "dashed",
+ box.padding = .5,
+ segment.curvature = 0.2,
+ segment.ncp = 3,
+ segment.angle = 20)+
+ coord_cartesian(xlim = c(min(log(glmnet_objs$engine$lambda)-2), 0))+
+ theme(panel.grid.major = element_blank())+
+ geom_hline(yintercept = 0,
+ linetype = 'dotted',
+ alpha = 0.5)
}
@@ -229,24 +345,24 @@ coef_plot_by_group = function(coefs,
scales = "free",
shrink = T,
...) {
-
- tmp =
- paste0('^', group)
-
- coefs |>
- filter(grepl(tmp, term)) |>
- top_coefs_by_sign() |>
- mutate(term = gsub(tmp, "", term)) |>
- coef_plot.glmnet(...) +
- facet_wrap(sign ~.,
- scales = scales,
- shrink = shrink) +
- theme(strip.text.x = element_text(size = 10),
- axis.text.y = element_text(hjust = 1))+
- scale_x_continuous(breaks = scales::pretty_breaks(n=3))+
- guides(fill = 'none') +
- labs(title = stringr::str_to_title(group))+
- scale_y_discrete(label=function(x) stringr::str_trunc(x, width = width))
-
-
+
+ tmp =
+ paste0('^', group)
+
+ coefs |>
+ filter(grepl(tmp, term)) |>
+ top_coefs_by_sign() |>
+ mutate(term = gsub(tmp, "", term)) |>
+ coef_plot.glmnet(...) +
+ facet_wrap(sign ~.,
+ scales = scales,
+ shrink = shrink) +
+ theme(strip.text.x = element_text(size = 10),
+ axis.text.y = element_text(hjust = 1))+
+ scale_x_continuous(breaks = scales::pretty_breaks(n=3))+
+ guides(fill = 'none') +
+ labs(title = stringr::str_to_title(group))+
+ scale_y_discrete(label=function(x) stringr::str_trunc(x, width = width))
+
+
}
\ No newline at end of file
diff --git a/targets-runs/tracking.csv b/targets-runs/tracking.csv
index d78d142..d3e9d8a 100644
--- a/targets-runs/tracking.csv
+++ b/targets-runs/tracking.csv
@@ -1,9 +1,9 @@
-"","time","user","model","penalty","mixture",".config","minratings","outcome","rmse","mae","mape","rsq","ccc"
-"1",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet",0.01,0.5,"Preprocessor1_Model27",0,"average",1.303,0.923,16.481,0.113,0.204
-"2",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet",0.01,0.5,"Preprocessor1_Model27",0,"averageweight",0.548,0.42,24.993,0.529,0.701
-"3",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet+glmnet",NA,NA,NA,0,"bayesaverage",0.3,0.174,2.878,0.412,0.633
-"4",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet",0.01,0.5,"Preprocessor1_Model27",0,"usersrated",994.732,205.786,Inf,0.163,0.401
-"5",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet",0.01,0.5,"Preprocessor1_Model27",25,"average",0.688,0.506,7.625,0.277,0.458
-"6",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet",0.01,0.5,"Preprocessor1_Model27",25,"averageweight",0.479,0.367,20.356,0.63,0.773
-"7",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet+glmnet",NA,NA,NA,25,"bayesaverage",0.3,0.174,2.878,0.412,0.633
-"8",2024-05-23 13:13:49.184795,"phil.henrickson@github.com","glmnet",0.01,0.5,"Preprocessor1_Model27",25,"usersrated",1888.348,468.294,165.111,0.145,0.379
+"","time","user","model","min_n","tree_depth",".config","minratings","outcome","rmse","mae","mape","rsq","ccc"
+"1",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm",15,7,"Preprocessor1_Model06",0,"average",1.317,0.935,16.324,0.113,0.217
+"2",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm",15,7,"Preprocessor1_Model06",0,"averageweight",0.532,0.403,23.69,0.56,0.733
+"3",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm+lightgbm",NA,NA,NA,0,"bayesaverage",0.293,0.17,2.823,0.432,0.646
+"4",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm",15,7,"Preprocessor1_Model06",0,"usersrated",829.856,211.708,Inf,0.253,0.498
+"5",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm",15,7,"Preprocessor1_Model06",25,"average",0.692,0.509,7.582,0.282,0.463
+"6",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm",15,7,"Preprocessor1_Model06",25,"averageweight",0.457,0.347,19.21,0.665,0.804
+"7",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm+lightgbm",NA,NA,NA,25,"bayesaverage",0.293,0.17,2.823,0.432,0.646
+"8",2024-05-24 09:41:20.367494,"phil.henrickson@github.com","lightgbm",15,7,"Preprocessor1_Model06",25,"usersrated",1565.092,461.642,184.381,0.229,0.476