Skip to navigation

Write Predictive Queries

View as Markdown

This tutorial shows how to translate a business question into a Predictive Query Language (PQL) query that Kumo can use to generate predictions from relational data. You will test the query on a small set of entities first, which makes errors easier to diagnose before you scale to a larger request.

Before you begin, you need a validated Kumo relational graph assigned to graph and a few entity IDs that exist in the graph.

Example question

How much will each customer spend during the next 30 days?

Assume the graph contains customers(customer_id, ...) and orders(order_id, customer_id, amount, order_time).

1. Choose the entity

The result should contain one prediction for each customer. Therefore, identify the entity by the customers.customer_id primary key.

FOR EACH customers.customer_id

2. Define the target and horizon

The target is the sum of future order amounts. The prediction anchor time is the cutoff between the historical data Kumo uses as context and the future period you want to predict. The interval 0, 30, days starts at that cutoff and ends 30 days later.

PREDICT SUM(orders.amount, 0, 30, days)

3. Start with explicit entities

Combine the two parts into a complete query for a few known entity IDs:

PREDICT SUM(orders.amount, 0, 30, days)
FOR customers.customer_id IN (101, 102, 103)

Start without filters so that you can isolate errors in the target, graph relationships, and entity selection.

Use backticks around identifiers that contain spaces, punctuation, a leading digit, or another character the PQL grammar cannot express as a bare name. Quote the table and column separately:

PREDICT SUM(`Order Lines`.`Line Total`, 0, 30, days)
FOR EACH `My Customers`.`Customer ID`

Backticks delimit identifiers; string values continue to use single quotes. Quote each identifier segment independently, leaving the dot between the table and column outside the backticks.

4. Submit and inspect

from kumo_relational_client import RelationalClient
query = """
PREDICT SUM(orders.amount, 0, 30, days)
FOR customers.customer_id IN (101, 102, 103)
"""
with RelationalClient(url="http://localhost:8000") as client:
result = client.relational(graph).predict(query, run_mode="fast")
print(result[["ENTITY", "PREDICTION"]])

RelationalClient submits the query to the Kumo Relational service at the configured URL. The run_mode="fast" argument explicitly selects Kumo’s default run mode, which uses up to 1,000 examples from the graph as prediction context.

The printed result should contain one row per requested customer, with the customer ID in ENTITY and the predicted 30-day spend in PREDICTION. Confirm that every expected entity appears and that PREDICTION contains numeric values.

5. Add context filters carefully

Use WHERE to restrict the historical records that Kumo can use as context, not to choose which entities receive predictions. Current Kumo Relational static filters are limited to columns in the same table.

PREDICT SUM(orders.amount, 0, 30, days)
FOR customers.customer_id IN (101, 102, 103)
WHERE COUNT(orders.*, -90, 0, days) > 0

Compare the filtered and unfiltered results for the same entity set. If a query fails, remove the optional clauses and add them back one at a time.

6. Scale the entity list

After the query works for a few explicit IDs, use FOR EACH in PQL and pass a larger list of customer IDs through the indices parameter. The following example submits the first 1,000 IDs from an existing customer_ids collection:

with RelationalClient(url="http://localhost:8000") as client:
result = client.relational(graph).predict(
"PREDICT SUM(orders.amount, 0, 30, days) "
"FOR EACH customers.customer_id",
indices=customer_ids[:1000],
run_mode="fast",
)

Use Batch Prediction when the job exceeds the 1,000-ID request limit.

Review checklist

  • The entity column is a validated primary key.
  • The target table is connected to the entity table.
  • Temporal targets use the intended future window and unit.
  • Context filters do not include events after the anchor time, which would expose the prediction to future information.
  • The first request uses a small, known entity set.
  • Results are joined to downstream data by ENTITY, never by row position.

See Prediction Types and Filters and Operators.