Predict.aiDocs
Segments

Normalization

Every gap-filling strategy, fallback chains, per-field overrides, point-in-time safety, and templates.

Raw signals rarely land on a perfect grid. When a segment row has no value within tolerance for some field, that cell is a gap — and the normalization strategy decides what fills it. Choosing well matters: fill a status flag by interpolation and you invent states that never happened; carry a noisy sensor forward and you freeze noise into fact.

The strategy object

A strategy is a config object with a primary, an ordered fallback chain, and its own tolerance:

{
  "primary_strategy": "linear_interpolation",
  "fallback_strategies": ["nearest_value", "previous_value", "mean"],
  "tolerance": 60
}

The primary is tried first; each fallback runs only for cells the previous strategies couldn't fill. A chain ending in zero or none always resolves — chains that end in a value-dependent strategy can still leave empty cells at the edges of your data.

A segment sets one global strategy and may override it per field:

{
  "normalization_strategy": {
    "primary_strategy": "nearest_value",
    "fallback_strategies": ["previous_value", "zero"],
    "tolerance": 43200
  },
  "segment_strategies": {
    "promo_active": {
      "primary_strategy": "previous_value",
      "fallback_strategies": ["zero"],
      "tolerance": 86400
    }
  }
}

Per-field overrides win for their field; everything else uses the global strategy.

The strategy catalog

StrategyFills a gap withBest for
previous_valueThe most recent earlier valueStates, counters, sparse series — anything that "stays" until it changes
forward_valueThe next later valueBackfilling historical tables where future context is acceptable
nearest_valueThe closest value, earlier or laterGeneral-purpose numeric data
linear_interpolationA straight line between neighborsSmooth continuous quantities (temperature, price)
meanThe field's segment-wide meanNoisy, stationary series
medianThe field's segment-wide medianLike mean, robust to outliers
zero0Counts and event-like fields where absence means zero
noneNothing (left empty)When the model should see missingness
custom:<value>A constant you choose (custom:42, custom:false)Domain-specific sentinel values
db_previous / db_nearestSame as previous_value / nearest_valueAccepted for backward compatibility

Anything outside this catalog is rejected with 422 at create/edit time — a segment that can't be served never gets saved.

Choosing per data shape

Your field looks likeUse
Continuous sensor reading (temperature, load)linear_interpolationnearest_valueprevious_value
State or category (promo_active, mode)previous_valuenearest_value — never interpolate states
Counter / accumulating totalprevious_valuenearest_valuezero
Sparse, slow-moving (monthly indicator)previous_value with a generous tolerance — and consider event features
Highly variable / noisymean or median in the chain to smooth
Event countszero — no event means zero

Point-in-time safety

Several strategies look forward in time: forward_value, nearest_value (its forward half), and linear_interpolation (which needs the next point). That's fine for training tables built from settled history — but if you're simulating "what did we know at time T?" (backtests, leakage-sensitive evaluation), forward-looking fills leak the future.

Set pit_safe: true on the segment and every strategy — global and per-field — is substituted with its causal equivalent automatically:

ConfiguredExecuted under pit_safe
forward_value, nearest_value, linear_interpolationprevious_value
mean, medianzero
previous_value, zero, none, custom:<value>unchanged

Your stored configuration is untouched — the substitution happens at query time, so one segment can serve both a standard training table and a point-in-time-safe one.

Templates and suggestions

Rather than picking blind, fetch pre-built templates plus suggestions derived from your workspace's actual data patterns — cadence, variability, counter-like behavior, categorical fields:

curl "$API_BASE/v1/segment/normalization-templates" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "templates": [
      {
        "name": "Time Series Sensor Data",
        "description": "Ideal for continuous numeric data like temperature, pressure, etc.",
        "global_strategy": {
          "primary_strategy": "linear_interpolation",
          "fallback_strategies": ["nearest_value", "previous_value", "mean"],
          "tolerance": 60
        },
        "field_examples": ["temperature", "pressure", "humidity", "voltage"]
      },
      { "name": "Categorical or State Data",  },
      { "name": "Counter or Accumulating Data",  },
      { "name": "Sparse Data",  },
      { "name": "Highly Variable Data",  }
    ],
    "suggested": [
      {
        "name": "Workspace Counter Data",
        "description": "Optimized for your fields that show accumulating/counting behavior",
        "global_strategy": {
          "primary_strategy": "previous_value",
          "fallback_strategies": ["nearest_value", "zero"],
          "tolerance": 120
        },
        "field_examples": ["page_views", "order_count"],
        "is_suggested": true,
        "confidence": "high",
        "reason": "Based on the accumulating/counting pattern detected in these fields"
      },

    ],
    "analysis": {
      "fields_analyzed": 12,
      "numeric_fields": 10,
      "string_fields": 2,
      "patterns_detected": { "accumulating": 2, "highly_variable": 3, "categorical": 2 }
    }
  }
}

templates are the five standard starting points; suggested entries are generated from your data (each with a confidence and a reason) and name the actual fields they were derived from in field_examples. Copy a global_strategy straight into your create call — the shapes match.

Workspaces with fewer than two signals get the standard templates and a default suggestion only — the pattern analysis needs data to work with.

On this page