Skip to navigation

Forecasting

View as Markdown

Forecasting repeats a temporal target across consecutive future windows. Use forecasting when you need a sequence of predictions for one entity rather than a single aggregate over the entire horizon.

In this client workflow, sdm-client asks one regression call per forecast step and assembles the results — materialize() and predict() still handle it in one call each on your side. This also works with deployments that natively serve only classification and regression.

Minimal forecast

from sdm_client import PredictiveQuery, SDMClient, KumoRelational
query = PredictiveQuery(
"""
PREDICT SUM(orders.amount, 0, 7, days)
FORECAST 8 TIMEFRAMES
FOR accounts.account_id=42
""",
schema,
)
request = query.materialize(indices=[42])
with SDMClient(url="http://localhost:8000") as client:
result = client.predict(request, model=KumoRelational())

This query requests eight consecutive predictions for seven-day windows for account 42, as eight calls.

Requirements and limits

  • Forecast predictions for one entity per request.
  • Use a temporal aggregation with an explicit window and unit.
  • Provide enough ordered history before the anchor time to represent the pattern.
  • Ensure that the target and entity have a valid relationship in the schema.
  • A forecast cannot be pinned with fit() — each step needs the context that supplies its own labels, while a session pins one context.

Supported target forms depend on the deployed NIM release. Start with SUM, COUNT, or COUNT_DISTINCT.

Window semantics

For the following target:

PREDICT SUM(orders.amount, 0, 7, days)
FORECAST 8 TIMEFRAMES

The first forecast row covers the first seven-day window after the anchor time. The second row covers the next seven-day window, and so on. The start boundary is excluded, and the end boundary is included: 0, 7, days covers (anchor, anchor + 7 days].

Anchor time and lagged targets

import pandas as pd
request = query.materialize(
indices=[42],
anchor_time=pd.Timestamp("2025-01-01T00:00:00Z"),
lag_timesteps=3,
use_prediction_time=True,
)
  • anchor_time sets the beginning of the forecast.
  • lag_timesteps supplies previous target windows as additional context.
  • use_prediction_time supplies the prediction timestamp as a feature.

Evaluate these options with historical backtests because they do not improve results for every dataset.

Narrowing the context narrows by anchor, not at random

When num_context_samples narrows a forecast’s gathered context, each step narrows around its own anchor, keeping the newest anchor dates in full rather than thinning the whole span. random_seed governs which entities are sampled within an anchor, not which anchor dates are kept. See Limits.

Results

result.to_pandas() carries row_index, id, prediction, and forecast_step — a one-based sequence number for the forecast period. A forecast returns one row per timeframe.

answers = result.to_pandas()
print(answers[["id", "forecast_step", "prediction"]].head())

Troubleshooting

SymptomCheck
Forecast validation failsConfirm a single explicit entity, supported aggregation, time column, and timeframe count.
Too little historyMove the anchor later or include more pre-anchor events.
Request is too largeReduce num_context_samples, columns, relationships, or timeframe count; or lower rows_per_call.
Poor backtest accuracyRecheck window boundaries, leakage, seasonality, and lag settings before increasing context size.