A rejected loan applicant asks a reasonable question: “What would have to be different for this model to approve me?” A recourse method answers with changes intended to flip the model's decision. The answer is useful only if its arithmetic is faithful and the person can actually make the changes.
Luzio's paper finds a remarkably clean way to satisfy the first condition for gradient- boosted trees. It also shows how badly standard evaluation misses the second. One worked recommendation asks an applicant to make an account three years older—correct model arithmetic attached to an impossible action.
Every tree contributes one coordinate
A boosted ensemble sends an instance down each of M trees and sums the reached leaf values. Instead of treating those values as temporary results, place them in a vector φ(x). The model score is then simply the sum of φ's coordinates. The model remains nonlinear in input features, but it is linear in this leaf-value space.
def leaf_vector(forest, features):
coordinates = []
for tree in forest:
node = tree
while node["kind"] == "split":
value = features[node["feature"]]
node = node["left"] if value <= node["threshold"] else node["right"]
coordinates.append(node["value"])
return coordinates
def score(forest, features, bias=0.0):
return bias + sum(leaf_vector(forest, features))Two people who reach the same leaf in a tree have the same coordinate there. Their difference is therefore exactly zero for that tree. Only trees where their paths diverge can carry the score gap.
Explanation becomes subtraction
Choose an accepted comparator and subtract the rejected query's leaf vector from it. Every nonzero coordinate is a signed, model-native contribution. Sum the coordinates and the result must equal comparator score minus query score.
def contrast(query_coordinates, comparator_coordinates):
deltas = []
for query, comparator in zip(query_coordinates, comparator_coordinates):
deltas.append(comparator - query)
return deltas, sum(deltas)Our tested four-tree example scores the query at -1.55 and the comparator at 2.15. The leaf-coordinate explanation sums to 3.70, exactly matching their 3.70-point gap.
Trees are coordinates; features are an accounting choice
A person cannot act on “tree 87.” COACH assigns each diverging tree to the first split where the query and comparator take different branches, then sums trees assigned to the same feature. Those rows still partition the exact gap. But the paper is careful about what this does not mean.
Retrieval turns explanation into recourse
COACH retrieves an existing training instance that the model accepts, rather than optimizing a synthetic point. It prefers comparators that share leaves, concentrate the score gap in fewer trees, and remain close in standardized feature space. This grounds the target in a real profile, but the ranking is not the main source of validity.
Replacing the ranking with an arbitrary eligible comparator leaves validity at least 0.965, versus at least 0.967 with ranking. Copying the decisive values tends to land near an already accepted instance. Eligibility does the heavy lifting; the heuristic mainly narrows the recommendation.
The standard metric approves impossible advice
| Feasible changes only | FICO HELOC | Taiwan Credit | Adult Income |
|---|---|---|---|
| COACH constraint-aware | 0.648 | 0.315 | 0.752 |
| COACH filtered | 0.547 | 0.087 | 0.708 |
| NICE filtered | 0.372 | 0.115 | 0.74 |
| FACE filtered | 0.343 | 0.187 | 0.767 |
| Feature Tweaking | 0.208 | 0.09 | 0.893 |
On HELOC, constraint-aware COACH retains 67.0% of its unconstrained validity. Filtered NICE retains only 38.0%. Sparse advice has no slack: if one of two recommended changes is impossible, most of the plan disappears. The broader method looks worse under conventional sparsity metrics yet degrades more gracefully.
What to verify before deployment
- Reconstruct every reported margin gap from the exported explanation table.
- Separate contrastive accounting from one-feature intervention effects.
- Define mutability and permitted directions before evaluating recourse.
- Report constrained validity, not only whether the model accepts an edited row.
- Show effort and realism separately instead of hiding their tradeoff in one score.
The mutability labels are judgments, not facts in the dataset, and COACH's constrained validity is still only 0.572 on average—explicitly not deployment-ready. Explore the model family on the XGBoost, LightGBM, and decision-tree pages.
References
- Emanuele Luzio (2026). Leaf Values as Coordinates: Exact Contrastive Explanation for Gradient-Boosted Ensembles. arXiv preprint, cs.LG
- Tianqi Chen, Carlos Guestrin (2016). XGBoost: A Scalable Tree Boosting System. Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining