Skip to navigation

Understand Prediction Results

View as Markdown

client.predict() and FittedModel.predict() always return a PredictionResult — never a DataFrame sometimes and an explanation object other times.

result = client.predict(request, model=KumoTabular())
result.to_pandas() # always a frame
result.metadata # whatever the endpoint reported
result.explanations # gradients and column cohorts when requested and supported

For upcoming explanation support and its deployment requirements, see Explain Kumo Tabular Predictions. Explanations are separate from to_pandas(): use .explanations.gradients.to_pandas() or .explanations.columns.to_pandas() after checking that column analysis is available.

How many rows come back

The shape depends on the task, not the model:

TaskRows
classificationOne per entity
regressionOne per entity

Kumo Tabular does not produce ranked or multi-step results, so every prediction is one row per scored row.

Joining

Every row carries row_index. It also carries id — the entity’s key — when the schema declared one; a single-table request with no primary key has none.

Join on the key when it is there, otherwise on row_index. Never on row order. The endpoint is not required to return rows in the order they were sent.

answers = result.to_pandas()
joined = (
to_score.reset_index(drop=True)
.reset_index(names="row_index")
.merge(answers, on="row_index")
)

row_index in the response is the zero-based position of each row within the frame you sent — not whatever index labels to_score happened to carry. Drop to_score’s own index first (reset_index(drop=True)) before turning the position into a row_index column; skipping that step silently mismatches predictions to rows whenever to_score was filtered, sorted, or sliced beforehand.

Columns

FieldColumn(s)
predictionprediction
probabilitiesprobability_<class>, one per class
quantilesquantile_<level>, one per level

A column appears only when at least one returned row carries that field, so a classification result has probability_* columns and a regression one has quantile_* columns without either inventing the other.

A regression on Kumo Tabular always reports the mean of its predicted distribution under prediction, and does not take prediction_statistic — that option exists only for the relational model, which defaults to the median instead. See Kumo Relational: What a regression reports.

Which fields the answer actually carries

outputs=[...] on predict() asks for fields; it does not guarantee they come back. Check what you asked for against what arrived:

result = client.predict(request, model=KumoTabular(), outputs=["prediction", "quantiles"])
missing = result.absent(["prediction", "quantiles"])

sdm-client also warns when a requested field is absent from the answer, naming it.

Illustrative shapes

Classification:

row_index prediction probability_0 probability_1
0 0 0 0.79 0.21
1 1 1 0.12 0.88

Regression:

row_index prediction
0 0 128.40
1 1 301.75

These examples show only the column structure. The values depend on the query and the deployed release.

An empty result still has columns

Scoring an empty predict frame is legal — it is what a filter that matched nothing produces — and to_pandas() returns a frame with row_index and the requested output columns, not a frame with zero columns.