Do the related cases support this action? (support)¶
Your model flags a card payment as clean, but the card belongs to an
account inside a ring of sixteen accounts sharing eight phones, and
thirteen of those accounts were confirmed as fraud. The related cases
are strong evidence, and they say "fraud". Passing the payment
automatically because the evidence is strong would be a mistake: it
is strong evidence against the action. This check holds a decision
when the related cases do not point the same way as the proposed action.
This page is for domain owners who decide when the related cases should
overrule the model, and for data scientists who build the evidence. It
assumes you know that each decision comes with evidence about the
related cases (see The six checks). The name of this check
in decision records is support.
The question¶
Of the related cases, what share carry the outcome this action implies, and is that share at least one half?
The other evidence checks ask whether the related cases are worth listening to: neighbour agreement asks whether linked cases agree with each other, the knife-edge check asks whether the link density is too close to your cut-off, and the unusual-cases check asks whether the score looks familiar. None of them asks which outcome the related cases point to. This check does.
The intuition: count the votes for this action¶
Every proposed action implies an outcome for the related cases. In
fraud review, block implies "confirmed fraud" and pass implies
"cleared". You tell the library which label the proposed action implies;
it counts the related cases carrying that label.
Dense ring, 16 accounts: F F F F F F F F F F F F F C C C (F = confirmed fraud, C = cleared)
proposed block -> needs F -> 13 of 16 = 0.81 -> at least 0.50, pass
proposed pass -> needs C -> 3 of 16 = 0.19 -> below 0.50, hold
The same evidence passes one action and holds the other. That is the point: the check is about direction, not strength.
Worked example¶
Three card authorisations. The first and third carry the same dense ring of 16 accounts, 13 of them confirmed fraud. The second is linked to four accounts through a chain of shared laptops, two of them confirmed fraud.
| Row | Event | Proposed action | Implied label | Support share | Support check | Verdict |
|---|---|---|---|---|---|---|
| 0 | suspicious |
block |
confirmed fraud | 13/16 = 0.8125 | pass | act block |
| 1 | suspicious |
block |
confirmed fraud | 2/4 = 0.5 | pass | hold (neighbour agreement and knife-edge fail) |
| 2 | clean |
pass |
cleared | 3/16 = 0.1875 | fail | hold |
Row 2 is the case from the opening. Every other check passes; only this one fails:
tick 2/3 event=clean
why $12 grocery purchase on a card in the same ring - the model says clean, the related accounts say fraud: held for review
...
support share=0.1875 vs min=0.50 does not support the proposed action
...
DECISION
hold — failed: support
certificate PASS can we compile this policy (star-height ≤ 3)?
game PASS can the policy keep making progress (parity win, nonnegative mean)?
reconstruction PASS do noisy neighbors recover the seed (dλ² > 1+margin)?
threshold PASS is density outside the operational flicker window?
conformal PASS is this candidate weirder than the calibration bag?
support FAIL do the related cases support the proposed action?
support 0.19 vs minimum 0.50 (does not support the proposed action)
→ ABSTAIN because conjunction failed on support; proposed 'pass' is blocked; naive would have fired 'block-or-pass'
The proposal pass stays on the record, so a reviewer sees that the
model said clean and the related accounts said fraud.
Row 1 shows the boundary: a share of exactly 0.5 passes, because the rule is "at least the minimum". That row is held anyway, by the checks that judge whether four accounts are enough to say anything.
The example measures support by passing the implied label when it builds the evidence:
from grounded_decision.examples.fraud_review import (
SUPPORTING_LABEL, # {"block": CONFIRMED_FRAUD, "pass": CLEARED}
device_graph_evidence,
)
evidence = device_graph_evidence(
device_logins,
last_review_outcome,
candidate_model_score=model_score_for_this_auth,
supporting_label=SUPPORTING_LABEL[proposed_action],
)
device_graph_evidence calls snapshot_from_graph(...,
supporting_label=...), which sets EvidenceSnapshot.support. If you
build the evidence yourself, set support directly.
The exact rule¶
With \(\ell\) = the label the proposed action implies, \(\ell_v\) = the
label of related case \(v\), \(n\) = the number of related cases and
\(m\) = Limits.min_support (default 0.5):
snapshot_from_graph computes the share over every vertex of the
graph, linked or not; an empty graph gives 0. When support is None
(you did not measure it), the check passes, unless
Limits.require_support is True, in which case it fails with
support not measured (require_support).
The record's support entry:
| Field | Meaning |
|---|---|
metrics.support |
the share (present only when measured; also health.support) |
metrics.min_support |
\(m\) |
metrics.require_support |
the require_support setting |
metrics.measured |
true when support was supplied |
trust |
always operational |
It is a practical rule with an explicit constant, not a result from the
math catalog, so its trust level is always operational (practical).
What it does not tell you¶
- It is off unless you measure it. Every shipped example except
fraud_reviewandclinical_triageleavessupportunmeasured, and the check passes withsupport not measured. SetLimits(require_support=True)once every decision carries it. - It does not know which label your action implies. The mapping
from action to label (
SUPPORTING_LABELin the examples) is yours. A wrong mapping makes the check hold exactly the decisions it should pass. - It counts, it does not weigh. Every related case counts once, however weakly linked. Whether the related cases are informative at all is the job of neighbour agreement and the knife-edge check; a 2-of-4 share passes here and is held there.
- One half is a starting point, not a result. No theorem says 0.5 is right for your data. Learn it from your history (below).
- A pass does not say the action is correct. It says most related cases carry the outcome the action implies. Your error rate is what learning with a certificate measures.
What to do when it fails¶
The reason reads like
support 0.19 vs minimum 0.50 (does not support the proposed action).
- One case held: your model and the related cases disagree. Route it to a person; that disagreement is what a reviewer is for.
- Many cases held: check the action-to-label mapping first, then whether the related cases are the right population (a graph that mixes unrelated accounts dilutes the share).
- Choose the minimum from your history:
Learn parameters from your history
tries minimums 0 (check off), 0.5, 0.6, 0.7, 0.8 and 0.9 alongside
the other settings and keeps the combination that acts most while
meeting your error target. The learned value becomes
Limits.min_support.
Where next¶
- All six checks side by side: The six checks.
- Building the evidence, including the support share: Build evidence from your data.
- The worked case in fraud terms: Fraud review.
- Terms: Glossary.