> 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.

# Customer Churn Prediction

Customer churn is the moment an engaged user quietly stops coming back, and a retention team wants to reach the users who are about to slip away while there is still time to win them back. This example makes three kinds of churn prediction: it flags users who are about to go completely inactive, it flags users who are about to stop buying, and it flags users who are about to abandon one specific high-value behavior such as streaming. Each one looks ahead from a user and predicts what will happen in the coming weeks, and Kumo Engine learns the pattern from the user's own profile and the activity and purchase history connected to that user in the graph.

## Data and relationships

The example assumes a prepared Kumo Engine `graph`, a matching `snapshot`, and these tables:

| Table    | Required columns                                                                             | Purpose                                                                                                                                         |
| -------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `users`  | `user_id` as the primary key, plus optional profile columns such as `signup_date` and `plan` | The customers, and the entity every query scores.                                                                                               |
| `events` | `event_id` as the primary key, plus `user_id`, `event_timestamp`, and `event_type`           | The activity log. Each row is one action a user took, and `event_type` names the action, for example `login`, `stream`, `click`, or `purchase`. |
| `orders` | `order_id` as the primary key, plus `user_id`, `order_date`, and `order_value`               | The purchase log, used by the purchase-churn query.                                                                                             |

Connect `events.user_id` to `users.user_id` and `orders.user_id` to `users.user_id`. Mark `event_timestamp` as the time column of the events table and `order_date` as the time column of the orders table. These time columns place every activity and purchase in time, so each prediction is trained and scored using only the history recorded before the point it looks ahead from. The `users` table has no time column of its own, so it is a static entity: each forward-looking window is measured from the scoring time, the moment you run the prediction, rather than from anything on the user row.

Every query here predicts a future window and restricts the users it scores. The target counts a user's actions over the days that follow the scoring time and compares that count to `0`, which turns "did nothing" into a churn label. The trailing `WHERE` keeps the prediction on users who were recently active, because a user who is already gone has nothing left to churn. The forward window is half-open: it excludes actions at the exact scoring time and includes actions through the end of the window.

## Predict which active users are about to go inactive

This query flags users who are engaged today but are about to stop showing up at all. `COUNT(events.*, 0, 30, days)` counts every action a user takes over the 30 days that follow the scoring time, and `= 0` turns "no activity at all" into a yes churn label. The trailing `WHERE COUNT(events.*, -30, 0, days) > 0` keeps the prediction on users who did something in the previous 30 days, so the model learns to separate a recently-active user who stays from one who disappears rather than scoring users who already left.

```python
from kumo.engine import PredictiveQuery

query_text = (
    "PREDICT COUNT(events.*, 0, 30, days) = 0 "
    "FOR EACH users.user_id "
    "WHERE COUNT(events.*, -30, 0, days) > 0"
)
query = PredictiveQuery(graph, query_text)
query.validate()
print(query.get_task_type())  # binary_classification
```

## Predict which recent buyers are about to stop buying

Engagement and revenue are not the same thing: a user can keep logging in while their spending dries up. This query looks ahead from each user and predicts whether they will place no orders in the next 30 days. `COUNT(orders.*, 0, 30, days) = 0` turns "no purchases in the window" into a yes churn label, and `WHERE COUNT(orders.*, -90, 0, days) > 0` keeps the prediction on users who bought at least once in the previous 90 days, so the model scores real customers rather than users who never purchased. The purchase window on the `WHERE` is wider than on the activity query because buying happens less often than logging in.

```python
query_text = (
    "PREDICT COUNT(orders.*, 0, 30, days) = 0 "
    "FOR EACH users.user_id "
    "WHERE COUNT(orders.*, -90, 0, days) > 0"
)
query = PredictiveQuery(graph, query_text)
query.validate()
print(query.get_task_type())  # binary_classification
```

## Predict which users are about to abandon one behavior

A user rarely churns all at once; they often drop the one habit that gives your product its value first, such as streaming on a media service or ordering on a marketplace. This query filters the activity log down to a single behavior and predicts whether the user will stop it. `COUNT(events.* WHERE events.event_type = 'stream', 0, 30, days)` counts only the streaming events in the forward window, and `= 0` flags a user who is about to stop streaming even if they keep doing other things. The trailing `WHERE` still restricts the prediction to recently-active users. Swap `'stream'` for whichever `event_type` names your product's core habit.

```python
query_text = (
    "PREDICT COUNT(events.* WHERE events.event_type = 'stream', 0, 30, days) = 0 "
    "FOR EACH users.user_id "
    "WHERE COUNT(events.*, -30, 0, days) > 0"
)
query = PredictiveQuery(graph, query_text)
query.validate()
print(query.get_task_type())  # binary_classification
```

## Reading the predictions

Each query returns a probability that the named kind of churn will happen for a user in the coming weeks. The inactivity query lets a retention team rank the users most likely to disappear entirely and reach them with a re-engagement campaign first. The purchase query surfaces users whose spending is about to stop even while they still log in, which is the right audience for an offer or a loyalty nudge. The behavior query points to users about to drop your product's core habit, which is often the earliest warning sign and the cheapest moment to intervene.

All three are estimates from past behavior, not guarantees, and each is anchored at the time you run it, so the model uses only history recorded before that moment and never sees the outcome it predicts. The 30-day forward window and the recent-activity windows in the `WHERE` clause are starting points; widen or narrow the number of days to match how far ahead your team can act and how often your users normally return. Refresh the predictions as new activity and orders arrive so each decision reflects the latest behavior.