-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #388 from epiforecasts/rework-quantile-scores
Rework quantile scores
- Loading branch information
Showing
94 changed files
with
3,278 additions
and
2,129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#' @title Add Coverage Values to Quantile-Based Forecasts | ||
#' | ||
#' @description Adds interval coverage of central prediction intervals, | ||
#' quantile coverage for predictive quantiles, as well as the deviation between | ||
#' desired and actual coverage to a data.table. Forecasts should be in a | ||
#' quantile format (following the input requirements of `score()`). | ||
#' | ||
#' **Interval coverage** | ||
#' | ||
#' Coverage for a given interval range is defined as the proportion of | ||
#' observations that fall within the corresponding central prediction intervals. | ||
#' Central prediction intervals are symmetric around the median and and formed | ||
#' by two quantiles that denote the lower and upper bound. For example, the 50% | ||
#' central prediction interval is the interval between the 0.25 and 0.75 | ||
#' quantiles of the predictive distribution. | ||
#' | ||
#' The function `add_coverage()` computes the coverage per central prediction | ||
#' interval, so the coverage will always be either `TRUE` (observed value falls | ||
#' within the interval) or `FALSE` (observed value falls outside the interval). | ||
#' You can summarise the coverage values to get the proportion of observations | ||
#' that fall within the central prediction intervals. | ||
#' | ||
#' **Quantile coverage** | ||
#' | ||
#' Quantile coverage for a given quantile is defined as the proportion of | ||
#' observed values that are smaller than the corresponding predictive quantile. | ||
#' For example, the 0.5 quantile coverage is the proportion of observed values | ||
#' that are smaller than the 0.5 quantile of the predictive distribution. | ||
#' | ||
#' **Coverage deviation** | ||
#' | ||
#' The coverage deviation is the difference between the desired coverage and the | ||
#' actual coverage. For example, if the desired coverage is 90% and the actual | ||
#' coverage is 80%, the coverage deviation is -0.1. | ||
#' | ||
#' @inheritParams score | ||
#' @return a data.table with the input and columns "interval_coverage", | ||
#' "interval_coverage_deviation", "quantile_coverage", | ||
#' "quantile_coverage_deviation" added. | ||
#' @importFrom data.table setcolorder | ||
#' @examples | ||
#' library(magrittr) # pipe operator | ||
#' example_quantile %>% | ||
#' add_coverage() | ||
#' @export | ||
#' @keywords scoring | ||
#' @export | ||
add_coverage <- function(data) { | ||
stored_attributes <- get_scoringutils_attributes(data) | ||
data <- validate(data) | ||
forecast_unit <- get_forecast_unit(data) | ||
data_cols <- colnames(data) # store so we can reset column order later | ||
|
||
# what happens if quantiles are not symmetric around the median? | ||
# should things error? Also write tests for that. | ||
interval_data <- quantile_to_interval(data, format = "wide") | ||
interval_data[, interval_coverage := ifelse( | ||
observed <= upper & observed >= lower, | ||
TRUE, | ||
FALSE) | ||
][, c("lower", "upper", "observed") := NULL] | ||
|
||
data[, range := get_range_from_quantile(quantile)] | ||
|
||
data <- merge(interval_data, data, by = unique(c(forecast_unit, "range"))) | ||
data[, interval_coverage_deviation := interval_coverage - range / 100] | ||
data[, quantile_coverage := observed <= predicted] | ||
data[, quantile_coverage_deviation := quantile_coverage - quantile] | ||
|
||
# reset column order | ||
new_metrics <- c("interval_coverage", "interval_coverage_deviation", | ||
"quantile_coverage", "quantile_coverage_deviation") | ||
setcolorder(data, unique(c(data_cols, "range", new_metrics))) | ||
|
||
# add coverage "metrics" to list of stored metrics | ||
# this makes it possible to use `summarise_scores()` later on | ||
stored_attributes[["metric_names"]] <- c( | ||
stored_attributes[["metric_names"]], | ||
new_metrics | ||
) | ||
data <- assign_attributes(data, stored_attributes) | ||
return(data[]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.