This is a practice page for Counterfactual explanations (6.3.10) . The parent note built the idea (find the smallest change to the input that flips the model's answer) and the formulas . Here we do nothing but worked cases — one for every kind of situation the topic can throw at you, so that when you meet a new problem you have already seen its shape.
Everything below reuses one small notation. Let me pin every symbol down first so no line surprises you.
Definition The symbols we use on this whole page
x — the original input , a list of numbers (features). Written in bold because it is a vector, i.e. a point in space. Example: x = ( income , credit score ) .
x ′ — the counterfactual : a different point that we search for. The little dash just means "the changed version".
f — the model . Give it a point, it hands back either a class (0 or 1 ) or a probability p between 0 and 1 .
w , b — for a linear model, f decides using w ⊤ x + b . Here w is the direction the boundary cares about and b shifts it. w ⊤ x means "multiply matching components and add them up": w 1 x 1 + w 2 x 2 + …
∥ x ′ − x ∥ 1 — the L 1 distance : add up the absolute size of each feature's change, ∑ i ∣ x i ′ − x i ∣ . This is the "total edit" cost.
∥ x ′ − x ∥ 2 — the L 2 distance : ∑ i ( x i ′ − x i ) 2 , ordinary straight-line distance.
∥ w ∥ — the length of w , i.e. w 1 2 + w 2 2 + … .
A few reminders of tools the parent note defined, so this page stands on its own:
Recall Terse recaps of borrowed tools
sign ( z ) ::: returns + 1 if z > 0 , − 1 if z < 0 , and is undefined/ambiguous at z = 0 (right on the boundary).
σ ( z ) (the "sigmoid") ::: squashes any real number into ( 0 , 1 ) : σ ( z ) = 1 + e − z 1 , with σ ( 0 ) = 0.5 . Used to turn a raw score into a probability.
hinge loss max ( 0 , 0.5 − p ) ::: is 0 once the probability p has crossed 0.5 (success), and positive while p < 0.5 ; it "pushes" until we win, then stops.
λ (lambda) ::: a positive weight balancing the hinge term against the distance term — big λ = "cross the boundary at any cost", small λ = "stay close, even if you barely cross".
α (alpha) ::: the learning rate, the step size of each gradient descent move — small α = slow but safe, big α = fast but can overshoot.
If any of those felt fast, look at the parent note's derivation — this page assumes you have read it once.
Every counterfactual problem lives in one of these boxes. The examples below are labelled with the box they fill.
Cell
What makes it distinct
Example
A. Linear, one feature moves
closest-boundary formula, sign of the side
Ex 1
B. Linear, two features
projection along w , geometry
Ex 2
C. Feature costs / immutable feature
w i weights, w i = ∞
Ex 3
D. Degenerate: point already on the other side
zero change needed
Ex 4
E. Degenerate: w = 0 or point ON boundary
formula divides by zero / limit
Ex 5
F. L 1 vs L 2 give different answers
sparse vs spread change
Ex 6
G. Non-linear model, gradient walk
iterate, project, plausibility
Ex 7
H. Diversity (DiCE): two counterfactuals
"either/or" options
Ex 8
I. Real-world word problem
loan, units, actionability
Ex 9
J. Exam twist: which direction flips fastest?
gradient magnitude reasoning
Ex 10
We build up from the cleanest geometry (linear) so each formula is earned , then move to gradients and words.
Worked example Ex 1 — Cell A: linear, closest point on the boundary
A model scores loans with f ( x ) = sign ( w x + b ) , where w = 1 , b = − 50 , and the only feature is income (in k ) . H er e wan d xa r es in g l e n u mb er s ( o n e f e a t u r e = a sc a l a r , n o t a v ec t or ) . S o t h escor e i s \text{income} - 50: ∗ ∗ p os i t i v e → a pp r o v e d ∗ ∗ . A ppl i c an t ha s in co m e 45k , soscor e = -5 < 0$: denied . Find the smallest income change that flips the decision.
Forecast: guess the new income before reading. (Most people say "50 k".)
Write the boundary. w x + b = 0 ⇒ income − 50 = 0 ⇒ income = 50 .
Why this step? The boundary is exactly where the decision changes. The nearest flip is the nearest point on this line.
Apply the closest-boundary formula from the parent note (the scalar version, ∥ w ∥ 2 = w 2 ):
x ′ = x − w 2 w x + b w .
Here w x + b = 45 − 50 = − 5 , and w 2 = 1 2 = 1 .
x ′ = 45 − 1 − 5 ( 1 ) = 45 + 5 = 50.
Why this step? The fraction is "how far past the line we need to slide, measured in w -units". The minus sign flips because we are below the boundary and must move up .
State the recourse. Raise income from 45 k to 50 k (+ 5 k).
Verify: at income 50 , score = 50 − 50 = 0 : exactly on the boundary. Any nudge above flips it. The change ∣50 − 45∣ = 5 ; no smaller change reaches 50 . ✓ Forecast was right here because the boundary sits at 50 .
Intuition Why the formula has a
sign
w x + b is positive on one side of the boundary, negative on the other . Its sign tells you which way to walk. If our applicant already earned 60 k the same formula gives x ′ = 60 − ( 60 − 50 ) = 50 — walking down — but they were already approved, so we would not move at all (see Ex 4). The formula finds the boundary; you decide whether crossing it is needed.
Worked example Ex 2 — Cell B: two features, geometric projection
Now two features: x 1 = income, x 2 = savings (both in k ) , so t h e in p u t i s a v ec t or \mathbf{x}. M o d e l \mathbf{w}=(3,4), b=-350. A ppl i c an t \mathbf{x}=(50,25). A pp r o v e d w h e n \mathbf{w}^\top\mathbf{x}+b>0. F in d t h ec l oses t a pp r o v in g p o in t \mathbf{x}'$.
Forecast: will income and savings both change, and by how much each?
Compute the score. w ⊤ x + b = 3 ( 50 ) + 4 ( 25 ) − 350 = 150 + 100 − 350 = − 100 . Negative → denied.
Why this step? We must know the side and the distance-to-boundary, both packed in this one number.
Compute ∥ w ∥ 2 . 3 2 + 4 2 = 9 + 16 = 25 .
Why this step? The formula divides by it — it converts "score units" into "movement in feature space".
Move along w :
x ′ = x − 25 − 100 w = ( 50 , 25 ) + 4 ( 3 , 4 ) = ( 50 + 12 , 25 + 16 ) = ( 62 , 41 ) .
Why this step? The straight-line shortest path to a line is perpendicular to it, and w is the perpendicular direction. So we slide purely along w .
Read off the recourse. Income + 12 k, savings + 16 k.
Verify: score at x ′ : 3 ( 62 ) + 4 ( 41 ) − 350 = 186 + 164 − 350 = 0 : on the boundary. ✓ Straight-line distance moved: ∥ ( 12 , 16 ) ∥ 2 = 144 + 256 = 400 = 20 , and 20 = ∥ w ∥ ∣ − 100 ∣ = 5 100 . ✓ Both change because w points diagonally.
Look at the figure: the pink point is x , the dashed line is the boundary, the yellow arrow is the perpendicular hop along w , landing exactly on the line at x ′ .
Worked example Ex 3 — Cell C: feature costs and an immutable feature
Same model as Ex 2 (w = ( 3 , 4 ) , b = − 350 , x = ( 50 , 25 ) ), but now income is immutable (you cannot magically raise your salary this quarter). Only savings may change. Find the counterfactual under this constraint.
Forecast: the pure-geometry answer wanted + 12 k income — now that's forbidden, so savings must do all the work. More or less than 16 k?
Fix income. Set x 1 ′ = 50 (locked). This is the w i = ∞ cost from the parent note: infinite cost means "never touch it".
Why this step? An actionable recourse must only ask for changes the user can actually make.
Solve the boundary for the free feature. Need 3 ( 50 ) + 4 x 2 ′ − 350 = 0 ⇒ 150 + 4 x 2 ′ = 350 ⇒ x 2 ′ = 50 .
Why this step? With income pinned, the boundary equation has a single unknown — just solve it.
Recourse: savings from 25 to 50 (+ 25 k).
Verify: score = 3 ( 50 ) + 4 ( 50 ) − 350 = 150 + 200 − 350 = 0 : on the boundary. ✓ Note + 25 > 16 : constraining a feature always costs more total change — makes sense, we removed a cheaper option. This is the price of actionability .
Worked example Ex 4 — Cell D: point already on the desired side (zero change)
Model w = 1 , b = − 50 (income model from Ex 1). Applicant income = 70 k. Target = approved . Find the counterfactual.
Forecast: trick question?
Check current prediction. Score = 70 − 50 = 20 > 0 : already approved .
Why this step? Before optimising anything, ask whether the desired outcome already holds.
Return x ′ = x . No change needed; the L 1 distance is 0 .
Why this step? The counterfactual objective is a minimisation ; the minimum possible distance is zero, achieved when we are already correct.
Verify: f ( x ′ ) = f ( x ) = approved, and ∥ x ′ − x ∥ 1 = ∣70 − 70∣ = 0 . ✓ A valid counterfactual exists only relative to a target class different from the current one — always confirm the starting side.
Worked example Ex 5 — Cell E: degenerate model, the formula breaks
Two sub-cases where the tidy formula x ′ = x − ∥ w ∥ 2 w ⊤ x + b w needs care.
(a) w = 0 . Model w = ( 0 , 0 ) , b = 2 . Then w ⊤ x + b = 2 for every x : the model ignores the input entirely.
Forecast: can we flip it?
Try the formula. ∥ w ∥ 2 = 0 → division by zero. Undefined.
Why this step? Division by zero is the maths screaming "there is no direction to move".
Interpret. With w = 0 there is no decision boundary — the output is constant. No counterfactual exists at any distance.
Verify: score is 2 > 0 regardless; changing features never changes it. ✓ (Degenerate: report "no recourse possible; model is input-independent".)
(b) Point exactly on the boundary. w = 1 , b = − 50 , income = 50 k, so score = 0 .
The formula gives x ′ = x − 1 0 w = x : zero move.
Why this step? The nearest boundary point of a point on the boundary is itself.
But sign ( 0 ) is ambiguous — the class right at the line is undefined. Introduce a tiny positive number ε (read "epsilon", meaning "as small as you like but not zero", e.g. ε = 0.01 ). Nudge by ε in the + w direction to be safely approved: x ′ = 50 + ε .
Why this step? We need to leave the ambiguous line; any positive push does, and we take the smallest we trust the model at.
Read the table below. The needed change shrinks toward 0 as ε → 0 , but is never exactly 0 — the true minimum is an infimum (a greatest lower bound you approach but never reach).
ε
new income
score = x − 50
approved?
1
51
1
yes
0.1
50.1
0.1
yes
0.01
50.01
0.01
yes
→ 0
→ 50
→ 0 +
yes (never at 0 )
Verify: 50 + ε − 50 = ε > 0 for every ε > 0 ; the needed change tends to 0 but is never exactly 0 . ✓ Operational rule: pick the smallest ε at which you trust the model's output (a few cents of income), and report that as the recourse.
Worked example Ex 6 — Cell F:
L 1 vs L 2 disagree
Suppose two features are interchangeable for crossing the boundary: to flip, the sum x 1 ′ + x 2 ′ must rise by 10 from x = ( 0 , 0 ) (boundary x 1 + x 2 = 10 , i.e. w = ( 1 , 1 ) , b = − 10 ). Which point does L 1 pick? Which does L 2 pick?
Forecast: does the change get spread over both features or concentrated in one?
L 2 (smooth spread). Perpendicular hop along w = ( 1 , 1 ) : x ′ = ( 0 , 0 ) − 2 0 + 0 − 10 ( 1 , 1 ) = ( 5 , 5 ) . Both features change by 5 .
Why this step? L 2 measures straight-line distance; the shortest is perpendicular, splitting the move evenly along the diagonal w .
L 1 (sparse). Minimise ∣ x 1 ′ ∣ + ∣ x 2 ′ ∣ subject to x 1 ′ + x 2 ′ = 10 , both ≥ 0 . The sum ∣ x 1 ′ ∣ + ∣ x 2 ′ ∣ = 10 for any split — so L 1 is indifferent, and the tie is usually broken to a corner : change only one feature, e.g. ( 10 , 0 ) .
Why this step? L 1 's "diamond" contours touch the constraint line at a corner (single-feature) rather than the middle — this is why L 1 gives sparse recourse.
Compare costs. L 2 cost of ( 5 , 5 ) is 50 ≈ 7.07 ; L 2 cost of ( 10 , 0 ) is 10 . So L 2 prefers ( 5 , 5 ) . L 1 cost of both is 10 ; L 1 is happy with the sparse corner.
Verify: ( 5 , 5 ) : 5 + 5 = 10 ✓ on boundary. ( 10 , 0 ) : 10 + 0 = 10 ✓ on boundary. L 2 favours the spread point (7.07 < 10 ); L 1 favours changing one feature. ✓ Rule of thumb: tabular data → L 1 (fewer things to change is more actionable); images → L 2 (smooth, no salt-and-pepper). Same lesson used to attack models in Adversarial Examples .
Look at the figure: the yellow dot is the start ( 0 , 0 ) ; the pink diamond is the L 1 unit shape and it kisses the dashed boundary at the corner ( 10 , 0 ) (sparse, one feature); the blue circle is the L 2 shape and it kisses the boundary at its middle ( 5 , 5 ) (spread, both features). The picture is the reason L 1 gives sparse recourse: a diamond touches a line at a corner, a circle touches it face-on.
Worked example Ex 7 — Cell G: non-linear model, gradient walk
A model outputs probability p = f ( x ) = σ ( g ( x )) where the boundary is a curve . We cannot solve it in closed form, so we walk using the parent note's update. Take a 1-D toy: g ( x ) = x 2 − 4 , p = σ ( g ( x )) (recall from the recap box: σ squashes any number into ( 0 , 1 ) , σ ( 0 ) = 0.5 ). Start at x = 1 where g = − 3 , so p = σ ( − 3 ) ≈ 0.047 : class 0 . Target class 1 (need p > 0.5 , i.e. g > 0 ).
Forecast: which way will x move — up or down — and where does it stop?
Pick the loss. L ( x ) = ∣ x − 1∣ + λ max ( 0 , 0.5 − p ) , where λ > 0 (recap box) trades off "cross the boundary" against "stay close". A moderate λ (say λ = 5 ) crosses without wandering far.
Why this step? The hinge term is 0 once we succeed, so optimisation stops rewarding movement past the boundary — recourse stays minimal.
Find the target region. g ( x ) = x 2 − 4 > 0 ⇒ x > 2 or x < − 2 . The nearest to x = 1 is x = 2 (distance 1 ), not x = − 2 (distance 3 ).
Why this step? Non-linear boundaries can have multiple crossing points; gradient descent will slide toward the near one because that lowers ∣ x − 1∣ fastest.
Iterate with x ← x − α L ′ ( x ) , where α is the learning rate (recap box), a small step size like α = 0.1 . Near x = 1 the hinge gradient drives x upward (raising x raises g there), so x climbs 1 → 1.5 → 1.9 → 2. 0 + .
Why this step? Each step nudges downhill on L ; after each we project onto any constraints (here none).
Stop and read the recourse: move x from 1 to just above 2 , a change of ≈ 1 .
Why this step? The moment p first exceeds 0.5 , the hinge term hits 0 ; the only term left is ∣ x − 1∣ , whose gradient now pulls back toward x = 1 . The two forces balance exactly at the boundary, so the walk halts right at the nearest crossing — that balance is precisely what makes the change minimal. Pushing further would only increase ∣ x − 1∣ for no gain.
Verify: at x = 2 , g = 2 2 − 4 = 0 , p = σ ( 0 ) = 0.5 exactly — the boundary. At x = 2.1 , g = 0.41 > 0 , p ≈ 0.60 > 0.5 ✓ approved. Nearest crossing distance = ∣2 − 1∣ = 1 < ∣ − 2 − 1∣ = 3 ✓ (the walk correctly avoids the far root). This "walk to the boundary" is exactly how we probe a model in Model Debugging .
Worked example Ex 8 — Cell H: DiCE, two diverse counterfactuals
Boundary x 1 + x 2 = 10 from Ex 6, start x = ( 0 , 0 ) . A user wants two options , not one. DiCE adds a term − γ ∥ x 1 ′ − x 2 ′ ∥ 1 (with γ > 0 a weight, like λ ) that rewards the two counterfactuals being far apart. Propose a valid pair.
Forecast: what makes two counterfactuals genuinely different "advice"?
First counterfactual — change only feature 1. x 1 ′ = ( 10 , 0 ) . Valid: 10 + 0 = 10 .
Why this step? Sparse single-feature recourse (from Ex 6) is one natural option.
Second — change only feature 2. x 2 ′ = ( 0 , 10 ) . Valid: 0 + 10 = 10 .
Why this step? The diversity term wants these far apart; ( 10 , 0 ) vs ( 0 , 10 ) maximises L 1 separation among single-feature options.
Check diversity. ∥ x 1 ′ − x 2 ′ ∥ 1 = ∣10 − 0∣ + ∣0 − 10∣ = 20 — large, so the reward term is happy.
Verify: both on boundary (10 = 10 ) ✓; separation = 20 ✓. Recourse text: "Either raise feature 1 by 10, or raise feature 2 by 10." Giving alternatives is the whole point of diversity — a user blocked on one path can take the other.
Worked example Ex 9 — Cell I: real-world word problem, units & actionability
A bank model (linear) uses income I (thousands of $/year) and debt-to-income ratio r (unitless, 0 –1 ). w = ( 2 , − 100 ) , b = − 40 . Approve when score > 0 . Applicant: I = 40 , r = 0.5 . r can only decrease (pay off debt) and income can only increase . Find an actionable recourse.
Forecast: which lever is cheaper in real units — earn more, or cut debt?
Current score. 2 ( 40 ) − 100 ( 0.5 ) − 40 = 80 − 50 − 40 = − 10 . Denied.
Why this step? Establish the gap to close: 10 score-points.
Option via income (raise I ). Need 2Δ I = 10 ⇒ Δ I = 5 . New I = 45 k.
Why this step? Holding r fixed, one unit of income buys 2 score-points, so close the 10 -point gap with + 5 k. Allowed (income increases). ✓
Option via debt (lower r ). Need − 100 Δ r = 10 ⇒ Δ r = − 0.1 . New r = 0.4 .
Why this step? One point of ratio buys 100 score-points, so a tiny 0.1 cut suffices. Allowed (ratio decreases). ✓
Reject illegal directions. Increasing r or decreasing I would also be "solutions" to the raw maths but violate the causal direction — forbid them, à la Causal Inference and FACE constraints.
Verify: income path score: 2 ( 45 ) − 100 ( 0.5 ) − 40 = 90 − 50 − 40 = 0 ✓ boundary. Debt path score: 2 ( 40 ) − 100 ( 0.4 ) − 40 = 80 − 40 − 40 = 0 ✓ boundary. Both minimal in their own feature. Present both as valid recourse; a human picks the achievable one.
Worked example Ex 10 — Cell J: exam twist, which feature flips fastest?
Linear model w = ( 1 , 5 , 2 ) over three features, all currently equally far from their limits. Without computing a full counterfactual: which single feature, changed alone, reaches the boundary with the smallest change?
Forecast: the one with the biggest weight, or the smallest?
Change feature i alone. Score changes by w i Δ x i . To close a fixed gap G : Δ x i = G / w i .
Why this step? This is the sensitivity — how much score you buy per unit of change is exactly w i .
Compare Δ x i . Δ x 1 = G /1 , Δ x 2 = G /5 , Δ x 3 = G /2 . Smallest change is feature 2 (largest ∣ w i ∣ ).
Why this step? Bigger weight → each unit moves the score more → fewer units needed.
Conclusion. The feature with the largest ∣ w i ∣ flips the prediction with the least change; that's the direction gradient descent (Ex 7) grabs first — exactly the parent's remark that "income had the largest gradient, so it changed first".
Verify: for G = 10 : Δ x 1 = 10 , Δ x 2 = 2 , Δ x 3 = 5 . Minimum is Δ x 2 = 2 ✓. General rule: single-feature L 1 cost is G /∣ w i ∣ , minimised at arg max i ∣ w i ∣ ✓.
Recall Quick self-test
Ex 1 flips loan by moving income from 45 to ::: 50 k.
In Ex 2 the recourse was income + 12 k, savings ::: + 16 k, total L 2 distance 20 .
Why does locking income in Ex 3 raise the total change to + 25 k savings? ::: removing a cheaper lever forces the remaining feature to do all the work.
When does no counterfactual exist (Ex 5a)? ::: when w = 0 , the model ignores the input, so no change flips it.
L 1 vs L 2 on the diagonal (Ex 6): L 1 picks ::: a sparse corner like ( 10 , 0 ) ; L 2 picks the spread point ( 5 , 5 ) .
Feature that flips fastest (Ex 10) has the ::: largest weight magnitude ∣ w i ∣ .
Mnemonic Before you optimise, run
S-C-A-P
S ide (which side of the boundary am I on?) · C onstraints (immutable / one-directional features) · A ctionable (can the user do this?) · P lausible (does x ′ look like real data?).