Your first model
Start with one payment and one outcome: will this payment receive a dispute within the next 30 days? A risk team needs this estimate while the payment is still being processed, so it can decide which payments deserve review. Historical outcomes teach the model; new payments supply only the evidence available at that decision.
Begin with the relationship between amount, merchant, and the later outcome across past payments. This first model has no account history. The next tutorial puts this payment and its predecessors in one transaction branch, with a dispute target on every item.
You need Python 3.11 or newer. Install relflow in your project:
uv add relflowDescribe one payment
Each training record contains the information available at payment time and the outcome observed later:
amount: 84.50
merchant: North Market
disputed: falseDefine the fields
import relflow as rf
model = rf.Model.xs(
amount=rf.Number,
merchant=rf.Category,
disputed=rf.Boolean(mask=True),
)Number represents the amount, Category represents the merchant, and Boolean represents the yes-or-no outcome. mask=True marks disputed as a prediction target: the model learns from its value without seeing it as an input. Model.xs supplies a small model configuration.
Train the model
Use your application’s Parquet files, with one payment per row and the three columns above. Train on earlier payments and validate on a later period; both splits include the observed disputed labels.
data = rf.ArrowDataModule(
train="payments/train.parquet",
validate="payments/validation.parquet",
)
model.fit(data, batch_size=128, max_epochs=20)batch_size=128 sets the number of payments per training batch on each device. relflow configures the training loop, stops early when validation loss stops improving, and restores the best validation checkpoint.
Predict new payments
The request file contains amount and merchant. It omits disputed, because that is the outcome you want to predict.
requests = rf.ArrowDataModule(
predict="payments/requests.parquet",
)
predictions = model.predict(datamodule=requests, batch_size=256, devices=1)devices=1 collects the predictions on one device. predictions is an Arrow table with the target under predictions.disputed; Read predictions shows the full record and how to extract each probability.
Next, add transaction history to move the payment fields into trxns and score each transaction using the shared account context.