> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/sdgm/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/sdgm/_mcp/server.

# Predict a Yes or No Outcome on Linux

> Train a temporal binary model and choose a probability threshold for its predictions

Predict whether each active AdventureWorks customer will order in the next 90 days, then convert the model's probabilities into yes or no predictions.
This example runs a binary classification fit and writes predictions at three probability thresholds.
Evaluate the model and choose a threshold that matches your business objective before using its decisions.
This guide uses the local Python API from the Linux setup. Do not combine its calls with legacy Kumo Studio examples.

## Run the Complete Example

Complete [Linux Machine Deployment Setup](/kumo-engine/1.0.0/get-started-with-kumo-engine/installation/linux-machine-deployment), then download the [Linux examples bundle and prepare the sample CSV files](/kumo-engine/1.0.0/examples/linux-local-examples#prepare-the-input-files).
Use the four prepared AdventureWorks CSVs.
Activate the installed Python environment and keep `ADVENTUREWORKS_DATA` set to the prepared CSV directory.

Run this command from the extracted bundle directory.
Replace the two output paths with new, separate directories.
Use local storage for scratch and retain results on storage whose lifetime meets your needs.
Keep both directories separate from the inputs and from each other.

```bash
export KUMO_BINARY_OUTPUT=/path/to/retained-results/adventureworks-binary-01
python adventureworks_binary.py \
  --input-dir "$ADVENTUREWORKS_DATA" \
  --scratch-dir /path/to/local-storage/adventureworks-binary-scratch \
  --output-dir "$KUMO_BINARY_OUTPUT" \
  --prediction-time 2025-06-30T00:00:00
```

The script builds the graph, generates historical labels from the event data, suggests a model plan, trains the model, and writes the model and prediction outputs.
Review the model plan and training budget before adapting it to production data.
It saves the model under `model/` and writes one prediction file for each threshold: `0.0`, `0.5`, and `1.0`.
It trains only once.

A nonzero exit means the example did not complete.
Preserve its error and existing outputs, correct the reported problem, and choose a new output directory before another attempt.

## Understand the Prediction Task

The script uses this predictive query:

```text
PREDICT COUNT(SalesOrderHeader.*, 0, 90, days) > 0
FOR EACH Customer.CustomerID
WHERE COUNT(SalesOrderHeader.*, -365, 0, days) > 0
```

At each training time, the label asks whether the customer has at least one order after that time and up to and including 90 days later.
The `> 0` comparison turns a numeric event count into a binary target.
It is separate from the probability threshold used after the model predicts.

Generated training rows use `ENTITY1`, `TIMESTAMP`, and `TARGET1`.
The `WHERE` clause limits the population to customers with an order in the preceding 365 days.

## Set the Prediction Time and Threshold

The example predicts from June 30, 2025.
Pass a datetime without timezone information; Kumo interprets it as UTC.
Set the time when generating the prediction table. Pass that table and the matching snapshot to inference.

When adapting the script in your own Python process, use the following call pattern.
It requires the binary `query`, its training `snapshot`, the fitted `trainer`, and `KUMO_BINARY_OUTPUT` from the example.
The output configuration writes a separate `binary-custom.parquet` file and replaces that file if the call is repeated.
The [training guide](/kumo-engine/1.0.0/user-code-guide/code-examples/linux-deployment/train-a-classification-model) explains fitting; the bundled script contains the complete binary setup.
These objects do not remain available after the script exits.

```python
from datetime import datetime
import os
from pathlib import Path

from kumo.engine import FileConnector
from kumo.engine.trainer.output_config import PredictionOutputConfig
from kumoapi.jobs import PredictionArtifactType, WriteMode

output = Path(os.environ["KUMO_BINARY_OUTPUT"]).expanduser().resolve()
output_config = PredictionOutputConfig(
    connector=FileConnector(root_dir=str(output)),
    artifact_type=PredictionArtifactType.PREDICTIONS,
    table_name="binary-custom.parquet",
    write_mode=WriteMode.OVERWRITE,
)
prediction_time = datetime(2025, 6, 30)
prediction_table = query.generate_prediction_table(
    snapshot, prediction_time=prediction_time
)
result = trainer.predict(
    prediction_table,
    snapshot=snapshot,
    binary_classification_threshold=0.5,
    output_config=output_config,
)
```

Supply a finite numeric threshold from `0` to `1`, inclusive; the API does not select `0.5` for you.
If the call reports that `binary_classification_threshold` must be specified, add this argument.
An out-of-range or nonfinite value raises a `ValueError`; replace it with a finite number in the permitted range.
A row is predicted true only when `True_PROB` is strictly greater than the supplied threshold.
A probability equal to the threshold is predicted false.
Changing the threshold changes this decision rule; it does not retrain the model.
Do not assume that separate inference calls produce numerically identical probabilities.

## Inspect the Saved Predictions

After the script exits, read its middle-threshold output in a new Python process with the same `KUMO_BINARY_OUTPUT` environment variable:

```python
import os
from pathlib import Path

import numpy as np
import pandas as pd

output = Path(os.environ["KUMO_BINARY_OUTPUT"]).expanduser().resolve()
predicted = pd.read_parquet(output / "predictions-threshold-0.5.parquet")
columns = ["ENTITY", "TIMESTAMP", "TARGET_PRED", "False_PROB", "True_PROB"]
missing = set(columns) - set(predicted.columns)
if missing:
    raise KeyError(f"Missing prediction columns: {sorted(missing)}")
probabilities = predicted[["False_PROB", "True_PROB"]]
assert np.isfinite(probabilities.to_numpy()).all()
assert probabilities.ge(0).all().all() and probabilities.le(1).all().all()
assert np.allclose(probabilities.sum(axis=1), 1, atol=1e-6)
assert predicted["TARGET_PRED"].eq(predicted["True_PROB"].gt(0.5)).all()
print("Rows:", len(predicted))
print(predicted.head())
```

Expect one row per eligible customer, with these columns:

| Column        | Meaning                                                         |
| ------------- | --------------------------------------------------------------- |
| `ENTITY`      | Customer identifier                                             |
| `TIMESTAMP`   | Requested prediction time                                       |
| `False_PROB`  | Predicted probability that the query's binary target is false   |
| `True_PROB`   | Predicted probability that the query's binary target is true    |
| `TARGET_PRED` | True or false decision after applying the probability threshold |

The other two files are `predictions-threshold-0.0.parquet` and `predictions-threshold-1.0.parquet`.
Each applies its own threshold to the same type of output.
Use an appropriate evaluation dataset and training budget before choosing a production threshold.

See [Making Predictions](/kumo-engine/1.0.0/user-code-guide/making-predictions) for prediction parameters and output retention, and [Publish and Retrieve Models](/kumo-engine/1.0.0/user-code-guide/train-a-model/publish-and-retrieve-models) for model reload requirements.