Profile context and a second outcome

Extend the transaction model with payment channels, account profile context, and a merchant-repeat target.

The transaction-history model reads an ordered sequence to predict a later dispute for each transaction. Now a payment service also wants to anticipate repeat payments. Add the evidence that question needs: how each payment was made and how long the account has been open. Then add a second outcome to the same observation.

This is a richer transaction model, built after the basic training and evaluation workflow. Keep the earlier model as a baseline so you can test what each addition contributes.

Keep events and account context together

Consider a direct debit to an internet provider. Keep that latest payment once, at the end of trxns, alongside the earlier transactions known at the decision time. Repeated amounts and booking days supply evidence of a recurring pattern:

account_age_days: 420
trxns:
  - booked_at: "2026-03-28T09:00:00"
    amount: 24.00
    merchant: Harbor Internet
    channel: direct_debit
    disputed: false
    repeats_next_30_days: true
  - booked_at: "2026-04-28T09:00:00"
    amount: 24.00
    merchant: Harbor Internet
    channel: direct_debit
    disputed: false
    repeats_next_30_days: true
  - booked_at: "2026-05-27T08:00:00"
    amount: 32.00
    merchant: Station Cafe
    channel: card
    disputed: true
    repeats_next_30_days: false
  - booked_at: "2026-05-28T09:00:00"
    amount: 24.00
    merchant: Harbor Internet
    channel: direct_debit
    disputed: false
    repeats_next_30_days: true

The transaction list is the event history, including the payment being scored. Each event keeps its amount, merchant, channel, and booking date together. account_age_days supplies profile context shared by the sequence. Use its value as known at the decision time.

Evidence What it contributes
Amount, merchant, and channel within one event Distinguishes a direct debit from a card purchase, even at the same merchant.
Ordered transactions and booking dates Exposes repeated amounts, merchant visits, and calendar patterns.
Account profile Supplies context shared by the transaction sequence, such as account tenure.

A calculated mean payment amount or dominant channel is another possible input. Compare those summaries with the event sequence to learn whether preserving individual transactions is useful.

The record follows Prepare observations: sorted oldest to newest, ending at the latest payment, with a cutoff at that final booking on May 28 at 09:00. disputed records whether a new dispute against the transaction was reported in the 30 days after the cutoff, and repeats_next_30_days records whether another payment to that transaction’s merchant occurred in the same window. Every transaction’s predictions use the complete sequence known at the common cutoff.

Learn two outcomes from the same history

Place both targets inside trxns, beside the transaction they describe. mask=True hides each transaction’s answers and supplies their supervision. The two predictions share encoded context, with their own decoders and supervision. This lets the application test a joint model against separate models for the two decisions:

import relflow as rf

model = rf.Model.xs(
    account_age_days=rf.Number,
    trxns=rf.Branch(
        length=32,
        overflow="tail",
        booked_at=rf.DateParts(
            dateparts=["day_of_month", "day_of_week", "hour_of_day"],
        ),
        amount=rf.Number,
        merchant=rf.Category,
        channel=rf.Enum(values=("card", "direct_debit", "bank_transfer")),
        disputed=rf.Boolean(mask=True),
        repeats_next_30_days=rf.Boolean(mask=True),
    ),
)
data = rf.ArrowDataModule(
    train="payments/context/train.parquet",
    validate="payments/context/validation.parquet",
)
model.fit(data, batch_size=128, max_epochs=30)

An account root contains account_age_days Number and one repeated trxns branch. Each transaction has booked_at DateParts, amount Number, merchant Category, channel Enum, and two Boolean targets, disputed and repeats_next_30_days, each hidden and supervised at every transaction.

An account root contains account_age_days Number and one repeated trxns branch. Each transaction has booked_at DateParts, amount Number, merchant Category, channel Enum, and two Boolean targets, disputed and repeats_next_30_days, each hidden and supervised at every transaction.

Figure 1: Profile context sits at the root. Every transaction carries its own evidence and two hidden targets that share the same context.

These application-supplied Parquet files keep profile context at the root and all transaction fields inside trxns. Every listed transaction supplies both Boolean labels. Their schema addresses are /trxns/disputed and /trxns/repeats_next_30_days.

Prediction files omit both outcome fields from every transaction while keeping the transaction records. The results arrive inside predictions.trxns, with inferred: true for both targets at every retained transaction position. See Read predictions.

Shared context lets you test whether learning the account’s behavior helps both tasks. Inspect each outcome separately: improvement on repeat payments can accompany a regression in dispute detection. For repeat payments, measure precision and recall for another payment to each transaction’s merchant within the common 30-day window. For disputes, measure recall at the team’s review capacity. A dispute label records a later customer outcome and needs its own operational definition.

Choose a learning workflow

With settled outcome labels, train the supervised model directly. When you have many more histories than labels, first hide sampled transaction amounts or merchants and learn to reconstruct them from the remaining context. That gives unlabeled activity a learning role before adapting the model to dispute or repeat-payment prediction.

Reconstructing a hidden transaction value asks what fits the observed sequence. Predicting a later outcome asks what happens after the decision. Define and evaluate those objectives separately. The pretraining guide shows how to change objectives while reusing compatible learned state.

You can also export a contextual representation: learned vectors combining the account fields and its history. Keep the encoder fixed while training separate task predictors on those vectors. This tests whether the learned context is useful for another outcome before updating the encoder for it. Reusable representations explains that workflow.

Make the comparison about the decision

For repeat payments, compare with rules based on merchant, amount, and the booking calendar. For disputes, compare with the existing tabular model and its history features. Keep the eligible payments, available evidence, and outcome windows identical.

Test each addition in sequence: history versus the payment alone, channel and profile versus history alone, then joint targets versus separate models. Later, compare reconstruction pretraining with the same supervised model trained from scratch. Evaluation explains these comparisons.

Next, Nested context and account outcomes nests line items inside transactions, adds a separate withdrawal history, and combines transaction dispute targets with an account-level loss target.