Skip to content

CRPS() incorrect for sqrt() transformed forecasts #442

Description

@nickreich

Here is a reproducible example for what I think is a bug uncovered while developing forecasting evaluation course materials.

I had locally a copy of fabletools 0.8.0 and the website is running a cached version of 0.7.x and we were getting different results for a power-transformed (fourth-root, in this case) forecasts. Below is a minimal reproducible example using fabletools 0.8.0.

Note that at the end the fabletools_CRPS should agree with the sample_truth column and it does for the no transform and log transform but does not agree for the sqrt transform.

## Minimal reproducible example
##
## fabletools::CRPS() over-estimates CRPS for power-transformed
## (e.g. sqrt) forecast distributions.
## It is correct for untransformed (Normal) and log-transformed forecasts.
##
## Ground truth = CRPS of the SAME forecast distribution, estimated from its own
## samples via scoringRules::crps_sample().

suppressMessages({library(fable); library(tsibble); library(dplyr)})

set.seed(1)
n   <- 100
y   <- rnorm(n, mean = 2.5, sd = 0.35)^2      # simple, positive, right-skewed series
dat <- tsibble(t = seq_len(n), y = y, index = t)

obs <- 6                                       # value to score the 1-step forecast against

fit <- dat |> model(
  none = RW(y),          # Normal forecast   (control)
  log  = RW(log(y)),     # log transform     (control)
  sqrt = RW(sqrt(y))     # power transform   (affected)
)
fc <- forecast(fit, h = 1)

res <- lapply(c("none", "log", "sqrt"), function(m) {
  D <- fc |> filter(.model == m) |> pull(y)    # length-1 distribution vector
  set.seed(1)
  data.frame(
    model           = m,
    fabletools_CRPS = fabletools::CRPS(D, obs),
    sample_truth    = scoringRules::crps_sample(obs, distributional::generate(D, 1e6)[[1]])
  )
})
res <- do.call(rbind, res); res$ratio <- res$fabletools_CRPS / res$sample_truth
print(res, digits = 4, row.names = FALSE)
#>  model fabletools_CRPS sample_truth  ratio
#>   none          0.5790       0.5790 0.9999
#>    log          0.5263       0.5258 1.0009
#>   sqrt          2.8696       0.5418 5.2967

sessionInfo()
#> R version 4.4.3 (2025-02-28)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sequoia 15.7.7
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib 
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0
#> 
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#> 
#> time zone: America/New_York
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] dplyr_1.2.0      tsibble_1.2.0    fable_0.5.0      fabletools_0.8.0
#> 
#> loaded via a namespace (and not attached):
#>  [1] gtable_0.3.6         compiler_4.4.3       vecvec_1.2.0        
#>  [4] tidyselect_1.2.1     reprex_2.1.1         Rcpp_1.1.1-1.1      
#>  [7] dichromat_2.0-0.1    tidyr_1.3.2          scales_1.4.0        
#> [10] yaml_2.3.12          fastmap_1.2.0        ggplot2_4.0.2       
#> [13] R6_2.6.1             generics_0.1.4       distributional_0.5.0
#> [16] knitr_1.51           MASS_7.3-65          ggtime_0.2.0.9000   
#> [19] tibble_3.3.1         mixtime_0.2.0.9000   lubridate_1.9.5     
#> [22] tzdb_0.5.0           RColorBrewer_1.1-3   pillar_1.11.1       
#> [25] scoringRules_1.1.3   rlang_1.2.0          xfun_0.59           
#> [28] S7_0.2.2             fs_2.1.0             otel_0.2.0          
#> [31] timechange_0.4.0     cli_3.6.6            progressr_1.0.0     
#> [34] withr_3.0.3          magrittr_2.0.5       digest_0.6.39       
#> [37] grid_4.4.3           rstudioapi_0.19.0    lifecycle_1.0.5     
#> [40] anytime_0.3.13       vctrs_0.7.1          evaluate_1.0.5      
#> [43] glue_1.8.1           numDeriv_2016.8-1.1  farver_2.1.2        
#> [46] purrr_1.2.0          rmarkdown_2.30       tools_4.4.3         
#> [49] pkgconfig_2.0.3      htmltools_0.5.9

Created on 2026-07-16 with reprex v2.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions