Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.summand.com/llms.txt

Use this file to discover all available pages before exploring further.

The Predictors component is a two-piece chain:
  • ebm_model (internal) — fits the EBM and persists it to S3.
  • ebm_graphs (user-visible) — extracts the global explanation, serializes shape functions and importance scores, and writes the JSON the dataset page renders.
You pick ebm_graphs in the experiment editor; ebm_model runs automatically as a dependency. The split exists so changing display-only behavior doesn’t refit the model.

Why EBMs

Explainable Boosting Machines sit at the intersection of “interpretable enough to read” and “accurate enough to ship”:
  • Per-feature shape functions are exact. No SHAP approximations. The model literally is the sum of those curves plus a small number of pairwise interaction terms.
  • Predictions decompose row-by-row. Every prediction has an additive breakdown — “here’s exactly which features pushed this score up or down.”
  • Categorical features handled natively. EBMs use feature_types=['nominal'] for categoricals; no one-hot encoding pollution in the explanations.
  • Performance is competitive. Within a few points of XGBoost on most tabular targets, while remaining fully readable.

Inputs

InputTypeRequiredDescription
target_columncolumn referenceThe column to explain or predict. Must be in the dataset’s schema.
The target’s distribution determines the task type:
  • Binary classification — exactly two distinct values.
  • Regression — continuous numeric.
  • Multiclass is on the roadmap; today the component rejects targets with three or more distinct categorical values.

Output shape (ebm_graphs)

{
  "features": [
    {
      "name": "tenure_months",
      "index": 0,
      "importance": 0.342,
      "type": "continuous",
      "names": [0, 12, 24, 36, 48, 60, 72],
      "scores": [-0.85, -0.34, 0.12, 0.41, 0.47, 0.39, 0.21],
      "upper_bounds": [-0.71, -0.21, 0.24, 0.55, 0.62, 0.51, 0.34],
      "lower_bounds": [-0.99, -0.47, 0.00, 0.27, 0.32, 0.27, 0.08],
      "density": {
        "names": [...],
        "scores": [...]
      }
    },
    {
      "name": "region & plan_tier",
      "index": 14,
      "type": "interaction",
      "importance": 0.082,
      "scores": [[...], [...]],
      "names": [["us-east", "us-west", "eu"], ["free", "pro"]]
    }
  ],
  "feature_names": [...],
  "feature_importances": [...],
  "metadata": { ... }
}
The artifact is written gzipped as graphs.json.gz. Each feature has:
  • scores — the y-axis of the shape function (the contribution at each x-value).
  • upper_bounds / lower_bounds — confidence bounds, derived from EBM’s bagged ensemble.
  • density — how many rows fall at each x-value (helps you spot when the curve is undersupported).
  • importance — the global feature importance (mean absolute contribution across the training set).
Pairwise interaction terms appear as 2-D scores matrices with two names arrays (one per axis).

Display

The Predictors component ships with a bespoke React viewer (EBMVisualization) instead of the generic block renderer. It draws:
  • Feature importance bar chart — sorted descending.
  • Shape functions per feature — line chart with confidence band, density underneath.
  • Pairwise interactions as heatmaps — for the small number of interaction terms EBM keeps.

Filtering from chat

Summand reads ebm_graphs via the analyze tool. Without parameters, it gets the summary fields (importances, feature names). With a feature_name parameter, it gets the full shape function for one feature plus an LTTB-downsampled version for context efficiency:
analyze({ component: "ebm_graphs", target: ..., params: { feature_name: "tenure_months" } })
This lets the agent ground answers like “Why is tenure important?” in the actual shape function rather than approximating from importance alone.

Compute profile

ComponentProfileTier
ebm_modelFargate4 CPU, 16 GB; scales with row count
ebm_graphsFargate2 CPU, 8 GB
Most datasets fit in a few minutes on the standard tier. Datasets with millions of rows or hundreds of features take longer; the dispatcher routes them to the larger Fargate tier automatically when the row count crosses an internal threshold.

Common gotchas

Either the target genuinely is noise relative to the columns you provided, or the target is a near-copy of one of the inputs (e.g. revenue = price × quantity and you have all three). EBM excludes near-tautological features, which can leave the result looking empty. Try removing suspect feature columns and re-running.
Two causes: insufficient data (under ~500 rows for the relevant feature value), or the feature is near-collinear with another feature. Check the density underneath the curve — if it’s spiky, the curve is undersupported in that region.
EBM needs at least a few hundred non-null target rows. Filter the source before running the experiment, or pick a different target.