Data Loading#
- class forecast_evaluation.data.DensityForecastData(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, extra_ids: list[str] | None = None, compute_levels: bool = True)[source]#
Bases:
ForecastDataClass for density forecasts with quantile information.
Extends the ForecastData class to handle density forecasts. DensityForecastData objects include a density_forecasts attribute that contains forecasts with quantile information (basically an extra column indicating quantiles). It can still handle point forecasts with the forecasts attribute.
- Parameters:
outturns_data (pd.DataFrame, optional) – DataFrame containing outturn (actual) data.
forecasts_data (pd.DataFrame, optional) – DataFrame containing point forecast records.
density_forecasts_data (pd.DataFrame, optional) – DataFrame containing density forecast records. Must include ‘quantile’ column.
point_estimator (str, optional) – Estimator for point forecasts; can be ‘median’, ‘mean’ or ‘mode’. Default is ‘median’.
load_fer (bool, optional) – Whether to load FER (Forecast Evaluation Report) data. Default is False.
extra_ids (list of str, optional) – Additional identification columns beyond ‘source’ and ‘quantile’.
Examples
>>> import pandas as pd >>> from forecast_evaluation.data import DensityForecastData >>> >>> # Create sample density forecasts >>> df = pd.DataFrame({ ... 'date': pd.date_range('2023-01-01', periods=4, freq='QE'), ... 'vintage_date': pd.Timestamp('2023-01-01'), ... 'variable': 'gdp', ... 'frequency': 'Q', ... 'forecast_horizon': [1, 2, 3, 4], ... 'source': 'model_1', ... 'quantile': 0.5, ... 'value': [100, 101, 102, 103] ... }) >>> >>> density_data = DensityForecastData(forecasts_data=df) >>> median = density_data.get_median_forecast()
- __init__(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, extra_ids: list[str] | None = None, compute_levels: bool = True)[source]#
Initialise DensityForecastData.
Initialises the density forecast data object. If forecasts_data is provided, it will be validated and added. The ‘quantile’ column is automatically included as an identification column.
- add_density_forecasts(df: DataFrame, extra_ids: list[str] | None = None) None[source]#
Validate and add density forecasts with quantile column.
- Parameters:
df (pd.DataFrame) – DataFrame containing density forecast records. Must include ‘quantile’ column with values between 0 and 1.
extra_ids (list of str, optional) – Additional identification columns beyond ‘source’ and ‘quantile’.
- Raises:
ValueError – If ‘quantile’ column is missing from the DataFrame.
Examples
>>> density_data = DensityForecastData() >>> df = pd.DataFrame({ ... 'date': ['2023-01-01'], ... 'vintage_date': ['2023-01-01'], ... 'variable': ['gdp'], ... 'frequency': ['Q'], ... 'forecast_horizon': [1], ... 'source': ['model_1'], ... 'quantile': [0.5], ... 'value': [100] ... }) >>> density_data.add_density_forecasts(df)
- clear_filter() None[source]#
Reset both parent forecasts and density forecasts to include all original data.
- property density_forecasts: DataFrame#
Get density forecasts with quantile information.
- filter(start_date: str | None = None, end_date: str | None = None, start_vintage: str | None = None, end_vintage: str | None = None, variables: list[str] | None = None, metrics: list[str] | None = None, sources: list[str] | None = None, frequencies: list[str] | None = None, custom_filter: Callable[[DataFrame], DataFrame] | None = None, filter_point_forecasts: bool | None = True, filter_density_forecasts: bool | None = True)[source]#
Filter the forecasts and main tables to only include data within specified date and vintage ranges, and optionally by variables, metrics, sources, or a custom filter.
- Parameters:
start_date (str, optional) – Start date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest date.
end_date (str, optional) – End date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest date.
start_vintage (str, optional) – Start vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest vintage.
end_vintage (str, optional) – End vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest vintage.
variables (Optional[Union[str, list[str]]] = None) – List of variable identifiers to filter. Default is None (no filtering).
metrics (Optional[list[str]] = None) – List of metric identifiers to filter. Default is None (no filtering).
sources (Optional[Union[str, list[str]]] = None) – List of source identifiers to filter. Default is None (no filtering).
frequencies (Optional[Union[str, list[str]]] = None) – List of frequency identifiers to filter. Default is None (no filtering).
custom_filter (Callable[[pd.DataFrame], pd.DataFrame], optional) – A custom filtering function that takes a DataFrame as input and returns a filtered DataFrame. Default is None. Custom filters should use ‘vintage_date_forecast’ as the column name.
filter_point_forecasts (bool, optional) – Whether to apply the filter to point forecasts. Default is True.
filter_density_forecasts (bool, optional) – Whether to apply the filter to density forecasts. Default is True.
- merge(other: ForecastData, compute_levels: bool = True) None[source]#
Merge another ForecastData or DensityForecastData instance into this one.
- Parameters:
other (ForecastData or DensityForecastData) – Another ForecastData or DensityForecastData instance to merge with this one.
compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts from other to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.
- plot_density_vintage(variable: str, vintage_date: str | Timestamp, quantiles: list[float] | None = [0.16, 0.5, 0.84], forecast_source: list[str] | None = None, outturn_start_date: str | Timestamp | None = None, frequency: Literal['Q', 'M'] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', return_plot: bool = False, **kwargs) tuple | None[source]#
Plot forecast density plots.
- Parameters:
**kwargs – Additional keyword arguments passed to the plotting function.
Notes
This method creates density plots for the density forecasts.
- sample_from_density(n_samples: int = 10000, random_state: int | None = None) DataFrame[source]#
Generate samples from the empirical distribution defined by quantiles.
Uses inverse transform sampling to draw samples from the distribution defined by the quantile forecasts.
- Parameters:
n_samples (int, optional) – Number of samples to generate per forecast group. Default is 10000.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
DataFrame with sampled values. Columns: [id_columns…, ‘sample_id’, ‘value’]
- Return type:
pd.DataFrame
Notes
Works well when you have many quantiles (50+). With few quantiles, consider using parametric fitting instead.
Examples
>>> samples = density_data.sample_from_density(n_samples=10000, random_state=42) >>> mean = samples.groupby(['date', 'variable'])['value'].mean()
- to_point_forecast(method: str = 'median') ForecastData[source]#
Convert density forecasts to point forecasts.
- Parameters:
method (str, optional) – Method to extract point forecast: - ‘median’: Use 0.5 quantile (default, most robust) - ‘mean’: Average via sampling from distribution - specific quantile: e.g., ‘0.5’, ‘0.75’
- Returns:
Point forecast data object.
- Return type:
Examples
>>> # Convert using median >>> point_data = density_data.to_point_forecast('median') >>> >>> # Convert using mean via sampling >>> point_data = density_data.to_point_forecast('mean') >>> >>> # Convert using specific quantile >>> point_data = density_data.to_point_forecast('0.75')
- class forecast_evaluation.data.ForecastData(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, outturn_vintages: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#
Bases:
PlottingMixinClass for validation and extending forecast data.
The main method is .add_forecasts() which validates the input data and compute relevant dataframes. underscore indicates that the object only meant to be used internally.
Notes
Each ForecastData instance should only contain forecasts of a single frequency (e.g., all quarterly or all monthly). To work with multiple frequencies, create separate ForecastData instances for each frequency.
- __init__(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, outturn_vintages: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#
Initialise with user data, FER data or null.
- Parameters:
outturns_data (pd.DataFrame, optional) – DataFrame containing outturn records to add on initialisation. Default is None.
forecasts_data (pd.DataFrame, optional) – DataFrame containing forecast records to add on initialisation. Default is None.
load_fer (bool, optional) – Whether to load FER outturns and forecast data on initialisation. Default is False.
extra_ids (Optional[list[str]], optional) – List of extra label columns (in addition to ‘source’) present in the forecasts data. Default is None.
metric (str, optional) – Metric to assign to the forecasts if ‘metric’ column is not present or contains null values. Default is ‘levels’. Options: ‘levels’, ‘pop’, ‘yoy’.
compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.
data_check (bool, optional) – Whether to run data checks when adding forecasts. See
add_forecasts()for details. Default is True.outturn_vintages (bool, optional) – Whether the outturn data contains vintage information (multiple releases of the same data point over time). When False, the data is assumed to contain a single final outturn per date, and column
vintage_dateis not required in the outturn data. Thekandlatest_vintagecolumns in the main table will be set to sentinel values andfilter_kwill be a no-op. Features that depend on outturn revisions (e.g.,plot_outturn_revisions,create_outturn_revisions) will raise an error. Default is True.default_k (int or None, optional) – Default outturn revision index used by evaluation functions when
kis omitted. If None, uses the class default.first_forecast_horizon (int or dict[str, int], optional) – DEPRECATED legacy value used when the input does not provide
forecast_horizon. In that case, the missing horizon is derived fromtarget_minus_vintageand aFutureWarningis emitted. If this argument is omitted too, the same deprecated fallback is used without a shift. Supplyforecast_horizonexplicitly instead.
- add_benchmarks(models: list[str] | str = ['AR', 'random_walk'], variables: str | Iterable[str] | None = None, metric: Literal['levels', 'diff', 'pop', 'yoy'] = 'levels', frequency: Literal['Q', 'M'] | Iterable[Literal['Q', 'M']] | None = None, forecast_periods: int = 13, *, max_lag: Literal[1, 2] = 2, estimation_start_date: Timestamp | None = None, show_progress: bool = False) None[source]#
Add benchmark model forecasts to the ForecastData instance.
Builds the requested benchmark models from the available outturn data and appends their forecasts to the instance via
add_forecasts(). The instance is modified in place.- Parameters:
models (list of str or str, optional) – Benchmark model(s) to add. Valid options are
"AR"(autoregressive AR(p) model) and"random_walk". Default is both (["AR", "random_walk"]).variables (str, iterable of str, or None, optional) – Variable(s) to build benchmarks for. If None (default), benchmarks are built for all variables present in the outturns.
metric (str, optional) – Metric to build the benchmarks for. Options:
"levels","diff","pop","yoy". Default is"levels".frequency (str, iterable of str, or None, optional) – Frequency (or frequencies) to build benchmarks for (
"Q"for quarterly,"M"for monthly). If None (default), frequencies are inferred from the outturns.forecast_periods (int, optional) – Number of periods to forecast ahead. Default is 13.
max_lag (int, optional) – Maximum number of lags (AR order) to consider when selecting the AR(p) model via BIC. Must be 1 or 2. Only applies to the
"AR"model. Default is 2.estimation_start_date (pd.Timestamp, optional) – The date from which to start including data for AR(p) model estimation. If None (default), all available data is used. Only applies to the
"AR"model.show_progress (bool, optional) – Whether to show progress bars while building the benchmarks. Default is False.
- Returns:
The method modifies the ForecastData instance in place.
- Return type:
None
- Raises:
ValueError – If any model in
modelsis not a recognised benchmark model.
- add_forecasts(df: DataFrame, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy']='levels', compute_levels: bool = True, data_check: bool = True, first_forecast_horizon: int | dict[str, int] | None=<object object>) None[source]#
Validate new forecasts, transform forecasts and outturns and compute main table and revisions.
If any validation or transformation step fails, the instance is left unchanged.
- Parameters:
df (pd.DataFrame) – DataFrame containing new forecast records to add.
extra_ids (list of str, optional) – List of extra label/identification columns (in addition to ‘source’) present in the forecasts data. Default is None.
metric (str, optional) – Metric to assign to the forecasts if ‘metric’ column is not present or contains null values. Default is ‘levels’. Options: ‘levels’, ‘pop’, ‘yoy’.
compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.
data_check (bool, optional) –
Whether to run data checks comparing forecast values to outturns per (source, variable, metric, frequency) group. When True:
- Horizon-zero published-target check: if rows with
forecast_horizon == 0match an outturn released on or before the forecast vintage at the target date, warns that the target was already published at the forecast vintage. A negativetarget_minus_vintagealone is not flagged because it can be a legitimate backcast caused by a publication lag. Explicitly negative forecast horizons are allowed and are not flagged by this check.
Vintage-distance -1 check (primary): if
target_minus_vintage == -1rows exist, each is compared to the outturn from the same vintage at the same date. Warns if the mean absolute deviation exceeds 0.5 std of the outturn series.IQR ratio check (fallback): over all (date, vintage_date) pairs that overlap, warns if the forecast IQR differs from the outturn IQR by >5x.
Detects common user errors: wrong
metriccolumn, scaling mistakes (e.g.pct*100instead ofpct), or non-real-time vintages.Warnings only; never raises errors. Set to
Falseto disable. Default is True.first_forecast_horizon (int or dict[str, int], optional) – DEPRECATED legacy value used only when
forecast_horizonis absent. In that case, the missing horizon is derived fromtarget_minus_vintageand aFutureWarningis emitted. If this argument is omitted too, the same deprecated fallback is used without a shift. The argument is ignored whenforecast_horizonis present. Supplyforecast_horizonexplicitly instead.
Notes
Outturns must be added before forecasts (call add_outturns first). All forecasts added to a ForecastData instance must have the same frequency. To work with forecasts of different frequencies, create separate ForecastData instances for each frequency. When compute_levels is True, sufficient historical outturn data is required for transformation, especially for ‘yoy’ metrics which need data from one year prior.
- add_outturns(df: DataFrame, *, metric: Literal['levels', 'pop', 'yoy'] = 'levels') None[source]#
Validate new outturns and add them to the outturns dataset
- Parameters:
df (pd.DataFrame) – DataFrame containing new outturn records to add.
metric (str, optional) – Metric to assign to the outturns if ‘metric’ column is not present or contains null values. Default is ‘levels’. Options: ‘levels’, ‘pop’, ‘yoy’.
- clear_filter() None[source]#
Reset the forecasts, main and revisions tables to include all original data.
- copy() ForecastData[source]#
Return a deep copy of the ForecastData object.
- create_pseudo_vintages(fill_to: str, vintage_frequency: Literal['M', 'Q'] = 'Q', publication_lags: dict[str, int] | None = None) None[source]#
Create pseudo vintages for outturns.
Starts from the earliest available vintage in the data and fills backward to
fill_to.This method computes the publication lag from existing data and creates a full vintage structure where each vintage contains all data available at that point in time. A vintage at date X contains all data up to (X - publication_lag).
- Parameters:
fill_to (str) – The earliest vintage date to create (i.e. how far back to fill). Format ‘YYYY-MM-DD’. Vintages are generated from this date up to the earliest existing vintage in the data.
vintage_frequency (str, optional) – Frequency at which to create vintages. Default is ‘Q’ (quarterly). Options: ‘M’ (monthly), ‘Q’ (quarterly).
publication_lags (dict[str, int] or None, optional) – A dictionary mapping variable names to their publication lag (in units of
vintage_frequency). If None (default), the lag is computed from existing data.
Notes
Computes publication lag per variable from existing data (max_vintage - max_date)
Expands the dataset by creating multiple vintage records for each data point
Each vintage V includes all data points D where (D + lag) <= V
Requires outturns to already have vintage_date values to compute the lag
- property df: DataFrame#
Get the main DataFrame.
Alongside the forecaster-supplied
forecast_horizon, includestarget_minus_vintage: the forecast target’s period distance from its vintage (dateminusvintage_date, in periods at the row’s frequency). It is derived, not supplied, and is used internally for calendar/vintage geometry rather than information content.
- filter(start_date: str | None = None, end_date: str | None = None, start_vintage: str | None = None, end_vintage: str | None = None, variables: str | list[str] | None = None, metrics: list[str] | None = None, sources: str | list[str] | None = None, frequencies: str | list[str] | None = None, custom_filter: Callable[[DataFrame], DataFrame] | None = None) None[source]#
Filter the forecasts and main tables to only include data within specified date and vintage ranges, and optionally by variables, metrics, sources, or a custom filter.
- Parameters:
start_date (str, optional) – Start date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest date.
end_date (str, optional) – End date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest date.
start_vintage (str, optional) – Start vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest vintage.
end_vintage (str, optional) – End vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest vintage.
variables (str or list of str, optional) – List of variable identifiers to filter. Default is None (no filtering).
metrics (list of str, optional) – List of metric identifiers to filter. Default is None (no filtering).
sources (str or list of str, optional) – List of source identifiers to filter. Default is None (no filtering).
frequencies (str or list of str, optional) – List of frequency identifiers to filter. Default is None (no filtering).
custom_filter (Callable[[pd.DataFrame], pd.DataFrame], optional) – A custom filtering function that takes a DataFrame as input and returns a filtered DataFrame. Default is None. Custom filters should use ‘vintage_date_forecast’ as the column name.
- filter_fer() None[source]#
Filter the main dataset to only include specific variable-metric and model combinations
- property forecast_required_columns: list[str]#
Get the required columns list to help the user.
- property forecasts: DataFrame#
Get forecasts.
- property id_columns: list[str] | None#
Get identification / labelling columns.
- merge(other: ForecastData, compute_levels: bool = True) None[source]#
Merge another ForecastData instance into this one.
- Parameters:
other (ForecastData) – Another ForecastData instance to merge with this one.
compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts from other to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.
- Returns:
The method modifies this instance in place.
- Return type:
None
- property outturn_required_columns: list[str]#
Get the required columns list to help the user.
- property outturn_vintages: bool#
Whether the outturn data contains vintage information.
- property outturns: DataFrame#
Get outturns.
- run_dashboard(from_jupyter: bool = False, host: str = '127.0.0.1', port: int = 8000) None[source]#
Run the Shiny dashboard with the current data.
- Parameters:
from_jupyter (bool, optional) – Whether to run the dashboard within a Jupyter notebook. Default is False.
host (str, optional) – Host address for the dashboard server. Default is “127.0.0.1”.
port (int, optional) – Port number for the dashboard server. Default is 8000.
- summary() None[source]#
Print a summary of the forecast and outturns datasets.
For each dataset, displays: - Number of variables - List of variables with their properties - For each variable: frequency, date range, and first vintage date
- property supports_outturn_revision_analysis: bool#
Whether analyses and plots requiring outturn revisions are supported.
- property uses_intra_period_vintages: bool#
Whether forecast vintages are intra-period releases for the same target period.
When True, a target period has many forecast vintages and outturn releases within it, so analyses that assume one forecast per (source, horizon, period) - efficiency, forecast revision, correlation and radar analyses - do not apply, while intra-period analyses do.
- class forecast_evaluation.data.NowcastData(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#
Bases:
ForecastDataForecastData subclass for nowcasting evaluation.
Designed for environments where forecasts (and outturns) are released multiple times per period with intra-period vintage dates (e.g. weekly). Non-negative information horizons are used (h=0 nowcast, h=1 one-period- ahead) so that multiple weekly vintages per horizon provide many observations for accuracy statistics. Vintage-relative backcasts are identified by
target_minus_vintageinstead.Differences from ForecastData:
The main table includes a
days_to_publicationcolumn computed as(vintage_date_outturn - vintage_date_forecast).days, which can be used for intra-period accuracy analysis.Efficiency analyses (weak/strong efficiency, Blanchard-Leigh, revision predictability, revisions-errors correlation) are not available.
Notes
Two different time axes appear in nowcast analysis and should not be confused:
days_to_publication(this class) is the distance from the forecast vintage to the release date of the selected outturn vintage. It therefore depends onkand on the publication lag of the series.days_to_period_endis the distance from the forecast vintage to the end of the target period, independent of when the outturn is published.
The two differ by the publication lag. Intra-period accuracy and bias functions take an
axisargument ('period_end', the default, or'publication') to choose between them, and bin the result to the nearest 7 days.- __init__(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#
Initialise NowcastData.
- Parameters:
outturns_data (pd.DataFrame, optional) – DataFrame containing outturn records.
forecasts_data (pd.DataFrame, optional) – DataFrame containing forecast records.
extra_ids (list of str, optional) – Extra label columns in addition to ‘source’.
metric (str, optional) – Default metric if not present in the data. Default is ‘levels’.
compute_levels (bool, optional) – Whether to auto-transform non-levels forecasts to levels.
data_check (bool, optional) – Whether to run data checks when adding forecasts.
first_forecast_horizon (int or dict[str, int], optional) – DEPRECATED legacy value used when
forecast_horizonis absent. In that case, the missing horizon is derived fromtarget_minus_vintageand aFutureWarningis emitted. If this argument is omitted too, the same deprecated fallback is used without a shift. Supplyforecast_horizonexplicitly instead.
- add_benchmarks(*args, **kwargs)[source]#
Add benchmark model forecasts to the ForecastData instance.
Builds the requested benchmark models from the available outturn data and appends their forecasts to the instance via
add_forecasts(). The instance is modified in place.- Parameters:
models (list of str or str, optional) – Benchmark model(s) to add. Valid options are
"AR"(autoregressive AR(p) model) and"random_walk". Default is both (["AR", "random_walk"]).variables (str, iterable of str, or None, optional) – Variable(s) to build benchmarks for. If None (default), benchmarks are built for all variables present in the outturns.
metric (str, optional) – Metric to build the benchmarks for. Options:
"levels","diff","pop","yoy". Default is"levels".frequency (str, iterable of str, or None, optional) – Frequency (or frequencies) to build benchmarks for (
"Q"for quarterly,"M"for monthly). If None (default), frequencies are inferred from the outturns.forecast_periods (int, optional) – Number of periods to forecast ahead. Default is 13.
max_lag (int, optional) – Maximum number of lags (AR order) to consider when selecting the AR(p) model via BIC. Must be 1 or 2. Only applies to the
"AR"model. Default is 2.estimation_start_date (pd.Timestamp, optional) – The date from which to start including data for AR(p) model estimation. If None (default), all available data is used. Only applies to the
"AR"model.show_progress (bool, optional) – Whether to show progress bars while building the benchmarks. Default is False.
- Returns:
The method modifies the ForecastData instance in place.
- Return type:
None
- Raises:
ValueError – If any model in
modelsis not a recognised benchmark model.
- add_forecasts(df, **kwargs)[source]#
Add forecasts, aligning outturn vintages to forecast vintages first.
Alignment mutates the outturns before the parent validates the input, so the rollback discards those snapshots if the forecasts are rejected.
- add_outturns(df, **kwargs)[source]#
Add outturns, then normalise the internal
_alignedmarker column.Genuine new outturn releases never carry the
_alignedmarker (it is only set by_align_outturn_vintagesfor forward-filled snapshots). Concatenating them with existing aligned rows can introduce NaNs in this Boolean column, which would break~outturns["_aligned"]expressions elsewhere. Treat missing values as False (i.e. not aligned).
- clear_filter() None[source]#
Reset the forecasts, main and revisions tables to include all original data.
Overrides the parent implementation to reapply the nowcast-specific
krevision index anddays_to_publicationcolumn, which the parent’s calendar-based rebuild does not preserve.
- create_pseudo_vintages(*args, **kwargs)[source]#
Create pseudo vintages for outturns.
Starts from the earliest available vintage in the data and fills backward to
fill_to.This method computes the publication lag from existing data and creates a full vintage structure where each vintage contains all data available at that point in time. A vintage at date X contains all data up to (X - publication_lag).
- Parameters:
fill_to (str) – The earliest vintage date to create (i.e. how far back to fill). Format ‘YYYY-MM-DD’. Vintages are generated from this date up to the earliest existing vintage in the data.
vintage_frequency (str, optional) – Frequency at which to create vintages. Default is ‘Q’ (quarterly). Options: ‘M’ (monthly), ‘Q’ (quarterly).
publication_lags (dict[str, int] or None, optional) – A dictionary mapping variable names to their publication lag (in units of
vintage_frequency). If None (default), the lag is computed from existing data.
Notes
Computes publication lag per variable from existing data (max_vintage - max_date)
Expands the dataset by creating multiple vintage records for each data point
Each vintage V includes all data points D where (D + lag) <= V
Requires outturns to already have vintage_date values to compute the lag
- filter_fer()[source]#
Filter the main dataset to only include specific variable-metric and model combinations
- merge(other: ForecastData, compute_levels: bool = True) None[source]#
Merge another instance into this one, excluding synthetic outturn snapshots.
The parent implementation passes
other._raw_outturnsstraight throughadd_outturns, which strips the_alignedmarker (it isn’t part of the outturn schema). Forward-filled snapshots built by_align_outturn_vintageswould then be indistinguishable from genuine releases and could corrupt revision indices and outturn-revision analyses.This override merges only
other’s genuine outturn releases (_alignedis False or absent). Forecasts are merged as usual;add_forecasts(overridden above) regenerates aligned snapshots and recomputesk/days_to_publicationfor the merged data.
- property uses_intra_period_vintages: bool#
Whether forecast vintages are intra-period releases for the same target period.
- forecast_evaluation.data.create_sample_forecasts() DataFrame[source]#
Create sample forecasts DataFrame for testing and examples.
- forecast_evaluation.data.create_sample_nowcast_forecasts() DataFrame[source]#
Create sample nowcasting forecasts with weekly vintage dates.
Generates nowcasts (2020-2025) from two models for two variables (
gdpandcpi). Vintages are produced once per week across the full sample. Each vintage targets two consecutive releases:h = 1 (forecast): the next quarter (not yet started or in progress).
- h = 0 (nowcast): the current quarter (in progress).
- the previous quarter while its official outturn has not yet been
published (gdp: 6 weeks after quarter-end; cpi: 2 weeks after quarter-end). Once the data is released, that vintage-relative path stops.
Forecast errors converge toward zero as the vintage date approaches the end of the target quarter, with additive noise so that convergence is realistic rather than perfectly monotonic.
- Returns:
DataFrame with columns: date, variable, vintage_date, source, frequency, value, and the explicitly supplied
forecast_horizon.- Return type:
pd.DataFrame
Examples
>>> df = create_sample_nowcast_forecasts() >>> df["source"].unique() array(['nowcast_dfm', 'nowcast_bridge'], dtype=object)
Visualize how forecasts evolve over weekly vintages:
>>> # Import the plotting function from the end of this module >>> import matplotlib.pyplot as plt >>> from forecast_evaluation.data.sample_data import plot_sample_nowcasts >>> plot_sample_nowcasts() # Plots forecasts by horizon, colored by vintage date
- forecast_evaluation.data.create_sample_nowcast_outturns() DataFrame[source]#
Create sample outturns DataFrame for nowcasting tests and examples.
Creates quarterly outturns for two variables (
gdpandcpi) with multiple outturn vintages, covering 2020Q1 to 2025Q4 (24 quarters).Publication lags and revision frequencies are realistic:
gdp: first release 6 weeks (42 days) after the end of the target quarter, then revised once per quarter at each subsequent quarter-end.
cpi: first release 2 weeks (14 days) after the end of the target quarter, then revised monthly (14 days after each subsequent month-end).
For each target quarter, the outturn data has:
A first-release vintage at the publication date.
Subsequent revision vintages (quarterly for GDP, monthly for CPI) up to 2026-03-31, with white noise shrinking as the vintage matures.
The realistic first-release dates mean that intra-quarter nowcast vintages before the publication date have no backcast (h=-1) outturn available for pairing, while later vintages within that quarter do.
- Returns:
DataFrame with outturn data suitable for nowcasting evaluation.
- Return type:
pd.DataFrame