No dates needed
A database with no time columns works. There are no
anchor_times,
observed_through or anchor_time to choose.Linked tables count
Features follow foreign keys, such as each account’s transactions and its
branch, the same way they do for forecasts.
No leaks
The target column is removed before features are built, so no feature can
read any row’s value, directly or through another table.
Numbers and 0/1 flags
A numeric column is regression. For a 0/1 column, such as a loan flag, you
get the probability of a 1.
Static predictions need
nori-rel 0.4.6 or later; see
Installation. Local mode runs Nori in your process,
with no API key. The outputs on this page come from a synthetic bank: 1,000
accounts, 7,046 transactions, no date columns, and 20% of the balances set to
NULL.Quickstart
Connect without registering any time columns, then name the column to predict and the table it belongs to:anchor_time is the time of the read.
How it works
A static target is a column of theFOR EACH table, with no time window.
Nori-Rel reads every table once and splits the rows of that table in two:
- Examples are the rows whose value is known (not NULL, and not NaN) and
that pass the query’s
WHERE. The rows being scored are never examples, even when their value is known.max_context_rows(default 5,000) counts only these rows. Above it, Nori-Rel keeps the lowest primary keys, often the oldest rows, or the newest rows when you passentity_created_at. To sample the whole table instead, see Choose the examples. - Scored rows are the ones
FORnames.FOR EACHmeans every row whose value is NULL or NaN;FOR accounts.account_id IN (3, 8)means those rows, known value or not.query_filter=narrows them further.
Check predictions against known values
Name rows whose value is known. They are scored and left out of the examples, so you can compare each prediction with the real value without the model having seen it:0/1 targets
A column of 0s and 1s, such as a loan flag, can be predicted as the probability of a 1. Its values alone don’t say whether you want a number or a probability, so Nori-Rel asks. It checks every stored value, not only the examples:task="regression" with output_type="mean". The mean of a 0/1 label is
the probability of a 1:
Values fixed when the row was created
Leaveentity_created_at out when the value is the row’s current state, such
as a balance. Pass it when the value describes the row at the moment it was
created, such as fraud on a transaction. Each row’s features then stop at that
row’s own time:
anchor_time is each row’s own
time.
Choose the examples
By default every row with a known value is an example, up tomax_context_rows (default 5,000), taken by lowest primary key. Pass
context=ContextPolicy(...) to choose them another way. Every setup below ran
on the synthetic bank; each score is the mean absolute error on the 200 hidden
balances:
Use every row when it fits. Below, each setup is one call.
A random sample when you cap the rows (recommended)
On a large table the lowest keys are usually the oldest rows. A random sample covers the whole table instead, and the sameseed keeps the same rows on
every run:
context replaces max_context_rows; passing both raises an error.
Narrow the examples with your own SQL
candidate_sql keeps only the examples your SELECT returns, for filters the
query’s WHERE can’t express, such as a join. It reads
candidates(entity_id, anchor_time), the rows Nori-Rel would use, and can only
narrow them:
WHERE in the query is simpler, for example
... FOR EACH accounts.account_id WHERE accounts.branch_id = 1.
Balance a 0/1 label
ClassBalance keeps every positive and a set number of negatives per
positive, so a rare label isn’t drowned out. Nori-Rel then maps the predicted
probabilities back to the population’s rate. With local regression on a 0/1
column, use output_type="mean":
See which rows were kept
details.metadata["context_policy"] reports the setup every prediction used,
with or without a policy: the policy itself, the label counts before and after
selection (labelled_label_counts, kept_label_counts), and, for a 0/1 label,
the population and sample positive rates and any correction applied.
Configuration
Arguments for a static target
Arguments for a static target
Good to know
- Nori-Rel removes only the target column. A column that copies or encodes it,
such as a
balance_band, would still leak it: connect a view without it. "noridfs"andAgenticSearchsize their features to a window of future events, which a static target doesn’t have, so they raise an error here.- A static prediction makes no reusable pipeline:
details.pipelineisNone. - Backtests at a past date aren’t supported yet. They need to know when each value was recorded, which the database doesn’t track.
- To score every known row at once, as in leave-one-out, name the rows in
batches with
FOR ... IN (...); there is no single call for it yet.
Next steps
Relational data
Forecast what happens next from linked tables, with past dates as examples.
Explainability
SHAP values, interactions, and partial dependence.