Skip to content

feat: add alpha optimization for croston#1126

Open
m-muecke wants to merge 2 commits into
robjhyndman:masterfrom
m-muecke:croston-optim
Open

feat: add alpha optimization for croston#1126
m-muecke wants to merge 2 commits into
robjhyndman:masterfrom
m-muecke:croston-optim

Conversation

@m-muecke

@m-muecke m-muecke commented Apr 10, 2026

Copy link
Copy Markdown
Contributor
  • Backport some features from fable's CROSTON() to croston_model()
  • alpha = NULL jointly optimizes the smoothing parameter and initial values via optim()
  • New init parameter for interval component initialization ("naive" or "mean")
  • Fitted values before the first non-zero demand are now NA instead of 0, matching fable and tsintermittent

Note: one could change the default value for initial to "mean" to match the fable and tsintermittent implementation, but that would be somewhat breaking change.

Brief comparison to the fable NA handling:

  library(forecast)
  library(fable)
  library(tsibble)
  library(tsintermittent)

  y <- c(0, 0, 0, 3, 0, 0, 2, 0, 5)

  # old: leading zeros get fitted = 0
  # fitted:  NA     0     0     0  0.75  0.75  0.75  0.7436  0.7436

  # new (fixed alpha): leading zeros are now NA
  croston_model(y, alpha = 0.1)$fitted
  #> NA    NA    NA    NA  0.75  0.75  0.75  0.7436  0.7436

  # new (optimized alpha + init values)
  fit <- croston_model(y, alpha = NULL)
  fit$alpha
  #> 0
  fit$fitted
  #> NA    NA    NA    NA  1.4  1.4  1.4  1.4  1.4

  # fable (optimized alpha + init values)
  tbl <- tsibble(t = 1:9, y = y, index = t)
  fit_fable <- tbl |> model(CROSTON(y ~ demand(param = 0.1) + interval(param = 0.1, method = "naive")))
  augment(fit_fable)$.fitted
  #> NA    NA    NA    NA  1.3648  1.3648  1.3648  1.3066  1.3066

  # tsintermittent (fixed alpha, optimized init values)
  crost(y, w = 0.1, type = "croston", init = "naive")$frc.in
  #> NA    NA    NA    NA  0.6111  0.6111  0.6111  0.625  0.625

@m-muecke m-muecke force-pushed the croston-optim branch 4 times, most recently from 8f028cb to cfe32a0 Compare April 10, 2026 17:04
@m-muecke m-muecke marked this pull request as draft April 10, 2026 17:05
@m-muecke m-muecke force-pushed the croston-optim branch 5 times, most recently from d4d518f to 1360b02 Compare April 11, 2026 11:35
@m-muecke m-muecke force-pushed the croston-optim branch 3 times, most recently from 0c16158 to a6e2669 Compare May 16, 2026 12:14
@m-muecke

Copy link
Copy Markdown
Contributor Author

Alternatively, we could stay backwards compatible and offer the two-parameter variant by following
tsintermittent's design: let alpha be length one (a single shared smoothing parameter, as today) or length two (separate demand and interval parameters). The scalar default is unchanged, so existing behavior is preserved.

Or add a new function croston2() or something else that mirrors fable with two args instead of one.

@m-muecke m-muecke marked this pull request as ready for review June 14, 2026 09:46
@robjhyndman

Copy link
Copy Markdown
Owner

I'd rather not have a new function, but allowing separate optimizations over the two alphas would be potentially useful. One possible design could be:

  • Leave alpha = 0.1 as the default.
  • Allow alpha to take length 2 if separate alphas are required (documentation would need to carefully describe which is which).
  • Add a new argument 'optimize_alpha=FALSEwhere the providedalpha` value (or values) would be starting points in the optimization.

That preserves current behaviour, but allows fable-like results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants