Predict.aiDocs
Segments

Engineered features

The full catalog of derived columns — lags, rolling statistics, differences, event and calendar features.

An engineered feature is a derived column: a transformation of one source field (or the row timestamp), declared on the segment and computed identically at training and inference time. They give the model context a single raw value can't carry — where the series has been (lags), how it's been behaving (rolling statistics), when it last moved (event features), and what time it is (calendar features).

Declaring one

Each entry in engineered_features names the output column, the technique, and the source field:

{
  "engineered_features": [
    {
      "name": "sales_ma7",
      "technique": "moving_average_7",
      "techniqueName": "Moving Average (7)",
      "sourceField": "daily_sales",
      "category": "Moving Averages"
    },
    {
      "name": "dow",
      "technique": "day_of_week",
      "techniqueName": "Day of Week",
      "sourceField": "ts",
      "category": "Time Features"
    }
  ]
}
FieldWhat it is
nameThe output column name — this is what the model sees.
techniqueA technique ID from the catalog below.
sourceFieldThe field to derive from; calendar features use the timestamp (ts).
techniqueName, categoryDisplay metadata (shown in the app and in field_info).
parametersOptional per-technique parameters (e.g. {"window": 14}, {"period_seconds": 604800}).

Engineered features are computed after gap-filling, so windows and lags run over the normalized grid — one value per row, no gaps. Every technique must come from the catalog; unknown techniques are rejected with 422 at create/edit time.

Windows and periods

Most rolling techniques encode their window in the ID (rolling_std_7 = 7 rows). The window counts grid rows, not wall-clock time: on a daily segment moving_average_7 is a 7-day average; on an hourly segment it's 7 hours. Window families accept any window size — the catalog lists the common presets, and you can request e.g. rolling_std_30 or pass parameters.window explicitly.

The catalog

Lag features

The value N rows back. The single most useful family — a label's own recent history is usually its strongest predictor.

TechniqueDescription
lag_1lag_7Previous value, 1–7 steps back (any lag_<n> works)

Moving averages

TechniqueDescription
moving_average_3, moving_average_7, moving_average_14, moving_average_30N-period simple moving average

Rolling statistics

TechniqueDescription
rolling_std_7Rolling standard deviation
rolling_min_7 / rolling_max_7Rolling extremes
rolling_median_7Rolling median
rolling_sum_7Rolling sum
rolling_kurtosis_<w>Rolling kurtosis — tail behavior for heavy-tailed series

Differences and changes

TechniqueDescription
lag_diff_1Difference from the previous row
lag_pct_changePercentage change from the previous row
momentum_3N-period momentum
rate_of_change_5N-period rate of change

Volatility and bands

TechniqueDescription
rolling_zscore_7Rolling z-score — how unusual is the current value
rolling_volatility_14Rolling volatility (stddev of percentage changes)
rolling_vol_diff_<w>Volatility of one-row differences — use instead of rolling_volatility_* for series that cross zero
bollinger_upper_20 / bollinger_lower_20SMA ± 2 standard deviations
rolling_bandwidth_20Band width relative to the moving average
cumulative_returnCumulative return since the window start

Event features

Sparse, slow-moving signals (monthly indicators, rarely-changing flags) carry most of their information at the moment the value changes. These turn that moment into a dense column the model can learn from on every row:

TechniqueDescription
release_flag1 on the row where the source value changed (or first appeared), 0 otherwise
release_surpriseThe signed delta from the previous value — pair with rolling_zscore_7 for a normalized surprise
time_since_releaseSeconds since the value last changed; resets to 0 on each change
time_since_spikeSeconds since the source last moved more than parameters.threshold in one row
stalenessSeconds since the source's last raw observation — true data age, independent of gap-filling

Calendar features

Computed from the row timestamp (in the segment's time_zone) — no source value involved:

TechniqueDescription
hour_of_day, day_of_week, day_of_month, day_of_yearPosition within the day/week/month/year
week_of_year, month_of_year, quarter_of_year, yearCoarser calendar position
is_weekend, is_business_dayWeekend / weekday flags
is_month_start, is_month_end, is_quarter_start, is_quarter_end, is_year_start, is_year_endBoundary flags
cyclic_sin / cyclic_cosSmooth phase encoding of an arbitrary period (parameters.period_seconds) — better than raw calendar integers for strong seasonality

Seeing them in action

Engineered features show up like any other column — in preview output, in field_info, and in the table the model trains on:

{
  "data": {
    "data": {
      "timestamp": ["2026-07-13T00:00:00.000000Z", "2026-07-14T00:00:00.000000Z"],
      "daily_sales": [12100.0, 12841.5],
      "sales_ma7": [11980.2, 12111.5],
      "dow": [0, 1]
    },

  }
}

Goal discovery generates engineered features automatically from measured data — inspect a goal's segment to see which transforms it chose. For hand-built segments, start with a lag or two and a moving average of the label; add event features for sparse drivers.

On this page