Enhance task cardinality and introduce exogenous forecasting - #860
Open
Irozuku wants to merge 2 commits into
Open
Enhance task cardinality and introduce exogenous forecasting#860Irozuku wants to merge 2 commits into
Irozuku wants to merge 2 commits into
Conversation
A task stated its column contract as one list of allowed types plus one
cardinality for the whole side. That cannot express "one date column and
any number of numeric ones": a single total accepts two dates and no
numbers just as readily.
Tasks now declare a list of groups, each naming interchangeable types and
how many columns of that set it takes, the way BaseGenerativeTask states
its per-type counts. Cardinality may be an exact int, "n", or a
{min, max} range. The older two-key spelling is read as a single group,
so existing tasks and plugins are unchanged, and get_metadata reports
both views so every current consumer keeps reading what it read before.
The column picker banner renders one requirement line per group.
ForecastingTask offers a model the date and nothing else, so a series that is driven by something measurable, a price, a promotion, the temperature, could only be forecast from its own history. ExogenousForecastingTask takes the same date column with one or more numeric variables beside it, which the per-group column contract can now express. It is a separate task rather than a wider ForecastingTask so that each stays honest about what it offers: a model reading only a date would silently drop the variables the user selected, and a model needing them cannot be fitted without them. What the two share, sorting the rows by date and reporting no labels, moves to TimeSeriesTask. The date column is now found by type rather than by position, since with variables alongside it need not come first. The temporal splitters, the forecasting evaluation strategies, the regression metrics and the Optuna optimizer serve the new task too.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ForecastingTaskoffers a model the date and nothing else, so a series driven by something measurable (a price, a promotion, the temperature) could only be forecast from its own history.ExogenousForecastingTasktakes the same date column with one or more numeric variables beside it, which the per group column contract from the previous branch can now express:Datewith cardinality 1, andFloat/Integerwith cardinality{min: 1, max: "n"}.It is a separate task rather than a wider
ForecastingTaskso that each stays honest about what it offers. A model reading only a date would silently drop the variables the user selected, and a model needing explanatory variables cannot be fitted without them.What the two tasks share moves to
TimeSeriesTask.Type of Change
Check all that apply like this [x]:
Changes (by file)
DashAI/back/tasks/time_series_task.py: new. Holds what both forecasting tasks share:PREDICTS_FORWARD_ONLY, sorting the rows by date, reporting no labels, and passing predictions through undecoded._date_columnfinds the date column by type rather than by position, since with variables alongside it need not come first. Added_date_column;_sort_by_date,process_predictionsandnum_labelsmoved here unchanged fromforecasting_task.py.DashAI/back/tasks/exogenous_forecasting_task.py: new. The task itself: metadata, description and display name in the five locales.DashAI/back/tasks/forecasting_task.py: reduced to its metadata and its strings, now subclassingTimeSeriesTask. Metadata restated in the group form, which yields an identical flat view.DashAI/back/initial_components.py: registersExogenousForecastingTask.DashAI/back/splitters/temporal_holdout.py,DashAI/back/splitters/rolling_origin.py: serve the new task too.DashAI/back/evaluation/forecasting_holdout.py,DashAI/back/evaluation/forecasting_cv.py: same.DashAI/back/metrics/regression_metric.py: same, which carries MAE, RMSE, MAPE and SMAPE across.DashAI/back/optimizers/optuna_optimizer.py: same.tests/back/tasks/test_exogenous_forecasting_task.py: new. Covers one variable and many, the date column arriving last, a date on its own being refused, variables without a date being refused, a second date column, a text variable, two outputs, the rows coming back in date order, and the metadata.tests/back/evaluation/test_forecasting_strategies.py,tests/back/splitters/test_splitter_partitioning.py: compatibility assertions widened, and the shuffling holdout splitter is now asserted to exclude both forecasting tasks.Testing
Notes
The shared base is named
TimeSeriesTask, notBaseForecastingTask.ComponentRegistry._get_base_typeselects MRO ancestors whose name contains"Base"and refuses a component with more than one, so an intermediate class withBasein its name breaks registration of every task under it. This follows the convention already used for models, whereForecastingModelsits underBaseModel.Non forecasting splitters and evaluation strategies list their tasks explicitly, so none of them picked up the new task by accident.