Public Documentation
Documentation for ForecastEnsembles's public interface.
Contents
Index
ForecastEnsembles.BLPForecastEnsembles.CRPSStackingForecastEnsembles.EnsembleMethodForecastEnsembles.EnsembleWeightsForecastEnsembles.FittedBLPForecastEnsembles.FittedCRPSStackingForecastEnsembles.FittedHedgeForecastEnsembles.FittedInverseScoreForecastEnsembles.FittedPartialPoolingForecastEnsembles.FittedQRAForecastEnsembles.FittedStackingForecastEnsembles.ForecastTableForecastEnsembles.HedgeForecastEnsembles.InverseScoreForecastEnsembles.LinearPoolForecastEnsembles.LogarithmicPoolForecastEnsembles.MixtureEnsembleForecastEnsembles.PartialPoolingForecastEnsembles.QRAForecastEnsembles.QuantileEnsembleForecastEnsembles.StackingForecastEnsembles.TrainedMethodForecastEnsembles.TrimmedMeanForecastEnsembles.UnfittedMethodForecastEnsembles.WindowedDataFrames.combineDataFrames.combineDataFrames.combineDataFrames.combineDataFrames.combineDataFrames.combineForecastEnsembles.backtestForecastEnsembles.effective_num_modelsForecastEnsembles.model_idsForecastEnsembles.output_typeForecastEnsembles.task_id_colsForecastEnsembles.weight_stabilityForecastEnsembles.weights
Public API
ForecastEnsembles.BLP Type
BLP(; weights = nothing)Beta-transformed linear pool (Gneiting & Ranjan 2013): a recalibrated mixture that corrects the linear opinion pool's underdispersion by passing the mixture CDF through a fitted Beta CDF.
fit(BLP(), training, observations) fits the Beta to the linear pool's PIT values on the training set (maximum likelihood); combine(ft, fitted) applies it by evaluating the linear pool's quantile function at Beta-remapped levels. weights are the underlying per-model pool weights (equal by default, or any per-model EnsembleWeights / fitted method); the Beta parameters are learned on top. Quantile forecasts only.
Because the fit is a Beta on PIT values rather than a full weight regression, BLP is a recalibration of the pool: weights returns nothing (the level remap is not expressible as model weights), so apply it with combine(ft, fitted).
Fields
weights: per-model pool weights, ornothingfor equal weights.
ForecastEnsembles.CRPSStacking Type
CRPSStacking(; dirichlet_alpha = 1.001,
lambda = nothing, time_col = nothing,
task_weights = nothing)CRPS-stacked linear opinion pool. Mirrors lopensemble::crps_weights, including its time weighting.
By default every training task contributes equally to the objective. Two ways to change that:
task_weights: aDataFramewith the training table's task-id columns plus a:weightcolumn — one non-negative weight per task. The general mechanism; covers recency, per-region weighting (lopensemble'sgamma), down-weighting anomalous reporting weeks, and so on.lambdawithtime_col: convenience for recency weighting.time_colnames the task column that orders tasks in time;lambdais one ofa scalar
φ ∈ (0, 1]: exponential decay, weightφ^(T − t)for the t-th of T ordered unique time values (the common forecasting- literature choice;φ = 1recovers equal weights),:lopensemble: the quadratic ramp2 − (1 − t/T)²thatlopensemble::crps_weightsuses by default (oldest ≈ 1, newest 2),a
Vector{Float64}with one weight per ordered unique time value (lopensemble's vector form),a function of the normalised time rank
t/T ∈ (0, 1]returning a weight.
lambda and task_weights are mutually exclusive. The Dirichlet prior strength scales with the effective sample size (Σλ)²/Σλ² rather than the raw task count, so heavy down-weighting of history does not quietly strengthen the prior relative to the data.
ForecastEnsembles.EnsembleMethod Type
EnsembleMethodTop of the method-type hierarchy. Subtypes split into
UnfittedMethod— can be passed tocombinedirectly.TrainedMethod— must be passed throughfitfirst to obtain a fitted counterpart, which is itself anUnfittedMethodand can then be passed tocombine.
ForecastEnsembles.EnsembleWeights Type
EnsembleWeights(data; shape = :auto)A typed container for per-model or per-quantile ensemble weights. The underlying data::DataFrame always has columns :model_id and :weight, and optionally :output_type_id. Two shapes are supported:
:per_model— columns:model_id, :weight. A single weight per model applied at every quantile/sample/etc.:per_quantile— columns:model_id, :output_type_id, :weight. Weights vary across quantile levels.
Construct from a DataFrame (shape inferred from columns by default) or by calling weights(m) on a fitted method. MixtureEnsemble and QuantileEnsemble accept any of: a raw DataFrame, an EnsembleWeights, or any fitted method for which weights(m) returns one. The conversion happens at construction of the method, not at combine time, so invalid inputs fail fast.
ForecastEnsembles.FittedBLP Type
FittedBLP(alpha, beta, weights)Output of fit(::BLP, …). Stores the fitted Beta shape parameters alpha and beta and the underlying pool weights. alpha = beta = 1 means the linear pool was already calibrated (no transform). Apply with combine(ft, fitted); weights returns nothing.
ForecastEnsembles.FittedCRPSStacking Type
FittedCRPSStacking(weights, models)Output of fit(::CRPSStacking, …). Stores the simplex-constrained ensemble weights as a DataFrame with columns model_id and weight, the list of models these weights refer to, and crps, the fitted objective value (the mean CRPS achieved at the optimum). Plug into combine(ft, fitted) (sample inputs) — internally a LinearPool with these weights.
ForecastEnsembles.FittedHedge Type
FittedHedge(weights, models, trajectory)Output of fit(::Hedge, …). Stores the final simplex weights (a DataFrame with columns model_id and weight), the component models in weight order, and the trajectory — a long DataFrame (time_col, model_id, weight) of the weights after each update, for diagnosing weight stability over time. Plug into combine(ft, fitted) — internally a LinearPool with the final weights.
ForecastEnsembles.FittedInverseScore Type
FittedInverseScore(weights, models, scores)Output of fit(::InverseScore, …). Stores the simplex weights (a DataFrame with columns model_id and weight), the component models in weight order, and the per-member mean scores they were derived from. Plug into combine(ft, fitted) — internally a LinearPool with these weights.
ForecastEnsembles.FittedPartialPooling Type
FittedPartialPooling(weights, global_weights, strata, models, score_value)Output of fit(::PartialPooling, …). Stores the per-stratum weights (a DataFrame with the strata columns plus model_id and weight), the pooled global_weights (model_id, weight) used for strata not seen in training, the strata columns, the component models, and the mean score_value at the optimum. Plug into combine(ft, fitted) — it applies each stratum's weights, falling back to global_weights for an unseen stratum. weights(fitted) returns the pooled global vector as an EnsembleWeights.
ForecastEnsembles.FittedQRA Type
FittedQRA(coefs, intercepts, models, levels, group_cols, per_quantile_weights, enforce_normalisation, has_intercept)Output of fit(::QRA, …). coefs is a Dict{NamedTuple => Vector{Float64}} mapping a (group..., quantile_level) key to a vector of model coefficients in the order models. When per_quantile_weights is false, all keys sharing the same group share the same coefficients (and have the same key under a sentinel :any quantile_level).
Fields
coefs:Dictmapping each(group, quantile_level)key to its vector of model coefficients (ordered asmodels).intercepts:Dictmapping each(group, quantile_level)key to its intercept; empty (all zero) when the fit has no intercept.models: component model ids, giving the order of the coefficient vectors.levels: the quantile levels the fit was trained on.group_cols: the grouping task columns used when fitting; may be empty.per_quantile_weights:Bool, whether coefficients vary across quantile levels.enforce_normalisation:Bool, whether the simplex constraint (non-negative coefficients summing to one) was imposed.has_intercept:Bool, whether an intercept was estimated.
ForecastEnsembles.FittedStacking Type
FittedStacking(weights, models, score_value)Output of fit(::Stacking, …). Stores the simplex ensemble weights (a DataFrame with columns model_id and weight), the component models in weight order, and the mean score_value achieved at the optimum. Plug into combine(ft, fitted) — internally a LinearPool with these weights.
ForecastEnsembles.ForecastTable Type
ForecastTableA long-format probabilistic-forecast table aligned with the hubverse model_out_tbl schema.
Required columns
the model identifier column (default
:model_id):output_type— symbol, one ofForecastEnsembles.KNOWN_OUTPUT_TYPES:output_type_id— quantile level, sample index, threshold, …:value— the forecast valueone or more task-id columns (e.g.
:location,:horizon,:target_date)
Construction
ForecastTable(df; task_id_cols, model_id_col = :model_id)task_id_cols may be omitted, in which case it is inferred as every column that is not one of the required columns.
Fields
data: the underlying long-formatDataFrameholding the forecasts.task_id_cols: the task-id columns identifying a forecast target.model_id_col: the column naming the model that produced each forecast.
ForecastEnsembles.Hedge Type
Hedge(score; eta = 1.0, time_col)Online ensemble weighting by the Hedge / exponentiated-gradient rule.
fit(Hedge(score; time_col), training, observations) walks the distinct time_col values in order and, at each step, multiplies every member's weight by exp(-eta · sₜ) — where sₜ is that member's mean score on the current step (negatively oriented, so a lower score keeps more weight) — then renormalises to the simplex. A member absent at a step keeps its weight (a "sleeping expert"). The final weights plug into combine; the full trajectory is kept for weight-stability diagnostics.
Unlike InverseScore (one pooled score per member) this adapts to when members did well, so it tracks regime change; unlike Stacking it needs no optimiser and updates incrementally. score is any callable score(samples, y; w); ScoringRules is the natural companion (Hedge(ScoringRules.crps; time_col)), not a dependency of this package.
Fields
score: the scoring-rule function (negatively oriented).eta: learning rate. Larger values adapt faster and concentrate weight more aggressively on recent winners; as it tends to0the weights stay uniform. Scale it to the magnitude of your score. Must be positive.time_col: the task-id column defining the update order.
ForecastEnsembles.InverseScore Type
InverseScore(score; temperature = 1.0)Performance weighting: score each member independently and weight the better ones more heavily — wᵢ ∝ exp(−temperature · sᵢ), where sᵢ is member i's mean score over the training set (negatively oriented, so a lower score earns more weight). No optimisation, so it is fast and robust with few observations; but — unlike Stacking — it scores each member in isolation and never sees how they combine, so it is blind to redundancy between them.
fit(InverseScore(score), training, observations) returns a FittedInverseScore that plugs into combine / weights. score is any callable score(samples, y; w); ScoringRules is the natural companion (InverseScore(ScoringRules.crps)), not a dependency of this package.
Fields
score: the scoring-rule function (negatively oriented).temperature: sharpness of the softmax over member scores. As it tends to0the weights approach equal; large values approach winner-take-all. Must be positive.
ForecastEnsembles.LinearPool Type
MixtureEnsemble(; weights = nothing, n_samples = 10_000)Mixture (linear-opinion-pool) ensemble: the ensemble distribution is the (weighted) mixture of the component distributions, F = Σᵢ wᵢ Fᵢ. The algorithm path depends on the forecast output_type:
:sample— weighted resample from per-model samples.:cdf— pointwise weighted average of CDFs.:quantile— reconstruct each model's CDF from its quantiles, drawn_samples, pool, and re-extract quantiles at the original levels.
Mixture pooling is fundamentally a per-model operation; per-quantile weights aren't meaningful here (use QuantileEnsemble for that).
ForecastEnsembles.LogarithmicPool Type
LogarithmicPool(; weights = nothing, ngrid = 2000)Logarithmic (geometric) opinion pool of quantile forecasts: the ensemble is the normalised weighted product of the member densities, f_ens(x) ∝ Πᵢ fᵢ(x)^wᵢ.
The geometric-mean counterpart of LinearPool (which averages the densities): the log pool is a product of experts, so it concentrates where the members agree and is typically sharper than the linear pool. weights are per-model (equal by default, or any per-model EnsembleWeights / fitted method) and act as the density exponents.
Each member's density is reconstructed from its quantiles (PCHIP interior, Normal tails), the log-product is formed on a grid of ngrid points, renormalised to integrate to one, and inverted at the requested levels. Quantile forecasts only.
Fields
weights: per-model exponent weights, ornothingfor equal weights.ngrid: number of grid points for the density product (higher is more accurate but slower).
ForecastEnsembles.MixtureEnsemble Type
MixtureEnsemble(; weights = nothing, n_samples = 10_000)Mixture (linear-opinion-pool) ensemble: the ensemble distribution is the (weighted) mixture of the component distributions, F = Σᵢ wᵢ Fᵢ. The algorithm path depends on the forecast output_type:
:sample— weighted resample from per-model samples.:cdf— pointwise weighted average of CDFs.:quantile— reconstruct each model's CDF from its quantiles, drawn_samples, pool, and re-extract quantiles at the original levels.
Mixture pooling is fundamentally a per-model operation; per-quantile weights aren't meaningful here (use QuantileEnsemble for that).
ForecastEnsembles.PartialPooling Type
PartialPooling(score; strata, lambda = 1.0, dirichlet_alpha = 1.0)Hierarchical (partially pooled) stacking: learn a weight vector per stratum that shrinks toward a shared global vector, so a data-sparse stratum borrows strength from the rest.
fit(PartialPooling(score; strata), training, observations) jointly optimises, in softmax space, one logit vector per distinct combination of the strata columns plus a global logit vector, minimising the mean score of each stratum's linearly-pooled forecast plus a shrinkage penalty pulling every stratum toward the global vector. The FittedPartialPooling result plugs into combine, which applies each stratum's own weights (an unseen stratum falls back to the global vector).
score is any callable score(samples, y; w); ScoringRules is the natural companion, not a dependency of this package. Generalises Stacking: a single stratum, or lambda → ∞, recovers global stacking.
Fields
score: the scoring-rule function to minimise (negatively oriented).strata: task-id columns whose value combinations define the strata (e.g.[:location],[:location, :age_group]).lambda: shrinkage strength toward the global vector.0fits each stratum independently; large values pool them toward one shared vector. Must be≥ 0.dirichlet_alpha: strength of a symmetric-Dirichlet prior on each stratum's weights, pulling them toward the simplex centre;1.0applies no prior.
ForecastEnsembles.QRA Type
QRA(; per_quantile_weights = false, intercept = true,
enforce_normalisation = false, noncross = false,
group = Symbol[])Quantile Regression Averaging. group lists task dimensions over which a separate regression is fitted. Mirrors qrensemble::qra.
ForecastEnsembles.QuantileEnsemble Type
QuantileEnsemble(agg = :mean; weights = nothing)Per-quantile weighted aggregation of quantile forecasts. At each task and quantile level τ, take a weighted mean (agg = :mean, also called Vincentization) or weighted median (agg = :median) of the per-model quantile values. weights may be:
nothing— equal weights (the "simple ensemble" of the hubverse).a per-model
EnsembleWeights— same weights at every τ.a per-quantile
EnsembleWeights— different weights per τ (e.g. from a per-τQRA fit, or supplied externally).any fitted method whose
weights(m)returns one of the above (FittedCRPSStacking,FittedQRAin the right configuration, etc.).
ForecastEnsembles.Stacking Type
Stacking(score; dirichlet_alpha = 1.0)Score-optimal stacking against a user-supplied proper scoring rule.
fit(Stacking(score), training, observations) learns simplex ensemble weights that minimise the mean score of the linearly-pooled forecast, where score is any negatively-oriented rule from ScoringRules — e.g. ScoringRules.crps. The FittedStacking result plugs into combine, or into LinearPool/QuantileEnsemble via weights.
score is any callable score(samples, y; w); ScoringRules is the natural companion for it (using ScoringRules then Stacking(ScoringRules.crps)), but it is not a dependency of this package. CRPSStacking and QRA remain the closed-form specialisations for CRPS and WIS respectively.
Fields
score: the scoring-rule function to minimise (negatively oriented).dirichlet_alpha: strength of a symmetric-Dirichlet prior on the weights, pulling them toward the simplex centre;1.0applies no prior.
ForecastEnsembles.TrainedMethod Type
TrainedMethodAn ensemble method whose weights or coefficients are learned from past performance before use, for example QRA or CRPSStacking. Passing one through fit returns a fitted object (itself an UnfittedMethod) that can then be passed to combine.
ForecastEnsembles.TrimmedMean Type
TrimmedMean(; fraction = 0.1, mode = :trim)Robust ensemble mean. At each task and output_type_id (e.g. a quantile level τ), order the per-model values and either trim — drop the lowest and highest fraction of them, then average the rest — or winsorise — clamp those extremes to the surviving boundary values, then average all of them.
k = round(fraction · n) models are trimmed/clamped from each end, capped so at least one value always survives (so fraction → 0.5 degenerates to the median, fraction = 0 to the plain mean). This is the robust cousin of QuantileEnsemble(:mean): cheaper than a full median ensemble to reason about, and tunable in how much of the tail it discards. It aggregates values that are comparable across models at a shared output_type_id, so it supports :quantile and :cdf forecasts, not :sample (sample indices are not aligned across models — use MixtureEnsemble there).
Fields
fraction: proportion trimmed/clamped from each end, in[0, 0.5).mode::trim(drop the extremes) or:winsorise(clamp them).
Example
using ForecastEnsembles, DataFrames
df = DataFrame(
model_id = string.("m", 1:5),
output_type = "quantile",
output_type_id = 0.5,
location = "A",
value = [1.0, 2.0, 3.0, 4.0, 100.0]
)
ft = ForecastTable(df; task_id_cols = [:location])
combine(ft, TrimmedMean(; fraction = 0.2))ForecastEnsembles.UnfittedMethod Type
UnfittedMethodAn ensemble method applied directly to forecasts with no training, for example QuantileEnsemble(:mean) or MixtureEnsemble(). It carries any fixed configuration (aggregation rule, supplied weights) and can be passed straight to combine without a prior call to fit.
ForecastEnsembles.Windowed Type
Windowed(method, window; time_col)Wrap a TrainedMethod so it trains on only the most recent window values of time_col.
fit(Windowed(method, window; time_col), training, observations) keeps the last window distinct time_col values of training (and the matching observations), fits method on that subset, and returns method's own fitted result — so it drops straight into combine.
Useful for a rolling-window scheme in backtest: compare an expanding-window CRPSStacking() against a rolling Windowed(CRPSStacking(), 8; time_col = :date).
Fields
method: the innerTrainedMethodto fit on the window.window: number of most-recenttime_colvalues to train on (must be≥ 1).time_col: the task-id column defining time order.
ForecastEnsembles.backtest Function
backtest(ft, observations, schemes; time_col, score_fn, min_train = 1,
rng = default_rng()) -> DataFrameExpanding-window backtest of ensemble schemes. The unique values of time_col are ordered; for each test time after the first min_train, every scheme is trained on the earlier times and scored on the test time out-of-sample. Returns one row per (scheme, test time) with columns scheme, the time_col, and :score (mean over that time's tasks).
schemes maps names to EnsembleMethods (a Dict or a vector of name => method pairs):
a
TrainedMethod—CRPSStacking(),QRA(...)— is fitted on the training window each fold, then applied to the test time;an
UnfittedMethod—QuantileEnsemble(:mean),MixtureEnsemble()— is applied directly.
Each scheme must match the table's output_type: CRPSStacking and sample combiners need :sample data, QRA and quantile combiners need :quantile.
Scoring is the caller's choice: pass score_fn(forecast::ForecastTable, observations) -> Real (the mean score of one fold). ScoringRules.jl is a natural source — e.g. a CRPS-based scorer for sample forecasts — but any function of that shape works.
Aggregate across folds yourself, e.g.
using DataFrames
res = backtest(ft, obs, schemes; time_col = :target_date)
combine(groupby(res, :scheme), :score => mean => :mean_score)Arguments
ft: aForecastTable.observations: aDataFramewith the table's task-id columns and an:observedcolumn.schemes: aDictor vector ofname => EnsembleMethodpairs to compare.
Keyword Arguments
time_col: the column giving the time index to expand the window over.min_train: number of initial times used only for training (default1).rng: RNG used by sample-based schemes (defaultdefault_rng()).score_fn: a scorer(forecast, observations) -> Real, returning the mean score over the fold's tasks. Required — there is no default.
Examples
using ForecastEnsembles, DataFrames, Random, Statistics
rng = MersenneTwister(1)
T = 12; K = 40
obs = DataFrame(t = 1:T, observed = randn(rng, T))
rows = DataFrame[]
for (mid, s) in (("m1", (y, r) -> y .+ randn(r, K)), ("m2", (y, r) -> 2 .* randn(r, K)))
for t in 1:T
push!(rows, DataFrame(model_id = mid, output_type = "sample",
output_type_id = 1:K, t = t, value = s(obs.observed[t], rng)))
end
end
ft = ForecastTable(reduce(vcat, rows); task_id_cols = [:t])
schemes = ["equal" => MixtureEnsemble(), "stack" => CRPSStacking()]
# Inject a scorer — here mean absolute error of the ensemble mean; with
# `using ScoringRules` you would instead pass a proper rule such as ScoringRules.crps.
function mae(ens, o)
d = innerjoin(DataFrame(ens), o; on = :t)
per = combine(groupby(d, :t),
[:value, :observed] => ((v, y) -> abs(mean(v) - first(y))) => :e)
return mean(per.e)
end
backtest(ft, obs, schemes; time_col = :t, min_train = 6, score_fn = mae)DataFrames.combine Method
combine(ft::ForecastTable, m::QuantileEnsemble) -> ForecastTableHub-style simple/weighted ensemble. Aggregates value across model_id within each (task, output_type, output_type_id) group, using m.agg (:mean or :median) and optional per-model weights.
Mirrors hubEnsembles::simple_ensemble. The output model_id is set to "hub-ensemble", matching the R package default.
DataFrames.combine Method
combine(ft::ForecastTable, m::MixtureEnsemble; rng = default_rng()) -> ForecastTableLinear opinion pool. The kernel is dispatched on the table's output_type:
:sample→ weighted resampling of per-model samples to give a single pooled sample set per task (the only path that usesrng).:cdf→ weighted pointwise average of CDFs.:quantile→ reconstruct a continuous distribution per model viaQuantileDistribution, then invert the mixture CDF Σᵢ wᵢ Fᵢ exactly by bisection at each input level. Deterministic — no Monte Carlo error, which matters for the extreme levels (τ = 0.01, 0.99) hubs request.
DataFrames.combine Method
combine(ft::ForecastTable, m::LogarithmicPool; rng = default_rng()) -> ForecastTableApply the logarithmic (geometric) opinion pool at each task. See LogarithmicPool. The output model_id is "hub-ensemble".
DataFrames.combine Method
combine(ft::ForecastTable, m::TrimmedMean; rng = default_rng()) -> ForecastTableApply a trimmed or winsorised cross-model mean at each (task, output_type_id). See TrimmedMean. The output model_id is "hub-ensemble".
DataFrames.combine Method
combine(ft::ForecastTable, m::FittedQRA) -> ForecastTableApply fitted QRA weights to a new set of forecasts. The output has output_type = :quantile and one row per (task, quantile_level).
DataFrames.combine Method
combine(ft::ForecastTable, m::FittedCRPSStacking; rng = default_rng()) -> ForecastTableApply CRPS-stacked weights to a (sample-typed) forecast table. Equivalent to combine(ft, LinearPool(weights = m.weights)).
Arguments
ft: aForecastTableof sample forecasts.m: aFittedCRPSStackingholding the fitted ensemble weights.
Keyword Arguments
rng: random number generator used for resampling; defaults todefault_rng().
Example
using ForecastEnsembles, DataFrames, Random
rng = MersenneTwister(1)
T = 20; K = 50
obs = DataFrame(t = 1:T, observed = randn(rng, T))
rows = DataFrame[]
for (mid, s) in (("m1", (y, r) -> y .+ randn(r, K)), ("m2", (y, r) -> 3 .* randn(r, K)))
for t in 1:T
push!(rows, DataFrame(model_id = mid, output_type = "sample",
output_type_id = 1:K, t = t, value = s(obs.observed[t], rng)))
end
end
ft = ForecastTable(reduce(vcat, rows); task_id_cols = [:t])
fitted = fit(CRPSStacking(), ft, obs)
combine(ft, fitted)ForecastEnsembles.effective_num_models Function
effective_num_models(m) -> Float64 or DataFrameThe effective number of models in a weight vector: the participation ratio p. It is 1 when all weight sits on one model and equals the model count M when the weights are equal, so it reads as "how many models is this ensemble really using".
m may be a fitted method exposing weights (e.g. FittedCRPSStacking, FittedStacking, FittedHedge; FittedPartialPooling uses its pooled global vector), an EnsembleWeights, a weights DataFrame, or a raw weight vector. For per-quantile weights it returns a DataFrame (output_type_id, effective_num_models) — one value per quantile level; otherwise a scalar.
Example
using ForecastEnsembles
effective_num_models([0.6, 0.3, 0.1])Missing docstring.
Missing docstring for ForecastEnsembles.fit(::QRA, ::ForecastTable, ::DataFrames.AbstractDataFrame). Check Documenter's build log for details.
Missing docstring.
Missing docstring for ForecastEnsembles.fit(::CRPSStacking, ::ForecastTable, ::DataFrames.AbstractDataFrame). Check Documenter's build log for details.
ForecastEnsembles.model_ids Function
model_ids(ft::ForecastTable) -> VectorThe distinct model identifiers present in ft, taken from its model-id column.
Arguments
ft: aForecastTable.
Example
using ForecastEnsembles, DataFrames
df = DataFrame(
location = "A", horizon = 1,
model_id = repeat(["m1", "m2", "m3"], inner = 2),
output_type = "quantile",
output_type_id = repeat([0.25, 0.75], 3),
value = [1.0, 3.0, 2.0, 4.0, 0.5, 2.5]
)
ft = ForecastTable(df; task_id_cols = [:location, :horizon])
model_ids(ft)ForecastEnsembles.output_type Function
output_type(ft::ForecastTable) -> SymbolThe single output_type present in ft. Throws if the table mixes output types, since most ensemble methods are defined on a single type at a time.
Arguments
ft: aForecastTable.
Examples
using ForecastEnsembles, DataFrames
df = DataFrame(
location = "A", horizon = 1,
model_id = repeat(["m1", "m2", "m3"], inner = 2),
output_type = "quantile",
output_type_id = repeat([0.25, 0.75], 3),
value = [1.0, 3.0, 2.0, 4.0, 0.5, 2.5]
)
ft = ForecastTable(df; task_id_cols = [:location, :horizon])
output_type(ft)ForecastEnsembles.task_id_cols Function
task_id_cols(ft::ForecastTable) -> Vector{Symbol}The task-id columns of ft, i.e. the columns that together identify a forecast target (e.g. :location, :horizon, :target_date).
Arguments
ft: aForecastTable.
Example
using ForecastEnsembles, DataFrames
df = DataFrame(
location = "A", horizon = 1,
model_id = repeat(["m1", "m2", "m3"], inner = 2),
output_type = "quantile",
output_type_id = repeat([0.25, 0.75], 3),
value = [1.0, 3.0, 2.0, 4.0, 0.5, 2.5]
)
ft = ForecastTable(df; task_id_cols = [:location, :horizon])
task_id_cols(ft)ForecastEnsembles.weight_stability Function
weight_stability(m::FittedHedge) -> DataFrameHow much each model's Hedge weight moved over the training run: the total variation trajectory. A large value flags a model whose weight swung across the history (regime change or noise); a small one flags a stable contribution. Returns a DataFrame with columns model_id and total_variation.
Example
using ForecastEnsembles, DataFrames
trajectory = DataFrame(
model_id = repeat(["m1", "m2"], inner = 2),
weight = [0.5, 0.7, 0.5, 0.3],
t = [1, 2, 1, 2]
)
fitted = FittedHedge(
DataFrame(model_id = ["m1", "m2"], weight = [0.7, 0.3]), ["m1", "m2"], trajectory)
weight_stability(fitted)ForecastEnsembles.weights Function
weights(m) -> Union{DataFrame, Nothing}Per-model weights estimated by a fitted method, as a DataFrame with columns :model_id and :weight. Returns nothing when the fit does not correspond to a single weight vector on the simplex (e.g. unconstrained QRA, per-quantile QRA, QRA with a non-zero intercept).
When weights(m) !== nothing, m can be passed in place of an explicit weights frame to any method that accepts one — for example MixtureEnsemble(weights = m) or QuantileEnsemble(:mean; weights = m). This is the composition path between trained and untrained methods.
Arguments
m: a fitted method (such asFittedCRPSStackingorFittedQRA) from which per-model weights are extracted.
Examples
using ForecastEnsembles, DataFrames, Random
rng = MersenneTwister(1)
T = 20; K = 50
obs = DataFrame(t = 1:T, observed = randn(rng, T))
rows = DataFrame[]
for (mid, s) in (("m1", (y, r) -> y .+ randn(r, K)), ("m2", (y, r) -> 3 .* randn(r, K)))
for t in 1:T
push!(rows, DataFrame(model_id = mid, output_type = "sample",
output_type_id = 1:K, t = t, value = s(obs.observed[t], rng)))
end
end
ft = ForecastTable(reduce(vcat, rows); task_id_cols = [:t])
weights(fit(CRPSStacking(), ft, obs))