From d930c6aa61074deca4b35a12dbc3a7112758ccad Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Wed, 17 Jan 2024 11:42:31 -0500 Subject: [PATCH 01/36] Add skeleton for a score method for categorical forecasts --- R/score.R | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/R/score.R b/R/score.R index 4cd65ed79..bcbc2d911 100644 --- a/R/score.R +++ b/R/score.R @@ -98,6 +98,28 @@ score.forecast_binary <- function(data, metrics = rules_binary(), ...) { } +#' @importFrom stats na.omit +#' @importFrom data.table setattr +#' @rdname score +#' @export +score.forecast_categorical <- function(data, metrics = rules_categorical(), ...) { + data <- validate_forecast(data) + data <- na.omit(data) + metrics <- validate_metrics(metrics) + + data <- apply_rules( + data, metrics, + data$observed, data$predicted, ... + # need to add another column, "predicted_class" + ) + + setattr(data, "score_names", names(metrics)) + + return(data[]) + +} + + #' @importFrom Metrics se ae ape #' @importFrom stats na.omit #' @importFrom data.table setattr From be054227d7fcd71824af9e139acb754b5199a1ec Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Wed, 17 Jan 2024 11:45:20 -0500 Subject: [PATCH 02/36] skeleton for validate_forecast method for categorical forecasts --- R/validate.R | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/R/validate.R b/R/validate.R index e737ce003..c254d7428 100644 --- a/R/validate.R +++ b/R/validate.R @@ -83,6 +83,32 @@ validate_forecast.forecast_binary <- function(data, ...) { } +#' @export +#' @keywords check-forecasts +validate_forecast.forecast_categorical <- function(data, ...) { + data <- validate_general(data) + + # must have no sample_id or quantile column + columns_correct <- test_columns_not_present(data, c("sample_id", "quantile")) + if (!columns_correct) { + stop("Checking `data`: Input looks like a categorical forecast, but an", + "additional column called `sample_id` or `quantile` was found.", + "Please remove the column.") + } + + # must have a categorical outcome with more than 2 levels + # probabilities must sum to one + + input_check <- check_input_categorical(data$observed, data$predicted) + if (!is.logical(input_check)) { + stop("Checking `data`:", + "Input looks like a categorical forecast, but found the following issue: ", + input_check) + } + return(data[]) +} + + #' @export #' @keywords check-forecasts validate_forecast.forecast_point <- function(data, ...) { From b1ac2848efe1846ab547771704b53d95e755ae65 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Wed, 17 Jan 2024 11:46:29 -0500 Subject: [PATCH 03/36] add skeleton for default scoring rules for categorical forecasts --- R/default-scoring-rules.R | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/R/default-scoring-rules.R b/R/default-scoring-rules.R index 422d63c3f..56bd0d8d9 100644 --- a/R/default-scoring-rules.R +++ b/R/default-scoring-rules.R @@ -61,6 +61,30 @@ rules_binary <- function(select = NULL, exclude = NULL) { } +#' @title Scoring Rules for Categorical Forecasts +#' @description Helper function that returns a named list of default +#' scoring rules suitable for categorical forecasts. +#' +#' The default scoring rules are: +#' - "brier_score" = [brier_score()] +#' - "log_score" = [logs_binary()] +#' @inherit select_rules params return +#' @export +#' @keywords metric +#' @examples +#' rules_categorical() +#' rules_categorical(select = "brier_score") +#' rules_categorical(exclude = "log_score") +rules_categorical <- function(select = NULL, exclude = NULL) { + all <- list( + # brier_score = brier_score, + # log_score = logs_binary + ) + selected <- select_rules(all, select, exclude) + return(selected) +} + + #' @title Scoring Rules for Point Forecasts #' @description Helper function that returns a named list of default #' scoring rules suitable for point forecasts. From d0f57fb56e2774852b9a4dc2ba0d4a19407f04cb Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Wed, 17 Jan 2024 11:46:51 -0500 Subject: [PATCH 04/36] empty skeleton for check functions for categorical forecasts --- R/check-inputs-scoring-functions.R | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index e0c784ff2..bde3b1bce 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -186,6 +186,27 @@ check_input_binary <- function(observed, predicted) { } +#' @title Assert That Inputs Are Correct For Categorical Forecasts +#' @description Function assesses whether the inputs correspond to the +#' requirements for scoring categorical forecasts. +#' @param observed XX +#' @param predicted XX +#' @importFrom checkmate assert assert_factor +#' @inherit document_assert_functions return +#' @keywords internal_input_check +assert_input_categorical <- function(observed, predicted) { + return(invisible(NULL)) +} + + +#' @title Check That Inputs Are Correct For Categorical Forecasts +#' @inherit assert_input_categorical params description +#' @inherit document_check_functions return +#' @keywords internal_input_check +check_input_categorical <- function(observed, predicted) { +} + + #' @title Assert that inputs are correct for point forecast #' @description Function assesses whether the inputs correspond to the #' requirements for scoring point forecasts. From 3c5c23e1c66cac4fe377c462a7ba7d7a1e3e228e Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 10:42:00 +0200 Subject: [PATCH 05/36] implement nominal forecast class --- NAMESPACE | 5 +++ R/check-inputs-scoring-functions.R | 49 +++++++++++++++++++++++----- R/default-scoring-rules.R | 21 +++++------- R/forecast.R | 17 ++++++++++ R/get_-functions.R | 13 ++++++++ R/metrics-nominal.R | 34 +++++++++++++++++++ R/score.R | 18 ++++------ man/assert_input_nominal.Rd | 24 ++++++++++++++ man/check_input_nominal.Rd | 24 ++++++++++++++ man/metrics_nominal.Rd | 32 ++++++++++++++++++ man/score.Rd | 3 ++ man/scoring-functions-nominal.Rd | 29 ++++++++++++++++ man/test_forecast_type_is_nominal.Rd | 18 ++++++++++ 13 files changed, 256 insertions(+), 31 deletions(-) create mode 100644 R/metrics-nominal.R create mode 100644 man/assert_input_nominal.Rd create mode 100644 man/check_input_nominal.Rd create mode 100644 man/metrics_nominal.Rd create mode 100644 man/scoring-functions-nominal.Rd create mode 100644 man/test_forecast_type_is_nominal.Rd diff --git a/NAMESPACE b/NAMESPACE index 7bbaa1a4e..bdf6232c5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,7 @@ S3method(`[`,scores) S3method(as_forecast,default) S3method(assert_forecast,default) S3method(assert_forecast,forecast_binary) +S3method(assert_forecast,forecast_nominal) S3method(assert_forecast,forecast_point) S3method(assert_forecast,forecast_quantile) S3method(assert_forecast,forecast_sample) @@ -18,6 +19,7 @@ S3method(print,forecast_quantile) S3method(print,forecast_sample) S3method(score,default) S3method(score,forecast_binary) +S3method(score,forecast_nominal) S3method(score,forecast_point) S3method(score,forecast_quantile) S3method(score,forecast_sample) @@ -48,9 +50,11 @@ export(interval_coverage_deviation) export(is_forecast) export(log_shift) export(logs_binary) +export(logs_nominal) export(logs_sample) export(mad_sample) export(metrics_binary) +export(metrics_nominal) export(metrics_point) export(metrics_quantile) export(metrics_sample) @@ -93,6 +97,7 @@ importFrom(checkmate,assert_logical) importFrom(checkmate,assert_matrix) importFrom(checkmate,assert_number) importFrom(checkmate,assert_numeric) +importFrom(checkmate,assert_set_equal) importFrom(checkmate,assert_subset) importFrom(checkmate,assert_vector) importFrom(checkmate,check_atomic_vector) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index e6d23a190..d40d87688 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -193,24 +193,57 @@ check_input_binary <- function(observed, predicted) { } -#' @title Assert That Inputs Are Correct For Categorical Forecasts +#' @title Assert that inputs are correct for nominal forecasts #' @description Function assesses whether the inputs correspond to the -#' requirements for scoring categorical forecasts. -#' @param observed XX -#' @param predicted XX -#' @importFrom checkmate assert assert_factor +#' requirements for scoring nominal forecasts. +#' @param observed XXX +#' @param predicted XXX +#' @param predicted_label XXX +#' @importFrom checkmate assert_factor assert_numeric assert_set_equal #' @inherit document_assert_functions return #' @keywords internal_input_check -assert_input_categorical <- function(observed, predicted) { +assert_input_nominal <- function(observed, predicted, predicted_label) { + # observed + assert_factor(observed, min.len = 1, min.levels = 2) + levels <- levels(observed) + N <- length(levels) + + # predicted label + assert_factor(predicted_label, len = N) + assert_set_equal(levels(observed), levels(predicted_label)) + + # predicted + assert_numeric(observed, min.len = 1, lower = 0, upper = 1) + n <- length(observed) + if (n == 1) { + assert( + # allow one of two options + check_vector(predicted, len = N), + check_matrix(predicted, nrows = n, ncols = N) + ) + summed_predictions <- .rowSums(predicted, m = 1, n = N) + } else { + assert_matrix(predicted, nrows = n_obs) + summed_predictions <- rowSums(predicted) + } + if (!all(summed_predictions == 1)) { + cli_abort( + c( + `!` = "Probabilities belonging to a single forecast must sum to one" + ) + ) + } return(invisible(NULL)) } #' @title Check That Inputs Are Correct For Categorical Forecasts -#' @inherit assert_input_categorical params description +#' @inherit assert_input_nominal params description #' @inherit document_check_functions return #' @keywords internal_input_check -check_input_categorical <- function(observed, predicted) { +check_input_nominal <- function(observed, predicted, predicted_label) { + result <- check_try(assert_input_binary(observed, predicted, predicted_label)) + return(result) } diff --git a/R/default-scoring-rules.R b/R/default-scoring-rules.R index 9b5bd6bf9..1d19634aa 100644 --- a/R/default-scoring-rules.R +++ b/R/default-scoring-rules.R @@ -125,26 +125,23 @@ metrics_binary <- function(select = NULL, exclude = NULL) { } -#' @title Scoring Rules for Categorical Forecasts +#' @title Scoring rules for nominal forecasts #' @description Helper function that returns a named list of default -#' scoring rules suitable for categorical forecasts. +#' scoring rules suitable for nominal forecasts. #' #' The default scoring rules are: -#' - "brier_score" = [brier_score()] -#' - "log_score" = [logs_binary()] -#' @inherit select_rules params return +#' - "log_score" = [logs_nominal()] +#' @inherit select_metrics params return #' @export #' @keywords metric #' @examples -#' rules_categorical() -#' rules_categorical(select = "brier_score") -#' rules_categorical(exclude = "log_score") -rules_categorical <- function(select = NULL, exclude = NULL) { +#' metrics_nominal() +#' metrics_nominal(select = "log_score") +metrics_nominal <- function(select = NULL, exclude = NULL) { all <- list( - # brier_score = brier_score, - # log_score = logs_binary + log_score = logs_nominal ) - selected <- select_rules(all, select, exclude) + selected <- select_metrics(all, select, exclude) return(selected) } diff --git a/R/forecast.R b/R/forecast.R index ffccab287..5fb29e892 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -297,6 +297,23 @@ assert_forecast.forecast_sample <- function( } +#' @export +#' @keywords check-forecasts +assert_forecast.forecast_nominal <- function( + forecast, forecast_type = NULL, verbose = TRUE, ... +) { + forecast <- assert_forecast_generic(forecast, verbose) + assert(check_columns_present(forecast, "predicted_label")) + assert_names(colnames(forecast), disjunct.from = c("sample_id", "quantile_level")) + + assert_forecast_type(forecast, actual = "nominal", desired = forecast_type) + + + assert_input_nominal(forecast) + return(forecast[]) +} + + #' @title Re-validate an existing forecast object #' #' @description diff --git a/R/get_-functions.R b/R/get_-functions.R index a77ffe4a7..874022151 100644 --- a/R/get_-functions.R +++ b/R/get_-functions.R @@ -90,6 +90,19 @@ test_forecast_type_is_quantile <- function(data) { return(observed_correct && predicted_correct && columns_correct) } +#' Test whether data could be a nominal forecast. +#' @description Checks type of the necessary columns. +#' @inheritParams document_check_functions +#' @return Returns TRUE if basic requirements are satisfied and FALSE otherwise +#' @keywords internal_input_check +test_forecast_type_is_nominal <- function(data) { + observed_correct <- test_factor(x = data$observed) + predicted_correct <- test_numeric(x = data$predicted) + columns_correct <- test_columns_present(data, "predicted_label") + predicted_label_correct <- test_factor(x = data$predicted_label) + return(observed_correct && predicted_correct && + columns_correct && predicted_label_correct) +} #' Assert that forecast type is as expected #' @param data A forecast object as produced by [as_forecast()]. diff --git a/R/metrics-nominal.R b/R/metrics-nominal.R new file mode 100644 index 000000000..15727f91c --- /dev/null +++ b/R/metrics-nominal.R @@ -0,0 +1,34 @@ +#' Log score for nominal outcomes +#' +#' @description +#' **Log score for nominal outcomes** +#' +#' The Log Score is the negative logarithm of the probability +#' assigned to the observed value. It is a proper scoring rule. Small values +#' are better (best is zero, worst is infinity). +#' +#' @return A numeric vector of size n with log scores +#' @importFrom methods hasArg +#' @export +#' @keywords metric +#' @rdname scoring-functions-nominal +#' @examples +#' factor_levels <- c("one", "two", "three") +#' predicted_label <- factor(c("one", "two", "three"), levels = factor_levels) +#' observed <- factor(c("one", "three", "two"), levels = factor_levels) +#' predicted <- matrix(c(0.8, 0.1, 0.1, +#' 0.1, 0.2, 0.7, +#' 0.4, 0.4, 0.2), +#' nrow = 3) +#' logs_nominal(observed, predicted, predicted_label) +logs_nominal <- function(observed, predicted, predicted_label) { + assert_input_nominal(observed, predicted, predicted_label) + n <- length(observed) + if (n == 1) { + predicted <- matrix(predicted, nrow = 1) + } + observed_indices <- as.numeric(observed) + pred_for_observed <- predicted[cbind(1:n, observed_indices)] + logs <- -log(pred_for_observed) + return(logs) +} diff --git a/R/score.R b/R/score.R index dcb68ec9f..694e44441 100644 --- a/R/score.R +++ b/R/score.R @@ -104,21 +104,17 @@ score.forecast_binary <- function(forecast, metrics = metrics_binary(), ...) { #' @importFrom data.table setattr #' @rdname score #' @export -score.forecast_categorical <- function(data, metrics = rules_categorical(), ...) { - data <- validate_forecast(data) - data <- na.omit(data) +score.forecast_nominal <- function(data, metrics = metrics_nominal(), ...) { + forecast <- clean_forecast(forecast, copy = TRUE, na.omit = TRUE) metrics <- validate_metrics(metrics) - data <- apply_rules( - data, metrics, - data$observed, data$predicted, ... - # need to add another column, "predicted_class" + scores <- apply_metrics( + forecast, metrics, + forecast$observed, forecast$predicted, forecast$predicted_label, ... ) - setattr(data, "score_names", names(metrics)) - - return(data[]) - + scores <- as_scores(scores, metrics = names(metrics)) + return(scores[]) } diff --git a/man/assert_input_nominal.Rd b/man/assert_input_nominal.Rd new file mode 100644 index 000000000..596d26ccf --- /dev/null +++ b/man/assert_input_nominal.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check-inputs-scoring-functions.R +\name{assert_input_nominal} +\alias{assert_input_nominal} +\title{Assert that inputs are correct for nominal forecasts} +\usage{ +assert_input_nominal(observed, predicted, predicted_label) +} +\arguments{ +\item{observed}{XXX} + +\item{predicted}{XXX} + +\item{predicted_label}{XXX} +} +\value{ +Returns NULL invisibly if the assertion was successful and throws an +error otherwise. +} +\description{ +Function assesses whether the inputs correspond to the +requirements for scoring nominal forecasts. +} +\keyword{internal_input_check} diff --git a/man/check_input_nominal.Rd b/man/check_input_nominal.Rd new file mode 100644 index 000000000..dac5551c0 --- /dev/null +++ b/man/check_input_nominal.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check-inputs-scoring-functions.R +\name{check_input_nominal} +\alias{check_input_nominal} +\title{Check That Inputs Are Correct For Categorical Forecasts} +\usage{ +check_input_nominal(observed, predicted, predicted_label) +} +\arguments{ +\item{observed}{XXX} + +\item{predicted}{XXX} + +\item{predicted_label}{XXX} +} +\value{ +Returns TRUE if the check was successful and a string with an +error message otherwise. +} +\description{ +Function assesses whether the inputs correspond to the +requirements for scoring nominal forecasts. +} +\keyword{internal_input_check} diff --git a/man/metrics_nominal.Rd b/man/metrics_nominal.Rd new file mode 100644 index 000000000..44da05aa2 --- /dev/null +++ b/man/metrics_nominal.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/default-scoring-rules.R +\name{metrics_nominal} +\alias{metrics_nominal} +\title{Scoring rules for nominal forecasts} +\usage{ +metrics_nominal(select = NULL, exclude = NULL) +} +\arguments{ +\item{select}{A character vector of scoring rules to select from the list. If +\code{select} is \code{NULL} (the default), all possible scoring rules are returned.} + +\item{exclude}{A character vector of scoring rules to exclude from the list. +If \code{select} is not \code{NULL}, this argument is ignored.} +} +\value{ +A list of scoring rules. +} +\description{ +Helper function that returns a named list of default +scoring rules suitable for nominal forecasts. + +The default scoring rules are: +\itemize{ +\item "log_score" = \code{\link[=logs_nominal]{logs_nominal()}} +} +} +\examples{ +metrics_nominal() +metrics_nominal(select = "log_score") +} +\keyword{metric} diff --git a/man/score.Rd b/man/score.Rd index c39b6722c..3f96a4670 100644 --- a/man/score.Rd +++ b/man/score.Rd @@ -3,6 +3,7 @@ \name{score} \alias{score} \alias{score.forecast_binary} +\alias{score.forecast_nominal} \alias{score.forecast_point} \alias{score.forecast_sample} \alias{score.forecast_quantile} @@ -12,6 +13,8 @@ score(forecast, metrics, ...) \method{score}{forecast_binary}(forecast, metrics = metrics_binary(), ...) +\method{score}{forecast_nominal}(data, metrics = metrics_nominal(), ...) + \method{score}{forecast_point}(forecast, metrics = metrics_point(), ...) \method{score}{forecast_sample}(forecast, metrics = metrics_sample(), ...) diff --git a/man/scoring-functions-nominal.Rd b/man/scoring-functions-nominal.Rd new file mode 100644 index 000000000..37b74ffbd --- /dev/null +++ b/man/scoring-functions-nominal.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/metrics-nominal.R +\name{logs_nominal} +\alias{logs_nominal} +\title{Log score for nominal outcomes} +\usage{ +logs_nominal(observed, predicted, predicted_label) +} +\value{ +A numeric vector of size n with log scores +} +\description{ +\strong{Log score for nominal outcomes} + +The Log Score is the negative logarithm of the probability +assigned to the observed value. It is a proper scoring rule. Small values +are better (best is zero, worst is infinity). +} +\examples{ +factor_levels <- c("one", "two", "three") +predicted_label <- factor(c("one", "two", "three"), levels = factor_levels) +observed <- factor(c("one", "three", "two"), levels = factor_levels) +predicted <- matrix(c(0.8, 0.1, 0.1, + 0.1, 0.2, 0.7, + 0.4, 0.4, 0.2), + nrow = 3) +logs_nominal(observed, predicted, predicted_label) +} +\keyword{metric} diff --git a/man/test_forecast_type_is_nominal.Rd b/man/test_forecast_type_is_nominal.Rd new file mode 100644 index 000000000..1994d8bfb --- /dev/null +++ b/man/test_forecast_type_is_nominal.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_-functions.R +\name{test_forecast_type_is_nominal} +\alias{test_forecast_type_is_nominal} +\title{Test whether data could be a nominal forecast.} +\usage{ +test_forecast_type_is_nominal(data) +} +\arguments{ +\item{data}{A data.frame or similar to be checked} +} +\value{ +Returns TRUE if basic requirements are satisfied and FALSE otherwise +} +\description{ +Checks type of the necessary columns. +} +\keyword{internal_input_check} From 34be31a5171f6309e1e39bc6265cef903f928b47 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 11:59:56 +0200 Subject: [PATCH 06/36] fix issues --- NAMESPACE | 1 + R/check-inputs-scoring-functions.R | 8 ++++---- R/forecast.R | 1 + R/metrics-nominal.R | 14 ++++++++++---- R/score.R | 2 +- man/score.Rd | 2 +- man/scoring-functions-nominal.Rd | 17 ++++++++++++++--- 7 files changed, 32 insertions(+), 13 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index bdf6232c5..86edc243f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -95,6 +95,7 @@ importFrom(checkmate,assert_function) importFrom(checkmate,assert_list) importFrom(checkmate,assert_logical) importFrom(checkmate,assert_matrix) +importFrom(checkmate,assert_names) importFrom(checkmate,assert_number) importFrom(checkmate,assert_numeric) importFrom(checkmate,assert_set_equal) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index d40d87688..dc5730106 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -206,6 +206,7 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { # observed assert_factor(observed, min.len = 1, min.levels = 2) levels <- levels(observed) + n <- length(observed) N <- length(levels) # predicted label @@ -213,8 +214,7 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { assert_set_equal(levels(observed), levels(predicted_label)) # predicted - assert_numeric(observed, min.len = 1, lower = 0, upper = 1) - n <- length(observed) + assert_numeric(predicted, min.len = 1, lower = 0, upper = 1) if (n == 1) { assert( # allow one of two options @@ -223,7 +223,7 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { ) summed_predictions <- .rowSums(predicted, m = 1, n = N) } else { - assert_matrix(predicted, nrows = n_obs) + assert_matrix(predicted, nrows = n) summed_predictions <- rowSums(predicted) } if (!all(summed_predictions == 1)) { @@ -242,7 +242,7 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { #' @inherit document_check_functions return #' @keywords internal_input_check check_input_nominal <- function(observed, predicted, predicted_label) { - result <- check_try(assert_input_binary(observed, predicted, predicted_label)) + result <- check_try(assert_input_nominal(observed, predicted, predicted_label)) return(result) } diff --git a/R/forecast.R b/R/forecast.R index 5fb29e892..0cdda6f09 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -299,6 +299,7 @@ assert_forecast.forecast_sample <- function( #' @export #' @keywords check-forecasts +#' @importFrom checkmate assert_names assert_forecast.forecast_nominal <- function( forecast, forecast_type = NULL, verbose = TRUE, ... ) { diff --git a/R/metrics-nominal.R b/R/metrics-nominal.R index 15727f91c..103ef9d4a 100644 --- a/R/metrics-nominal.R +++ b/R/metrics-nominal.R @@ -6,7 +6,13 @@ #' The Log Score is the negative logarithm of the probability #' assigned to the observed value. It is a proper scoring rule. Small values #' are better (best is zero, worst is infinity). -#' +#' @param observed A factor of length n with N levels holding the observed +#' values. +#' @param predicted nxN matrix of predictive probabilities, n (number of rows) +#' being the number of observations and N (number of columns) the number of +#' possible outcomes. +#' @param predicted_label A factor of length N, denoting the outcome that the +#' probabilities in `predicted` correspond to. #' @return A numeric vector of size n with log scores #' @importFrom methods hasArg #' @export @@ -16,9 +22,9 @@ #' factor_levels <- c("one", "two", "three") #' predicted_label <- factor(c("one", "two", "three"), levels = factor_levels) #' observed <- factor(c("one", "three", "two"), levels = factor_levels) -#' predicted <- matrix(c(0.8, 0.1, 0.1, -#' 0.1, 0.2, 0.7, -#' 0.4, 0.4, 0.2), +#' predicted <- matrix(c(0.8, 0.1, 0.4, +#' 0.1, 0.2, 0.4, +#' 0.1, 0.7, 0.2), #' nrow = 3) #' logs_nominal(observed, predicted, predicted_label) logs_nominal <- function(observed, predicted, predicted_label) { diff --git a/R/score.R b/R/score.R index 694e44441..e36e1894c 100644 --- a/R/score.R +++ b/R/score.R @@ -104,7 +104,7 @@ score.forecast_binary <- function(forecast, metrics = metrics_binary(), ...) { #' @importFrom data.table setattr #' @rdname score #' @export -score.forecast_nominal <- function(data, metrics = metrics_nominal(), ...) { +score.forecast_nominal <- function(forecast, metrics = metrics_nominal(), ...) { forecast <- clean_forecast(forecast, copy = TRUE, na.omit = TRUE) metrics <- validate_metrics(metrics) diff --git a/man/score.Rd b/man/score.Rd index 3f96a4670..6f13b3bf8 100644 --- a/man/score.Rd +++ b/man/score.Rd @@ -13,7 +13,7 @@ score(forecast, metrics, ...) \method{score}{forecast_binary}(forecast, metrics = metrics_binary(), ...) -\method{score}{forecast_nominal}(data, metrics = metrics_nominal(), ...) +\method{score}{forecast_nominal}(forecast, metrics = metrics_nominal(), ...) \method{score}{forecast_point}(forecast, metrics = metrics_point(), ...) diff --git a/man/scoring-functions-nominal.Rd b/man/scoring-functions-nominal.Rd index 37b74ffbd..dfc400556 100644 --- a/man/scoring-functions-nominal.Rd +++ b/man/scoring-functions-nominal.Rd @@ -6,6 +6,17 @@ \usage{ logs_nominal(observed, predicted, predicted_label) } +\arguments{ +\item{observed}{A factor of length n with N levels holding the observed +values.} + +\item{predicted}{nxN matrix of predictive probabilities, n (number of rows) +being the number of observations and N (number of columns) the number of +possible outcomes.} + +\item{predicted_label}{A factor of length N, denoting the outcome that the +probabilities in \code{predicted} correspond to.} +} \value{ A numeric vector of size n with log scores } @@ -20,9 +31,9 @@ are better (best is zero, worst is infinity). factor_levels <- c("one", "two", "three") predicted_label <- factor(c("one", "two", "three"), levels = factor_levels) observed <- factor(c("one", "three", "two"), levels = factor_levels) -predicted <- matrix(c(0.8, 0.1, 0.1, - 0.1, 0.2, 0.7, - 0.4, 0.4, 0.2), +predicted <- matrix(c(0.8, 0.1, 0.4, + 0.1, 0.2, 0.4, + 0.1, 0.7, 0.2), nrow = 3) logs_nominal(observed, predicted, predicted_label) } From bf71982195065b1edcc594b3b81b8c648b5691c8 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 15:41:43 +0200 Subject: [PATCH 07/36] make code work --- R/check-inputs-scoring-functions.R | 2 +- R/forecast.R | 8 ++++---- R/get_-functions.R | 10 ++++++---- R/score.R | 18 +++++++++++++++--- man/as_forecast.Rd | 1 + 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index dc5730106..f418fbc39 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -224,7 +224,7 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { summed_predictions <- .rowSums(predicted, m = 1, n = N) } else { assert_matrix(predicted, nrows = n) - summed_predictions <- rowSums(predicted) + summed_predictions <- round(rowSums(predicted), 10) # avoid numeric errors } if (!all(summed_predictions == 1)) { cli_abort( diff --git a/R/forecast.R b/R/forecast.R index 0cdda6f09..dda1dfb47 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -75,6 +75,7 @@ as_forecast.default <- function(data, model = NULL, quantile_level = NULL, sample_id = NULL, + predicted_label = NULL, ...) { # check inputs data <- ensure_data.table(data) @@ -109,6 +110,9 @@ as_forecast.default <- function(data, if (!is.null(sample_id)) { setnames(data, old = sample_id, new = "sample_id") } + if (!is.null(predicted_label)) { + setnames(data, old = predicted_label, new = "predicted_label") + } # ensure that a model column is present after renaming ensure_model_column(data) @@ -306,11 +310,7 @@ assert_forecast.forecast_nominal <- function( forecast <- assert_forecast_generic(forecast, verbose) assert(check_columns_present(forecast, "predicted_label")) assert_names(colnames(forecast), disjunct.from = c("sample_id", "quantile_level")) - assert_forecast_type(forecast, actual = "nominal", desired = forecast_type) - - - assert_input_nominal(forecast) return(forecast[]) } diff --git a/R/get_-functions.R b/R/get_-functions.R index 874022151..8acfc0908 100644 --- a/R/get_-functions.R +++ b/R/get_-functions.R @@ -16,7 +16,9 @@ get_forecast_type <- function(data) { assert_data_frame(data) assert(check_columns_present(data, c("observed", "predicted"))) - if (test_forecast_type_is_binary(data)) { + if (test_forecast_type_is_nominal(data)) { + forecast_type <- "nominal" + } else if (test_forecast_type_is_binary(data)) { forecast_type <- "binary" } else if (test_forecast_type_is_quantile(data)) { forecast_type <- "quantile" @@ -275,7 +277,7 @@ get_protected_columns <- function(data = NULL) { protected_columns <- c( "predicted", "observed", "sample_id", "quantile_level", "upper", "lower", - "pit_value", "interval_range", "boundary", + "pit_value", "interval_range", "boundary", "predicted_label", "interval_coverage", "interval_coverage_deviation", "quantile_coverage", "quantile_coverage_deviation", grep("_relative_skill$", names(data), value = TRUE), @@ -319,8 +321,8 @@ get_duplicate_forecasts <- function( ) { assert_data_frame(data) forecast_unit <- get_forecast_unit(data) - available_type <- c("sample_id", "quantile_level") %in% colnames(data) - type <- c("sample_id", "quantile_level")[available_type] + available_type <- c("sample_id", "quantile_level", "predicted_label") %in% colnames(data) + type <- c("sample_id", "quantile_level", "predicted_label")[available_type] data <- as.data.table(data) data[, scoringutils_InternalDuplicateCheck := .N, by = c(forecast_unit, type)] out <- data[scoringutils_InternalDuplicateCheck > 1] diff --git a/R/score.R b/R/score.R index e36e1894c..fdbb3091d 100644 --- a/R/score.R +++ b/R/score.R @@ -106,13 +106,25 @@ score.forecast_binary <- function(forecast, metrics = metrics_binary(), ...) { #' @export score.forecast_nominal <- function(forecast, metrics = metrics_nominal(), ...) { forecast <- clean_forecast(forecast, copy = TRUE, na.omit = TRUE) + forecast_unit <- get_forecast_unit(forecast) metrics <- validate_metrics(metrics) + # transpose the forecasts that belong to the same forecast unit + # make sure the labels and predictions are ordered in the same way + f_transposed <- forecast[, .( + predicted = list(predicted[order(predicted_label)]), + observed = unique(observed) + ), by = forecast_unit] + + observed <- f_transposed$observed + predicted <- do.call(rbind, f_transposed$predicted) + predicted_label <- sort(unique(forecast$predicted_label, na.last = TRUE)) + f_transposed[, c("observed", "predicted") := NULL] + scores <- apply_metrics( - forecast, metrics, - forecast$observed, forecast$predicted, forecast$predicted_label, ... + f_transposed, metrics, + observed, predicted, predicted_label, ... ) - scores <- as_scores(scores, metrics = names(metrics)) return(scores[]) } diff --git a/man/as_forecast.Rd b/man/as_forecast.Rd index 91a4e5e8c..3f6df07b1 100644 --- a/man/as_forecast.Rd +++ b/man/as_forecast.Rd @@ -16,6 +16,7 @@ as_forecast(data, ...) model = NULL, quantile_level = NULL, sample_id = NULL, + predicted_label = NULL, ... ) } From 5eadf04b4d2870c8d1683f8d638431b99f29277a Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 15:41:52 +0200 Subject: [PATCH 08/36] add example data --- data/example_nominal.rda | Bin 0 -> 3597 bytes inst/create-example-data.R | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 data/example_nominal.rda diff --git a/data/example_nominal.rda b/data/example_nominal.rda new file mode 100644 index 0000000000000000000000000000000000000000..dc30b272bcf57f0ba37a8786f4a21cc99e5f7a29 GIT binary patch literal 3597 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 low_bound & predicted <= high_bound)] +example_nominal[, high := (predicted > high_bound)] + +example_nominal[, observed := ifelse( + observed < low_bound, "low", + ifelse(observed >= low_bound & observed <= high_bound, + "medium", "high"))] + +example_nominal <- example_nominal[ + , .(low = mean(low), + medium = mean(medium), + high = mean(high)), + by = c(by_vars, "model", "observed") +] +example_nominal <- melt( + example_nominal, measure.vars = c("low", "high", "medium"), + value.name = "predicted", variable.name = "predicted_label" +) + +example_nominal[, `:=`( + observed = factor(observed, levels = c("low", "medium", "high")), + predicted_label = factor(predicted_label, levels = c("low", "medium", "high")) +)] + +usethis::use_data(example_nominal, overwrite = TRUE) From 5e80e293e27439d0655b72d2ed5c0fd6e5252c6c Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 16:33:25 +0200 Subject: [PATCH 09/36] fix warnings --- R/data.R | 27 +++++++++++++++++++++++++++ R/forecast.R | 4 ++++ data/example_nominal.rda | Bin 3597 -> 3684 bytes inst/create-example-data.R | 3 ++- man/as_forecast.Rd | 5 +++++ man/example_nominal.Rd | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 man/example_nominal.Rd diff --git a/R/data.R b/R/data.R index 69651d166..ca4519a44 100644 --- a/R/data.R +++ b/R/data.R @@ -137,3 +137,30 @@ #' @source \url{https://github.com/european-modelling-hubs/covid19-forecast-hub-europe/commit/a42867b1ea152c57e25b04f9faa26cfd4bfd8fa6/} # nolint end "example_binary" + + +#' Nominal example data +#' +#' A data set with predictions for COVID-19 cases and deaths submitted to the +#' European Forecast Hub. +#' +#' The data was created using the script create-example-data.R in the inst/ +#' folder (or the top level folder in a compiled package). +#' +#' @format A data frame with the following columns: +#' \describe{ +#' \item{location}{the country for which a prediction was made} +#' \item{target_end_date}{the date for which a prediction was made} +#' \item{target_type}{the target to be predicted (cases or deaths)} +#' \item{observed}{Numeric: observed values} +#' \item{location_name}{name of the country for which a prediction was made} +#' \item{forecast_date}{the date on which a prediction was made} +#' \item{predicted_label}{outcome that a probabilty corresponds to} +#' \item{predicted}{predicted value} +#' \item{model}{name of the model that generated the forecasts} +#' \item{horizon}{forecast horizon in weeks} +#' } +# nolint start +#' @source \url{https://github.com/european-modelling-hubs/covid19-forecast-hub-europe/commit/a42867b1ea152c57e25b04f9faa26cfd4bfd8fa6/} +# nolint end +"example_nominal" diff --git a/R/forecast.R b/R/forecast.R index dda1dfb47..785fe3a87 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -65,6 +65,10 @@ as_forecast <- function(data, #' @param sample_id (optional) Name of the column in `data` that contains the #' sample id. This column will be renamed to "sample_id". Only applicable to #' sample-based forecasts. +#' @param predicted_label (optional) Name of the column in `data` that denotes +#' the outcome to which a preidcted probability corresponds to. +#' This column will be renamed to "predicted_label". Only applicable to +#' nominal forecasts. #' @export #' @importFrom cli cli_warn as_forecast.default <- function(data, diff --git a/data/example_nominal.rda b/data/example_nominal.rda index dc30b272bcf57f0ba37a8786f4a21cc99e5f7a29..a9a278fb1d5ab924aaaf6b113c1eb44469b738f2 100644 GIT binary patch delta 3298 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 delta 3210 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 Date: Fri, 7 Jun 2024 22:04:15 +0200 Subject: [PATCH 10/36] add tests --- R/check-inputs-scoring-functions.R | 13 ++- tests/testthat/test-forecast.R | 9 ++ tests/testthat/test-metrics-nominal.R | 116 ++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 tests/testthat/test-metrics-nominal.R diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index f418fbc39..6f0fb1606 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -210,7 +210,10 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { N <- length(levels) # predicted label - assert_factor(predicted_label, len = N) + assert_factor( + predicted_label, len = N, + any.missing = FALSE, empty.levels.ok = FALSE + ) assert_set_equal(levels(observed), levels(predicted_label)) # predicted @@ -221,15 +224,17 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { check_vector(predicted, len = N), check_matrix(predicted, nrows = n, ncols = N) ) - summed_predictions <- .rowSums(predicted, m = 1, n = N) + summed_predictions <- .rowSums(predicted, m = 1, n = N, na.rm = TRUE) } else { assert_matrix(predicted, nrows = n) - summed_predictions <- round(rowSums(predicted), 10) # avoid numeric errors + summed_predictions <- round(rowSums(predicted, na.rm = TRUE), 10) # avoid numeric errors } if (!all(summed_predictions == 1)) { + row_indices <- as.character(which(summed_predictions != 1)) cli_abort( c( - `!` = "Probabilities belonging to a single forecast must sum to one" + `!` = "Probabilities belonging to a single forecast must sum to one", + `i` = "Found issues in row{?s} {row_indices} of {.var predicted}" ) ) } diff --git a/tests/testthat/test-forecast.R b/tests/testthat/test-forecast.R index f95fddde4..435268c72 100644 --- a/tests/testthat/test-forecast.R +++ b/tests/testthat/test-forecast.R @@ -192,6 +192,15 @@ test_that("as_forecast() produces a warning if outdated formats are used", { ) }) +# as_forecast.forecast_nominal() ----------------------------------------------- +test_that("as_forecast() works with a forecast_nominal object", { + expect_s3_class( + as_forecast(example_nominal), + c("forecast_nominal", "data.table", "data.frame"), + exact = TRUE + ) +}) + # ============================================================================== # is_forecast() diff --git a/tests/testthat/test-metrics-nominal.R b/tests/testthat/test-metrics-nominal.R new file mode 100644 index 000000000..cfba86e4c --- /dev/null +++ b/tests/testthat/test-metrics-nominal.R @@ -0,0 +1,116 @@ +factor_levels <- c("one", "two", "three") +predicted_label <- factor(c("one", "two", "three"), levels = factor_levels) +observed <- factor(c("one", "two", "two"), levels = factor_levels) +predicted <- matrix(c(0.8, 0.1, 0.4, + 0.1, 0.2, 0.4, + 0.1, 0.7, 0.2), + nrow = 3) + + +# ============================================================================ # +# Input handling =============================================================== +# ============================================================================ # +test_that("Input checking for nominal forecasts works", { + # everything correct + expect_no_condition( + scoringutils:::assert_input_nominal(observed, predicted, predicted_label) + ) + + # observed and predicted_label have different level lengths + observed_wrong <- factor(observed, levels = c("one", "two")) + expect_error( + scoringutils:::assert_input_nominal(observed_wrong, predicted, predicted_label), + "Assertion on 'predicted_label' failed: Must have length 2, but has length 3." + ) + + # observed and predicted_label have different levels, resulting in an `NA` in predicted_label + predicted_label_wrong <- factor(predicted_label, levels = c("one", "two", "four")) + expect_error( + scoringutils:::assert_input_nominal(observed, predicted, predicted_label_wrong), + "Assertion on 'predicted_label' failed: Contains missing values" + ) + + # 6 observations, but only 3 forecasts + expect_error( + scoringutils:::assert_input_nominal(c(observed, observed), predicted, predicted_label), + "Assertion on 'predicted' failed: Must have exactly 6 rows, but has 3 rows." + ) + + # observed value or predicted_label is not factor + expect_error( + scoringutils:::assert_input_nominal(as.numeric(observed), predicted, predicted_label), + "Assertion on 'observed' failed: Must be of type 'factor', not 'double'." + ) + expect_error( + scoringutils:::assert_input_nominal(observed, predicted, as.character(predicted_label)), + "Assertion on 'predicted_label' failed: Must be of type 'factor', not 'character'." + ) + + # a single observation + expect_no_condition( + scoringutils:::assert_input_nominal(observed[1], predicted[1, ], predicted_label), + ) + expect_no_condition( + scoringutils:::assert_input_nominal(observed[1], as.numeric(predicted[1, ]), predicted_label), + ) + + # wrong dimensions + expect_error( + scoringutils:::assert_input_nominal(observed[1], predicted, predicted_label), + "One of the following must apply:" + ) + + # NA values in observed are permitted + observed2 <- c(observed[1:2], observed["missing"]) + expect_no_condition( + scoringutils:::assert_input_nominal(observed2, predicted, predicted_label) + ) + + # NA values in predicted are permitted and treated as zeros + # (as long as probabilities still sum to one) + predicted2 <- predicted + predicted2[2, 2] <- NA + expect_error( + scoringutils:::assert_input_nominal(observed, predicted2, predicted_label), + "Probabilities belonging to a single forecast must sum to one" + ) + predicted2[2, 1] <- 0.3 + expect_no_condition( + scoringutils:::assert_input_nominal(observed, predicted2, predicted_label) + ) +}) + + +# ============================================================================ # +# logs nominal =============================================================== # +# ============================================================================ # +test_that("logs_nominal() works as expected", { + expect_no_condition( + res <- logs_nominal(observed, predicted, predicted_label) + ) + res_manual <- -log(c(predicted[1, 1], predicted[2, 2], predicted[3, 2])) + expect_equal(res, res_manual) + + # log scores still work if there are NA values in probabilities that have + # not materialised + predicted2 <- predicted + predicted2[2, c(1, 3)] <- c(NA, 0.8) + expect_equal( + logs_nominal(observed, predicted2, predicted_label), + res_manual + ) + + # relevant NAs in predictions lead to NA outcomes + predicted2[1, 1:2] <- c(NA, 0.9) + expect_equal( + logs_nominal(observed, predicted2, predicted_label), + c(NA, res_manual[-1]) + ) + + # NA values in observed values lead to NAs in result + observed2 <- c(observed["nothing"], observed[-1]) + expect_equal( + logs_nominal(observed2, predicted, predicted_label), + c(NA, res_manual[-1]) + ) +}) From 4681f9272c2732ca110c0fd243c22792845a0bf7 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 23:41:39 +0200 Subject: [PATCH 11/36] Refine tests and docs --- NAMESPACE | 1 - NEWS.md | 4 ++-- R/documentation-templates.R | 10 +++++++++- R/forecast.R | 26 +++++++++++++++++++++++++- man/as_forecast.Rd | 10 +++++++++- man/assert_forecast.Rd | 10 +++++++++- man/forecast_types.Rd | 10 +++++++++- man/get_forecast_type.Rd | 10 +++++++++- man/score.Rd | 10 +++++++++- tests/testthat/test-forecast.R | 13 ++++++++++++- 10 files changed, 93 insertions(+), 11 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 86edc243f..bdf6232c5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -95,7 +95,6 @@ importFrom(checkmate,assert_function) importFrom(checkmate,assert_list) importFrom(checkmate,assert_logical) importFrom(checkmate,assert_matrix) -importFrom(checkmate,assert_names) importFrom(checkmate,assert_number) importFrom(checkmate,assert_numeric) importFrom(checkmate,assert_set_equal) diff --git a/NEWS.md b/NEWS.md index aa487da18..27822a4ca 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,12 +12,12 @@ of our [original](https://doi.org/10.48550/arXiv.2205.07090) `scoringutils` pape ### `score()` - The main function of the package is still the function `score()`. However, we reworked the function and updated and clarified its input requirements. - The previous columns "true_value" and "prediction" were renamed. `score()` now requires columns called "observed" and "predicted" and "model". The column `quantile` was renamed to `quantile_level` and `sample` was renamed to `sample_id` - - `score()` is now a generic. It has S3 methods for the classes `forecast_point`, `forecast_binary`, `forecast_quantile` and `forecast_sample`, which correspond to the different forecast types that can be scored with `scoringutils`. + - `score()` is now a generic. It has S3 methods for the classes `forecast_point`, `forecast_binary`, `forecast_quantile`, `forecast_sample`, and `forecast_nominal`, which correspond to the different forecast types that can be scored with `scoringutils`. - `score()` now calls `na.omit()` on the data, instead of only removing rows with missing values in the columns `observed` and `predicted`. This is because `NA` values in other columns can also mess up e.g. grouping of forecasts according to the unit of a single forecast. - `score()` and many other functions now require a validated `forecast` object. `forecast` objects can be created using the function `as_forecast()` (which replaces the previous `check_forecast()`). `score()` now returns objects of class `scores` with a stored attribute `metrics` that holds the names of the scoring rules that were used. Users can call `get_metrics()` to access the names of those scoring rules. - `score()` now returns one score per forecast, instead of one score per sample or quantile. - - Users can now also use their own scoring rules (making use of the `metrics` argument, which takes in a named list of functions). Default scoring rules can be accessed using the functions `metrics_point()`, `metrics_sample()`, `metrics_quantile()` and `metrics_binary()`, which return a named list of scoring rules suitable for the respective forecast type. Column names of scores in the output of `score()` correspond to the names of the scoring rules (i.e. the names of the functions in the list of metrics). + - Users can now also use their own scoring rules (making use of the `metrics` argument, which takes in a named list of functions). Default scoring rules can be accessed using the functions `metrics_point()`, `metrics_sample()`, `metrics_quantile()`, `metrics_binary()`, and `metrisc_nominal()`, which return a named list of scoring rules suitable for the respective forecast type. Column names of scores in the output of `score()` correspond to the names of the scoring rules (i.e. the names of the functions in the list of metrics). - Instead of supplying arguments to `score()` to manipulate individual scoring rules users should now manipulate the metric list being supplied using `customise_metric()` and `select_metric()`. ### Creating a forecast object diff --git a/R/documentation-templates.R b/R/documentation-templates.R index 9878d8cbe..2cfed3ee1 100644 --- a/R/documentation-templates.R +++ b/R/documentation-templates.R @@ -6,6 +6,7 @@ #' moment, those are: #' - point forecasts #' - binary forecasts ("soft binary classification") +#' - nominal forecasts ("soft classification with multiple unordered classes") #' - Probabilistic forecasts in a quantile-based format (a forecast is #' represented as a set of predictive quantiles) #' - Probabilistic forecasts in a sample-based format (a forecast is represented @@ -33,6 +34,13 @@ #' corresponding to the probability that `observed` is equal to the second #' factor level. See details [here][brier_score()] for more information. #' +#' *Nominal forecasts* require a column `observed` of type factor with N levels, +#' (where N is the number of possible outcomes), a column `predicted` of type +#' numeric with probabilities (which sum to one across all possible outcomes), +#' and a column `predicted_label` of type factor with N levels, denoting the +#' outcome for which a probability is given. Forecasts must be complete, i.e. +#' there must be a probability assigned to every possible outcome. +#' #' *Quantile-based forecasts* require a column `observed` of type numeric, #' a column `predicted` of type numeric, and a column `quantile_level` of type #' numeric with quantile-levels (between 0 and 1). @@ -43,7 +51,7 @@ #' #' For more information see the vignettes and the example data #' ([example_quantile], [example_sample_continuous], [example_sample_discrete], -#' [example_point()], and [example_binary]). +#' [example_point()], [example_binary], and [example_nominal]). #' #' @details # Forecast unit #' diff --git a/R/forecast.R b/R/forecast.R index 785fe3a87..d96de18ac 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -307,7 +307,7 @@ assert_forecast.forecast_sample <- function( #' @export #' @keywords check-forecasts -#' @importFrom checkmate assert_names +#' @importFrom checkmate assert_names, assert_set_equal assert_forecast.forecast_nominal <- function( forecast, forecast_type = NULL, verbose = TRUE, ... ) { @@ -315,6 +315,30 @@ assert_forecast.forecast_nominal <- function( assert(check_columns_present(forecast, "predicted_label")) assert_names(colnames(forecast), disjunct.from = c("sample_id", "quantile_level")) assert_forecast_type(forecast, actual = "nominal", desired = forecast_type) + + # levels need to be the same + outcomes <- levels(forecast$observed) + assert_set_equal(levels(forecast$predicted_label), outcomes) + + # forecasts need to be complete + forecast_unit <- get_forecast_unit(forecast) + complete <- forecast[, .(correct = test_set_equal( + as.character(predicted_label), outcomes) + ), by = forecast_unit] + + if (any(!complete$correct)) { + issue <- head(complete[(correct), ..forecast_unit], 1) + issue <- lapply(issue, FUN = as.character) + issue_location <- paste(names(issue), "==", issue) + + cli_abort( + c(`!` = "Found incomplete forecasts", + `i` = "For a nominal forecast, all possible outcomes must be assigned + a probability explicitly.", + `i` = "Found first missing probabilities in the forecast specified by + {.emph {issue_location}}") + ) + } return(forecast[]) } diff --git a/man/as_forecast.Rd b/man/as_forecast.Rd index 274808a00..1add867eb 100644 --- a/man/as_forecast.Rd +++ b/man/as_forecast.Rd @@ -92,6 +92,7 @@ moment, those are: \itemize{ \item point forecasts \item binary forecasts ("soft binary classification") +\item nominal forecasts ("soft classification with multiple unordered classes") \item Probabilistic forecasts in a quantile-based format (a forecast is represented as a set of predictive quantiles) \item Probabilistic forecasts in a sample-based format (a forecast is represented @@ -120,6 +121,13 @@ two levels and a column \code{predicted} of type numeric with probabilities, corresponding to the probability that \code{observed} is equal to the second factor level. See details \link[=brier_score]{here} for more information. +\emph{Nominal forecasts} require a column \code{observed} of type factor with N levels, +(where N is the number of possible outcomes), a column \code{predicted} of type +numeric with probabilities (which sum to one across all possible outcomes), +and a column \code{predicted_label} of type factor with N levels, denoting the +outcome for which a probability is given. Forecasts must be complete, i.e. +there must be a probability assigned to every possible outcome. + \emph{Quantile-based forecasts} require a column \code{observed} of type numeric, a column \code{predicted} of type numeric, and a column \code{quantile_level} of type numeric with quantile-levels (between 0 and 1). @@ -130,7 +138,7 @@ numeric with sample indices. For more information see the vignettes and the example data (\link{example_quantile}, \link{example_sample_continuous}, \link{example_sample_discrete}, -\code{\link[=example_point]{example_point()}}, and \link{example_binary}). +\code{\link[=example_point]{example_point()}}, \link{example_binary}, and \link{example_nominal}). } \section{Forecast unit}{ diff --git a/man/assert_forecast.Rd b/man/assert_forecast.Rd index e2858d9e7..25c1c47a7 100644 --- a/man/assert_forecast.Rd +++ b/man/assert_forecast.Rd @@ -51,6 +51,7 @@ moment, those are: \itemize{ \item point forecasts \item binary forecasts ("soft binary classification") +\item nominal forecasts ("soft classification with multiple unordered classes") \item Probabilistic forecasts in a quantile-based format (a forecast is represented as a set of predictive quantiles) \item Probabilistic forecasts in a sample-based format (a forecast is represented @@ -79,6 +80,13 @@ two levels and a column \code{predicted} of type numeric with probabilities, corresponding to the probability that \code{observed} is equal to the second factor level. See details \link[=brier_score]{here} for more information. +\emph{Nominal forecasts} require a column \code{observed} of type factor with N levels, +(where N is the number of possible outcomes), a column \code{predicted} of type +numeric with probabilities (which sum to one across all possible outcomes), +and a column \code{predicted_label} of type factor with N levels, denoting the +outcome for which a probability is given. Forecasts must be complete, i.e. +there must be a probability assigned to every possible outcome. + \emph{Quantile-based forecasts} require a column \code{observed} of type numeric, a column \code{predicted} of type numeric, and a column \code{quantile_level} of type numeric with quantile-levels (between 0 and 1). @@ -89,7 +97,7 @@ numeric with sample indices. For more information see the vignettes and the example data (\link{example_quantile}, \link{example_sample_continuous}, \link{example_sample_discrete}, -\code{\link[=example_point]{example_point()}}, and \link{example_binary}). +\code{\link[=example_point]{example_point()}}, \link{example_binary}, and \link{example_nominal}). } \examples{ diff --git a/man/forecast_types.Rd b/man/forecast_types.Rd index 4c4d2648b..f977e8087 100644 --- a/man/forecast_types.Rd +++ b/man/forecast_types.Rd @@ -12,6 +12,7 @@ moment, those are: \itemize{ \item point forecasts \item binary forecasts ("soft binary classification") +\item nominal forecasts ("soft classification with multiple unordered classes") \item Probabilistic forecasts in a quantile-based format (a forecast is represented as a set of predictive quantiles) \item Probabilistic forecasts in a sample-based format (a forecast is represented @@ -40,6 +41,13 @@ two levels and a column \code{predicted} of type numeric with probabilities, corresponding to the probability that \code{observed} is equal to the second factor level. See details \link[=brier_score]{here} for more information. +\emph{Nominal forecasts} require a column \code{observed} of type factor with N levels, +(where N is the number of possible outcomes), a column \code{predicted} of type +numeric with probabilities (which sum to one across all possible outcomes), +and a column \code{predicted_label} of type factor with N levels, denoting the +outcome for which a probability is given. Forecasts must be complete, i.e. +there must be a probability assigned to every possible outcome. + \emph{Quantile-based forecasts} require a column \code{observed} of type numeric, a column \code{predicted} of type numeric, and a column \code{quantile_level} of type numeric with quantile-levels (between 0 and 1). @@ -50,7 +58,7 @@ numeric with sample indices. For more information see the vignettes and the example data (\link{example_quantile}, \link{example_sample_continuous}, \link{example_sample_discrete}, -\code{\link[=example_point]{example_point()}}, and \link{example_binary}). +\code{\link[=example_point]{example_point()}}, \link{example_binary}, and \link{example_nominal}). } \section{Forecast unit}{ diff --git a/man/get_forecast_type.Rd b/man/get_forecast_type.Rd index 0e831c99f..62c8bda78 100644 --- a/man/get_forecast_type.Rd +++ b/man/get_forecast_type.Rd @@ -26,6 +26,7 @@ moment, those are: \itemize{ \item point forecasts \item binary forecasts ("soft binary classification") +\item nominal forecasts ("soft classification with multiple unordered classes") \item Probabilistic forecasts in a quantile-based format (a forecast is represented as a set of predictive quantiles) \item Probabilistic forecasts in a sample-based format (a forecast is represented @@ -54,6 +55,13 @@ two levels and a column \code{predicted} of type numeric with probabilities, corresponding to the probability that \code{observed} is equal to the second factor level. See details \link[=brier_score]{here} for more information. +\emph{Nominal forecasts} require a column \code{observed} of type factor with N levels, +(where N is the number of possible outcomes), a column \code{predicted} of type +numeric with probabilities (which sum to one across all possible outcomes), +and a column \code{predicted_label} of type factor with N levels, denoting the +outcome for which a probability is given. Forecasts must be complete, i.e. +there must be a probability assigned to every possible outcome. + \emph{Quantile-based forecasts} require a column \code{observed} of type numeric, a column \code{predicted} of type numeric, and a column \code{quantile_level} of type numeric with quantile-levels (between 0 and 1). @@ -64,7 +72,7 @@ numeric with sample indices. For more information see the vignettes and the example data (\link{example_quantile}, \link{example_sample_continuous}, \link{example_sample_discrete}, -\code{\link[=example_point]{example_point()}}, and \link{example_binary}). +\code{\link[=example_point]{example_point()}}, \link{example_binary}, and \link{example_nominal}). } \keyword{check-forecasts} diff --git a/man/score.Rd b/man/score.Rd index 6f13b3bf8..dd6325d5d 100644 --- a/man/score.Rd +++ b/man/score.Rd @@ -61,6 +61,7 @@ moment, those are: \itemize{ \item point forecasts \item binary forecasts ("soft binary classification") +\item nominal forecasts ("soft classification with multiple unordered classes") \item Probabilistic forecasts in a quantile-based format (a forecast is represented as a set of predictive quantiles) \item Probabilistic forecasts in a sample-based format (a forecast is represented @@ -89,6 +90,13 @@ two levels and a column \code{predicted} of type numeric with probabilities, corresponding to the probability that \code{observed} is equal to the second factor level. See details \link[=brier_score]{here} for more information. +\emph{Nominal forecasts} require a column \code{observed} of type factor with N levels, +(where N is the number of possible outcomes), a column \code{predicted} of type +numeric with probabilities (which sum to one across all possible outcomes), +and a column \code{predicted_label} of type factor with N levels, denoting the +outcome for which a probability is given. Forecasts must be complete, i.e. +there must be a probability assigned to every possible outcome. + \emph{Quantile-based forecasts} require a column \code{observed} of type numeric, a column \code{predicted} of type numeric, and a column \code{quantile_level} of type numeric with quantile-levels (between 0 and 1). @@ -99,7 +107,7 @@ numeric with sample indices. For more information see the vignettes and the example data (\link{example_quantile}, \link{example_sample_continuous}, \link{example_sample_discrete}, -\code{\link[=example_point]{example_point()}}, and \link{example_binary}). +\code{\link[=example_point]{example_point()}}, \link{example_binary}, and \link{example_nominal}). } \section{Forecast unit}{ diff --git a/tests/testthat/test-forecast.R b/tests/testthat/test-forecast.R index 435268c72..e4a396fcb 100644 --- a/tests/testthat/test-forecast.R +++ b/tests/testthat/test-forecast.R @@ -193,15 +193,26 @@ test_that("as_forecast() produces a warning if outdated formats are used", { }) # as_forecast.forecast_nominal() ----------------------------------------------- -test_that("as_forecast() works with a forecast_nominal object", { +test_that("as_forecast.forecast_nominal() works as expected", { expect_s3_class( as_forecast(example_nominal), c("forecast_nominal", "data.table", "data.frame"), exact = TRUE ) + + ex_faulty <- data.table::copy(example_nominal) + ex_faulty <- ex_faulty[predicted != 0] + expect_warning( + expect_error( + as_forecast(ex_faulty), + "Found incomplete forecasts" + ), + "Some forecasts have different numbers of rows" + ) }) + # ============================================================================== # is_forecast() # ============================================================================== From b5ef322a417baa84070c4f4cf20e789bd5ceca69 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 23:49:02 +0200 Subject: [PATCH 12/36] improve tests --- NAMESPACE | 2 ++ R/forecast.R | 7 +++++-- tests/testthat/test-forecast.R | 1 - 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index bdf6232c5..b04602fdf 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -95,6 +95,7 @@ importFrom(checkmate,assert_function) importFrom(checkmate,assert_list) importFrom(checkmate,assert_logical) importFrom(checkmate,assert_matrix) +importFrom(checkmate,assert_names) importFrom(checkmate,assert_number) importFrom(checkmate,assert_numeric) importFrom(checkmate,assert_set_equal) @@ -111,6 +112,7 @@ importFrom(checkmate,test_factor) importFrom(checkmate,test_list) importFrom(checkmate,test_names) importFrom(checkmate,test_numeric) +importFrom(checkmate,test_set_equal) importFrom(checkmate,test_subset) importFrom(cli,cli_abort) importFrom(cli,cli_inform) diff --git a/R/forecast.R b/R/forecast.R index d96de18ac..7b9d26704 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -307,13 +307,16 @@ assert_forecast.forecast_sample <- function( #' @export #' @keywords check-forecasts -#' @importFrom checkmate assert_names, assert_set_equal +#' @importFrom checkmate assert_names assert_set_equal test_set_equal assert_forecast.forecast_nominal <- function( forecast, forecast_type = NULL, verbose = TRUE, ... ) { forecast <- assert_forecast_generic(forecast, verbose) assert(check_columns_present(forecast, "predicted_label")) - assert_names(colnames(forecast), disjunct.from = c("sample_id", "quantile_level")) + assert_names( + colnames(forecast), + disjunct.from = c("sample_id", "quantile_level") + ) assert_forecast_type(forecast, actual = "nominal", desired = forecast_type) # levels need to be the same diff --git a/tests/testthat/test-forecast.R b/tests/testthat/test-forecast.R index e4a396fcb..16e3b58fb 100644 --- a/tests/testthat/test-forecast.R +++ b/tests/testthat/test-forecast.R @@ -212,7 +212,6 @@ test_that("as_forecast.forecast_nominal() works as expected", { }) - # ============================================================================== # is_forecast() # ============================================================================== From d666e6485b21440b46ed186dfd85b25d0f1c2365 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Fri, 7 Jun 2024 23:56:14 +0200 Subject: [PATCH 13/36] fix linting issues --- R/check-inputs-scoring-functions.R | 2 ++ R/forecast.R | 9 +++++---- R/z_globalVariables.R | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/R/check-inputs-scoring-functions.R b/R/check-inputs-scoring-functions.R index 6f0fb1606..812a1b78d 100644 --- a/R/check-inputs-scoring-functions.R +++ b/R/check-inputs-scoring-functions.R @@ -230,6 +230,7 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { summed_predictions <- round(rowSums(predicted, na.rm = TRUE), 10) # avoid numeric errors } if (!all(summed_predictions == 1)) { + #nolint start: keyword_quote_linter object_usage_linter row_indices <- as.character(which(summed_predictions != 1)) cli_abort( c( @@ -237,6 +238,7 @@ assert_input_nominal <- function(observed, predicted, predicted_label) { `i` = "Found issues in row{?s} {row_indices} of {.var predicted}" ) ) + #nolint end } return(invisible(NULL)) } diff --git a/R/forecast.R b/R/forecast.R index 7b9d26704..fab550553 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -325,15 +325,15 @@ assert_forecast.forecast_nominal <- function( # forecasts need to be complete forecast_unit <- get_forecast_unit(forecast) - complete <- forecast[, .(correct = test_set_equal( - as.character(predicted_label), outcomes) + complete <- forecast[, .( + correct = test_set_equal(as.character(predicted_label), outcomes) ), by = forecast_unit] - if (any(!complete$correct)) { + if (!all(complete$correct)) { issue <- head(complete[(correct), ..forecast_unit], 1) issue <- lapply(issue, FUN = as.character) + #nolint start: keyword_quote_linter object_usage_linter duplicate_argument_linter issue_location <- paste(names(issue), "==", issue) - cli_abort( c(`!` = "Found incomplete forecasts", `i` = "For a nominal forecast, all possible outcomes must be assigned @@ -341,6 +341,7 @@ assert_forecast.forecast_nominal <- function( `i` = "Found first missing probabilities in the forecast specified by {.emph {issue_location}}") ) + #nolint end } return(forecast[]) } diff --git a/R/z_globalVariables.R b/R/z_globalVariables.R index d2037617d..fa22274a9 100644 --- a/R/z_globalVariables.R +++ b/R/z_globalVariables.R @@ -13,9 +13,11 @@ globalVariables(c( "component_value", "..colnames_x", "..colnames_y", + "..forecast_unit", "..samplecols", "calibration", "compare_against", + "correct", "coverage", "count", "coverage_deviation", From 9aa1e0a5fc39861e51c9c4e5939811aaa29f2730 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sat, 8 Jun 2024 06:42:40 -0700 Subject: [PATCH 14/36] fix issues --- R/forecast.R | 8 ++++---- R/z_globalVariables.R | 1 + tests/testthat/test-metrics-nominal.R | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/R/forecast.R b/R/forecast.R index fab550553..1186984e0 100644 --- a/R/forecast.R +++ b/R/forecast.R @@ -330,15 +330,15 @@ assert_forecast.forecast_nominal <- function( ), by = forecast_unit] if (!all(complete$correct)) { - issue <- head(complete[(correct), ..forecast_unit], 1) - issue <- lapply(issue, FUN = as.character) + first_issue <- complete[(correct), ..forecast_unit][1] + first_issue <- lapply(first_issue, FUN = as.character) #nolint start: keyword_quote_linter object_usage_linter duplicate_argument_linter - issue_location <- paste(names(issue), "==", issue) + issue_location <- paste(names(first_issue), "==", first_issue) cli_abort( c(`!` = "Found incomplete forecasts", `i` = "For a nominal forecast, all possible outcomes must be assigned a probability explicitly.", - `i` = "Found first missing probabilities in the forecast specified by + `i` = "Found first missing probabilities in the forecast identified by {.emph {issue_location}}") ) #nolint end diff --git a/R/z_globalVariables.R b/R/z_globalVariables.R index fa22274a9..729d30d59 100644 --- a/R/z_globalVariables.R +++ b/R/z_globalVariables.R @@ -58,6 +58,7 @@ globalVariables(c( "pit_value", "point", "predicted", + "predicted_label", "pval", "quantile_level", "ratio", diff --git a/tests/testthat/test-metrics-nominal.R b/tests/testthat/test-metrics-nominal.R index cfba86e4c..bb01522dd 100644 --- a/tests/testthat/test-metrics-nominal.R +++ b/tests/testthat/test-metrics-nominal.R @@ -108,7 +108,7 @@ test_that("logs_nominal() works as expected", { ) # NA values in observed values lead to NAs in result - observed2 <- c(observed["nothing"], observed[-1]) + observed2 <- as.factor(c(observed["nothing"], observed[-1])) expect_equal( logs_nominal(observed2, predicted, predicted_label), c(NA, res_manual[-1]) From 0f1522630f1838fbc99a79fc028c959cf4b8acf0 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sat, 8 Jun 2024 07:02:11 -0700 Subject: [PATCH 15/36] try fix for failing test --- tests/testthat/test-metrics-nominal.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-metrics-nominal.R b/tests/testthat/test-metrics-nominal.R index bb01522dd..f28a53427 100644 --- a/tests/testthat/test-metrics-nominal.R +++ b/tests/testthat/test-metrics-nominal.R @@ -108,7 +108,7 @@ test_that("logs_nominal() works as expected", { ) # NA values in observed values lead to NAs in result - observed2 <- as.factor(c(observed["nothing"], observed[-1])) + observed2 <- factor(c(NA, "two", "two"), levels = c("one", "two", "three")) expect_equal( logs_nominal(observed2, predicted, predicted_label), c(NA, res_manual[-1]) From fec609f26a9d99d5d1db0ad83ebae79aaf2bdb5f Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sat, 8 Jun 2024 07:32:51 -0700 Subject: [PATCH 16/36] try fixing test again... --- tests/testthat/test-metrics-nominal.R | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/tests/testthat/test-metrics-nominal.R b/tests/testthat/test-metrics-nominal.R index f28a53427..862921c49 100644 --- a/tests/testthat/test-metrics-nominal.R +++ b/tests/testthat/test-metrics-nominal.R @@ -6,64 +6,63 @@ predicted <- matrix(c(0.8, 0.1, 0.4, 0.1, 0.7, 0.2), nrow = 3) - # ============================================================================ # # Input handling =============================================================== # ============================================================================ # test_that("Input checking for nominal forecasts works", { # everything correct expect_no_condition( - scoringutils:::assert_input_nominal(observed, predicted, predicted_label) + assert_input_nominal(observed, predicted, predicted_label) ) # observed and predicted_label have different level lengths observed_wrong <- factor(observed, levels = c("one", "two")) expect_error( - scoringutils:::assert_input_nominal(observed_wrong, predicted, predicted_label), + assert_input_nominal(observed_wrong, predicted, predicted_label), "Assertion on 'predicted_label' failed: Must have length 2, but has length 3." ) # observed and predicted_label have different levels, resulting in an `NA` in predicted_label predicted_label_wrong <- factor(predicted_label, levels = c("one", "two", "four")) expect_error( - scoringutils:::assert_input_nominal(observed, predicted, predicted_label_wrong), + assert_input_nominal(observed, predicted, predicted_label_wrong), "Assertion on 'predicted_label' failed: Contains missing values" ) # 6 observations, but only 3 forecasts expect_error( - scoringutils:::assert_input_nominal(c(observed, observed), predicted, predicted_label), + assert_input_nominal(c(observed, observed), predicted, predicted_label), "Assertion on 'predicted' failed: Must have exactly 6 rows, but has 3 rows." ) # observed value or predicted_label is not factor expect_error( - scoringutils:::assert_input_nominal(as.numeric(observed), predicted, predicted_label), + assert_input_nominal(as.numeric(observed), predicted, predicted_label), "Assertion on 'observed' failed: Must be of type 'factor', not 'double'." ) expect_error( - scoringutils:::assert_input_nominal(observed, predicted, as.character(predicted_label)), + assert_input_nominal(observed, predicted, as.character(predicted_label)), "Assertion on 'predicted_label' failed: Must be of type 'factor', not 'character'." ) # a single observation expect_no_condition( - scoringutils:::assert_input_nominal(observed[1], predicted[1, ], predicted_label), + assert_input_nominal(observed[1], predicted[1, ], predicted_label), ) expect_no_condition( - scoringutils:::assert_input_nominal(observed[1], as.numeric(predicted[1, ]), predicted_label), + assert_input_nominal(observed[1], as.numeric(predicted[1, ]), predicted_label), ) # wrong dimensions expect_error( - scoringutils:::assert_input_nominal(observed[1], predicted, predicted_label), + assert_input_nominal(observed[1], predicted, predicted_label), "One of the following must apply:" ) # NA values in observed are permitted observed2 <- c(observed[1:2], observed["missing"]) expect_no_condition( - scoringutils:::assert_input_nominal(observed2, predicted, predicted_label) + assert_input_nominal(observed2, predicted, predicted_label) ) # NA values in predicted are permitted and treated as zeros @@ -71,12 +70,12 @@ test_that("Input checking for nominal forecasts works", { predicted2 <- predicted predicted2[2, 2] <- NA expect_error( - scoringutils:::assert_input_nominal(observed, predicted2, predicted_label), + assert_input_nominal(observed, predicted2, predicted_label), "Probabilities belonging to a single forecast must sum to one" ) predicted2[2, 1] <- 0.3 expect_no_condition( - scoringutils:::assert_input_nominal(observed, predicted2, predicted_label) + assert_input_nominal(observed, predicted2, predicted_label) ) }) From 14a5fb77f2ec4dfd4a00601b5be722550924703c Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sat, 8 Jun 2024 07:35:22 -0700 Subject: [PATCH 17/36] update test to work with old R version --- tests/testthat/test-metrics-nominal.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-metrics-nominal.R b/tests/testthat/test-metrics-nominal.R index 862921c49..a25f93ad8 100644 --- a/tests/testthat/test-metrics-nominal.R +++ b/tests/testthat/test-metrics-nominal.R @@ -30,8 +30,12 @@ test_that("Input checking for nominal forecasts works", { ) # 6 observations, but only 3 forecasts + observed_wrong <- factor( + c("one", "two", "one", "one", "two", "three"), + levels = c("one", "two", "three") + ) expect_error( - assert_input_nominal(c(observed, observed), predicted, predicted_label), + assert_input_nominal(observed_wrong, predicted, predicted_label), "Assertion on 'predicted' failed: Must have exactly 6 rows, but has 3 rows." ) From dfc6c50b562a5c03d4c961e72b80a5cabb06def7 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Sat, 8 Jun 2024 07:55:18 -0700 Subject: [PATCH 18/36] round and round and round it goes --- tests/testthat/test-metrics-nominal.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-metrics-nominal.R b/tests/testthat/test-metrics-nominal.R index a25f93ad8..38c8768eb 100644 --- a/tests/testthat/test-metrics-nominal.R +++ b/tests/testthat/test-metrics-nominal.R @@ -64,7 +64,7 @@ test_that("Input checking for nominal forecasts works", { ) # NA values in observed are permitted - observed2 <- c(observed[1:2], observed["missing"]) + observed2 <- factor(c("one", "two", "missing"), levels = c("one", "two", "three")) expect_no_condition( assert_input_nominal(observed2, predicted, predicted_label) ) From 1cad15aa8caca985cc3098aed3603750ce0e5843 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Wed, 12 Jun 2024 16:08:48 -0700 Subject: [PATCH 19/36] Require R4.0 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index f682e1297..54e914413 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -72,5 +72,5 @@ URL: https://doi.org/10.48550/arXiv.2205.07090, https://epiforecasts.io/scoringu BugReports: https://github.com/epiforecasts/scoringutils/issues VignetteBuilder: knitr Depends: - R (>= 3.6) + R (>= 4.0) Roxygen: list(markdown = TRUE) From de851e31f94c1c85f1bb97b21df91ce247987622 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Wed, 12 Jun 2024 17:04:48 -0700 Subject: [PATCH 20/36] remove R3.6 from CI checks --- .github/workflows/R-CMD-check.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index d6011509b..23e7fe9ab 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -23,7 +23,6 @@ jobs: - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} - {os: ubuntu-latest, r: 'release'} - {os: ubuntu-latest, r: 'oldrel-1'} - - {os: ubuntu-latest, r: '3.6'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} From be1eab085ef0327f2203fe63e6c42aad6ca0df05 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Wed, 12 Jun 2024 17:06:37 -0700 Subject: [PATCH 21/36] update NEWS file --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 4b7010ad3..c593c9950 100644 --- a/NEWS.md +++ b/NEWS.md @@ -90,6 +90,7 @@ scores <- score(forecast_quantile) - Files ending in ".Rda" were renamed to ".rds" where appropriate when used together with `saveRDS()` or `readRDS()`. - Added a subsetting `[` operator for scores, so that the score name attribute gets preserved when subsetting. - Switched to using `cli` for condition handling and signalling, and added tests for all the `check_*()` and `test_*()` functions. See #583 by @jamesmbaazam and reviewed by @nikosbosse and @seabbs. +- `scoringutils` now requires R >= 4.0 ### Documentation and testing From efa1ec71b8debf3359c0aade2c41998c512ea992 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Thu, 13 Jun 2024 09:44:46 -0700 Subject: [PATCH 22/36] add CI check for 4.0 back in --- .github/workflows/R-CMD-check.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 23e7fe9ab..734ead913 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -23,6 +23,7 @@ jobs: - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} - {os: ubuntu-latest, r: 'release'} - {os: ubuntu-latest, r: 'oldrel-1'} + - {os: ubuntu-latest, r: '4.0'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} From 3bd0db6edcdb61a5d9f40dfe56e2798c14c9c554 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Thu, 13 Jun 2024 21:45:05 -0700 Subject: [PATCH 23/36] fix typo in news file --- NEWS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index c593c9950..9c7c6e1ef 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,7 +17,7 @@ of our [original](https://doi.org/10.48550/arXiv.2205.07090) `scoringutils` pape - `score()` and many other functions now require a validated `forecast` object. `forecast` objects can be created using the function `as_forecast()` (which replaces the previous `check_forecast()`). `score()` now returns objects of class `scores` with a stored attribute `metrics` that holds the names of the scoring rules that were used. Users can call `get_metrics()` to access the names of those scoring rules. - `score()` now returns one score per forecast, instead of one score per sample or quantile. - - Users can now also use their own scoring rules (making use of the `metrics` argument, which takes in a named list of functions). Default scoring rules can be accessed using the functions `metrics_point()`, `metrics_sample()`, `metrics_quantile()`, `metrics_binary()`, and `metrisc_nominal()`, which return a named list of scoring rules suitable for the respective forecast type. Column names of scores in the output of `score()` correspond to the names of the scoring rules (i.e. the names of the functions in the list of metrics). + - Users can now also use their own scoring rules (making use of the `metrics` argument, which takes in a named list of functions). Default scoring rules can be accessed using the functions `metrics_point()`, `metrics_sample()`, `metrics_quantile()`, `metrics_binary()`, and `metrics_nominal()`, which return a named list of scoring rules suitable for the respective forecast type. Column names of scores in the output of `score()` correspond to the names of the scoring rules (i.e. the names of the functions in the list of metrics). - Instead of supplying arguments to `score()` to manipulate individual scoring rules users should now manipulate the metric list being supplied using `customise_metric()` and `select_metric()`. ### Creating a forecast object @@ -34,8 +34,8 @@ of our [original](https://doi.org/10.48550/arXiv.2205.07090) `scoringutils` pape quantile_level = "quantile_level", forecast_unit = c("model", "location", "target_end_date", "forecast_date", "target_type") ) -scores <- score(forecast_quantile) -``` + scores <- score(forecast_quantile) + ``` - Overall, we updated the suggested workflows for how users should work with the package. The following gives an overview (see the [updated paper](https://drive.google.com/file/d/1URaMsXmHJ1twpLpMl1sl2HW4lPuUycoj/view?usp=drive_link) for more details). ![package workflows](./man/figures/workflow.png) From dd6cc2820a86fd6ab5b1328b078f7ec7dbd14488 Mon Sep 17 00:00:00 2001 From: nikosbosse Date: Thu, 13 Jun 2024 22:07:26 -0700 Subject: [PATCH 24/36] update manual figure --- man/figures/required-inputs.png | Bin 126510 -> 288951 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/man/figures/required-inputs.png b/man/figures/required-inputs.png index 1860a1dd8bb42289a5dfd0c2dab4704f9dd10e95..858089f0c560f045850caf78da03cff9cb354490 100644 GIT binary patch literal 288951 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