Explainable recommendation
A ranker that returns the right item but cannot say why is a black box your users distrust, your engineers cannot debug, and your regulators will not accept. The trick is to keep two questions apart — "is the model transparent?" and "can we attach an honest reason to this card?" — and to remember that an explanation is a claim about the model that most cheap methods fail to keep.
Why an explanation earns its latency
Explanations are not free — they cost compute, screen space, engineering time, and they can leak private signal (lesson 22 · Privacy). So before any method, name who the explanation is for, because the audience decides what "good" means. There are four, and they pull in different directions.
| Audience | Why they need it | What "good" means |
|---|---|---|
| User — trust & persuasion | "Because you watched X" lowers the friction of accepting an unfamiliar item; trust converts to clicks. Industrial A/B tests routinely report +5–8% CTR on cards that carry a reason, with measurable lifts in dwell and retention. | One short, true, human sentence — a watched item, a followed creator, a topic tag. |
| Developer — debugging | When the feed suddenly serves clickbait, an attribution tells you which feature drove it — a distribution shift, a leaked label, a runaway popularity prior. | A ranked per-prediction feature breakdown, comparable across model versions. |
| Regulator — compliance | Algorithm-transparency law (China's algorithmic-recommendation rules, the EU's DSA and GDPR "right to explanation") increasingly requires a stated logic plus an opt-out of personalization. | A reproducible, auditable account of the decision logic — defensible, not necessarily user-facing. |
| Auditor — fairness | To check whether a protected attribute or its proxy is driving exposure, you must attribute the score to features. Explainability is the instrument fairness work reads from (lesson 20 · Fairness). | Global attributions across slices, stable enough to compare groups. |
The interviewer who asks "why would you add explanations?" wants to hear that these are four jobs, not one. A method that is fine for a recommendation card ("people who liked this also liked…") can be malpractice in a fairness audit.
The master axis: intrinsic vs post-hoc
Every method sits on one side of a single axis. Either the model is transparent by construction (intrinsic, glass-box — the model is the explanation), or it is a black box you explain after the fact (post-hoc — an opaque model plus a separate explainer).
The choice is a business decision, not an aesthetic one. Pick intrinsic when the decision is high-stakes or regulated, when you are in cold start (lesson 15 · Cold start) and a simple rule is all the data supports anyway, or when the audit requirement is hard. Pick post-hoc when you have already paid for a deep ranker (lesson 04 · Ranking models) and cannot give up its accuracy — you bolt an explainer on and accept that the explanation is an approximation.
Intrinsic methods — when the model is the reason
Linear models and decision trees
A logistic CTR model p = σ(w·x + b) is self-explaining: feature i's contribution to the logit is exactly wᵢ xᵢ, and sorting those gives a per-prediction breakdown that is literally the computation (lesson 04 · Ranking models traces why we left LR behind). A decision tree hands you a root-to-leaf rule — "watch-time > 30s AND topic = cooking → recommend." In a regulated slice or for a brand-new user with three data points, that honesty is worth more than a deep model's last point of AUC.
Attention weights as explanations — and the honest caveat
Behavior-sequence rankers like DIN/DIEN (lesson 13 · User-behavior sequences) attend over the user's history: each past item hⱼ gets a weight αⱼ = softmax( a(hⱼ, cand) ) measuring its relevance to the candidate. The natural story is "we recommend this because of the high-attention items," visualized as a heat-strip over the history. It is the most popular explanation in industry — and the most over-claimed.
Knowledge-graph path explanations
The most satisfying intrinsic explanations come from models that reason over a knowledge graph of entities and relations (users, items, attributes, creators, topics). The recommendation is a path, and the path is the explanation — fully transparent and naturally human-readable.
Path-based recommenders (RippleNet, KPRN, PGPR) score a candidate by the strength of the connecting paths and surface the strongest one as the reason — faithful and readable in one object. The cost: you must build and maintain the graph, paths explode combinatorially, and graph coverage becomes the new bottleneck. But for a cold-start item with no interaction history, a semantic path ("recommended because you follow a science creator") is often the only reason you can honestly give.
Post-hoc methods — explaining a black box
You kept the deep ranker for its accuracy; now attach an explainer. Every post-hoc method shares one trick: probe the model by perturbing inputs and watch the output move.
LIME — a local linear surrogate
To explain one prediction, LIME samples perturbed versions of that input, gets the black box's prediction on each, and fits a tiny linear model in the neighborhood, weighting samples by closeness to the original. The surrogate's coefficients are the local feature importances. Model-agnostic and intuitive, but only as stable as the sampling — re-run it and the top features can wobble.
SHAP — fair credit from game theory
SHAP assigns each feature its Shapley value: the feature's average marginal contribution to the prediction, taken over all orderings in which features could be "added." It is the unique attribution satisfying three sane axioms — efficiency (contributions sum to prediction minus baseline), symmetry, and a dummy/null property:
φᵢ = ΣS ⊆ F∖{i} ( |S|! · (|F|−|S|−1)! / |F|! ) · [ f(S ∪ {i}) − f(S) ] with f(x) = φ₀ + Σᵢ φᵢ
Read it as: feature i's credit φᵢ is its marginal lift f(S∪{i}) − f(S), averaged over every coalition S of the other features. The exact sum is exponential in the feature count, so in practice you approximate — KernelSHAP (a weighted LIME-style regression) or, for tree ensembles, the exact-and-fast TreeSHAP in O(TLD²). The payoff: contributions that add up to the score, which is exactly what a developer breakdown and a fairness slice both want.
| Feature | φᵢ (contribution to p) |
|---|---|
| baseline φ₀ | 0.50 |
| watched cooking before | +0.15 |
| trending now | +0.12 |
| geo = USA | +0.05 |
| no recent history | −0.10 |
| Σ → prediction | 0.72 |
geo = USA contributes +0.05 — small, but a fairness auditor (lesson 20) can now see that a location proxy is moving the score and aggregate that φ across protected slices to check for disparate exposure. The widget below lets you toggle these features and watch the sum re-balance live.
| Method | Type | Granularity | Faithful? | Cost / pitfall | Best for |
|---|---|---|---|---|---|
| Linear / logistic weights | intrinsic | global + local | exact | caps model capacity | regulated, cold start |
| Decision-tree path | intrinsic | local rule | exact | shallow trees underfit | rule-like decisions |
| Attention heat-map | intrinsic | local | not guaranteed | not causal; can be gamed | user-facing reasons |
| KG path | intrinsic | local | exact (path is the model) | graph build & coverage | cold start, semantic links |
| LIME | post-hoc | local | approximate | unstable across runs | any black box, quick look |
| SHAP | post-hoc | local + aggregable | approximate, axiomatic | expensive; baseline matters | debugging, fairness audit |
| Counterfactual | post-hoc | local | causal-by-construction | search cost; may be unrealistic | "what would change this?" |
| Template / "because you…" | presentation | local | depends on the bound signal | can be a fake reason | the actual UI card |
Attributing the objective, not just the feature — multi-task rankers
Everything above attributes a score to features. But a production ranker is almost never one head — it is a multi-task model (lesson 12 · Multi-task learning) that predicts watch-time, like, comment, share, and a diversity term in parallel, then fuses them score = Σk wk · ŷk. The question a developer actually asks when the feed tilts is not "which feature fired?" but "which objective drove this card?" — and SHAP over input features cannot answer it, because two features can both feed the watch-time head and the diversity head at once. You need a second attribution axis: credit assigned over the heads / experts.
Two mechanisms, depending on how the model fuses objectives:
- LRP (Layer-wise Relevance Propagation) onto the fusion layer. Treat the final score as the relevance budget and back-propagate it through the fusion weights to each task head, conserving total relevance at every layer (the same conservation idea as SHAP's efficiency axiom, but propagated through the net rather than sampled over coalitions). The output is a clean decomposition: "this rec is 80% watch-time, 20% diversity."
- Per-expert activation in PLE / MMoE. In a gated expert architecture the gate already emits, per objective, how strongly each expert fires. Log those gate weights at serving time and you can read off when the model favored retention over clicks for a given user slice — e.g. "for new users the watch-time experts carry 0.65 of the gate mass; for power users the interaction experts carry 0.58." No extra pass; the explanation is a tensor you already compute.
| Objective head k | head output ŷk | fusion weight wk | contribution wkŷk | share |
|---|---|---|---|---|
| watch-time | 0.80 | 1.0 | 0.80 | 57% |
| like | 0.50 | 0.6 | 0.30 | 21% |
| diversity term | 0.40 | 0.5 | 0.20 | 14% |
| comment | 0.25 | 0.4 | 0.10 | 7% |
| Σ → fused score | 1.40 | 100% |
Template and counterfactual explanations
Templates — the reason the user actually sees
Whatever runs under the hood, the card almost always renders through a template: "Because you watched X," "Popular with people you follow," "Trending in cooking." Templates are cheap, fast, and readable. The danger is the fake reason — filling the slot with a high-weight feature that wasn't the real driver, or a generic "popular near you" that has nothing to do with this prediction. A template is only as honest as the signal you bind into it, which is why you verify the binding with a counterfactual.
LLM-generated reasons — fluent, and a new way to lie
The emerging pattern (lesson 26 · LLMs & GenAI) replaces the rigid template slot with an LLM that writes the sentence: instead of "Because you watched X," it produces "Recommended because you saved 3 similar cooking tutorials this week and the creator is an expert you interact with often." More natural, more persuasive, higher click-through on the reason — and a fresh failure mode on top of the old one. A template can only show a fake reason (a real feature that wasn't the driver). An LLM can show a hallucinated reason: a fluent, plausible sentence describing behaviour that never happened ("because you love Italian cuisine" when the user has never touched a cooking video). The fluency is exactly what makes it dangerous — a hallucinated reason reads more trustworthy than a clumsy true one.
- Constrain the input. Do not free-generate. Feed the LLM only the actual top-k SHAP features (or the strongest KG path) for this prediction and instruct it to paraphrase those — never to invent context. The model's job is fluency, not retrieval.
- Verify the output. Parse the entities the LLM named back out of the sentence and check them against the grounded set. If the sentence claims "saved 3 cooking tutorials," confirm (a) the cooking signal is in the top SHAP features and (b) the counterfactual holds — remove it and the item drops out of the top-K. Any named entity not in the grounded set is a hallucination: block the card and fall back to a deterministic template.
Counterfactuals — the most causal explanation you can cheaply give
A counterfactual answers what users and auditors actually mean: what would have to be different for the recommendation to change? "If you hadn't watched any gaming videos this week, this item would drop out of your top 10." You find it by searching for the smallest input change that flips the outcome:
x* = arg minx' d(x, x') subject to rank(item | x') > K (item leaves the top-K)
Because it intervenes on the input and observes the output, a counterfactual is causal-by-construction — it sidesteps the "attention isn't causal" trap entirely. It is also the cleanest consistency check: if a card claims "because you watched cooking videos," remove the cooking videos and confirm the item really falls. If it doesn't, your stated reason was a lie. The cost is search (you may probe the model many times) and realism (the minimal change must be one the user could plausibly have made).
Evaluating explanations — because an unfaithful one is worse than none
Here is the dimension most candidates miss entirely. You can pick the right method, bind a beautiful template, and still ship a disaster — because you never measured whether the explanation works. The engineering line is sharp: an explanation is a claim about the model, and an unfaithful or useless claim is not neutral, it is negative. A wrong "because you watched X" actively erodes the trust the feature was supposed to build, teaches users to ignore reasons, and — if it leaks into a fairness narrative — hands a regulator a false account. So explanations get the same treatment as any other shipped surface: a metric suite, thresholds, and an A/B with causal attribution. The book devotes a whole section to this; the lesson would be incomplete without it.
Measure on three layers, because the four audiences (top of this lesson) need different evidence.
| Layer | Metric | What it asks | Target / threshold |
|---|---|---|---|
| System | Explanation coverage | % of served items that get any reason | high & rising; a long tail with no honest reason is a coverage gap, not a free pass to fabricate |
| generation latency | does the reason fit the budget? | card sub-ms; heavy attribution nearline (lesson 17) | |
| Model / faithfulness | attribution stability | do the SHAP top-features agree with themselves across time windows? (Spearman ρ of the rankings) | ρ > 0.7 — below this the explainer is unstable; same input, different "reason" tomorrow |
| fidelity–stability | does the explanation track the model under small input perturbation? | > 0.7 — an explanation that swings while the prediction holds is noise | |
| decision-path coverage | do the top-3 explained paths overlap the user's actual behaviour log? | ≥ 85% overlap — the reason should describe what really happened | |
| User / business | ESS — explanation satisfaction | "did this reason help you understand the rec?" (5-pt Likert survey) | tracked over time; watch the low-activity cohort, where trust matters most |
| adoption & ECR | do users engage the reason, and does it lift conversion? | adoption = CTR on explained items; ECR = the conversion lift from adding the reason at all |
| before | after | Δ (this group) | |
|---|---|---|---|
| treatment — CTR on explained items | 4.0% | 4.6% | +0.6 pp |
| control — CTR, no reason shown | 4.0% | 4.2% | +0.2 pp |
ECRcausal = ΔCTRtreat − ΔCTRcontrol = (+0.6 pp) − (+0.2 pp) = +0.4 pp
Now the obvious next question — when the experiment shows watch-time down but share-rate up (a real and common outcome), the verdict is not a single number. You build a weighted decision score across the objectives and decide explicitly, exactly the multi-objective reasoning of lesson 08 · Evaluation; the explanation framework feeds that decision, it does not bypass it.
The accuracy–explainability tradeoff (and why it's overstated)
The folk theorem: simple models are explainable but weak, powerful models are accurate but opaque, so you must trade one for the other. There is a kernel of truth — a 3-deep tree genuinely cannot match a DCN-v2 cross stack on a billion-event dataset. But the tradeoff is routinely overstated, for three reasons:
- Post-hoc breaks the dilemma. You keep the accurate model and get an explanation; you give up faithfulness-by-construction, not accuracy. For user-facing justification, approximate faithfulness is usually fine.
- On structured signals the gap is often tiny. A well-tuned gradient-boosted tree (intrinsically interpretable via TreeSHAP) frequently sits within a fraction of a percent of a deep net — and is glass-box. The supposed accuracy cost of interpretability evaporates on exactly the tabular data recommenders mostly run on.
- Explainability buys accuracy back elsewhere. Explanations are how you find the leaked label, the popularity runaway, the train–serve skew. A debuggable model converges to a better production metric faster than an opaque one you cannot diagnose.
Interactive · feature-attribution composer (toy SHAP)
Toggle which signals fired for one prediction. The widget shows a SHAP-style additive breakdown — each feature's φᵢ contribution to the logit, summing to the score — picks the template slot from the top contributor, and runs a counterfactual consistency check on the reason it would show. The numbers are toy; the failure modes are the point.
Interview prompts you should be ready for
- "What's the difference between transparency and justification?" (Transparency = a human can follow the model's actual computation; justification = you can show the user a plausible reason for this result. A glass-box model can be shown with a misleading reason; a black box can carry a faithful post-hoc attribution. Different audiences demand different ones.)
- "Intrinsic vs post-hoc — when do you pick each?" (Intrinsic when high-stakes / regulated / cold-start where a simple rule is all the data supports; post-hoc when you've already paid for a deep ranker and can't surrender its accuracy. Intrinsic is faithful-by-construction but caps capacity; post-hoc keeps accuracy but only approximates.)
- "Can I just show attention weights as the explanation?" (For a user-facing card, yes — plausible and persuasive. For an audit, no: attention is a relevance weight in one layer, not causal; low-attention items' value vectors can dominate, and different attention distributions can yield the same prediction. Verify with a counterfactual instead.)
- "Explain SHAP and why it beats raw feature weights." (Shapley value = a feature's average marginal contribution over all coalitions; the unique attribution with efficiency, symmetry, dummy. Contributions add up to the score — aggregable across a fairness slice and stable in a way LIME isn't. Cost: exponential exact, so KernelSHAP / TreeSHAP approximations.)
- "How do you make sure a 'Because you watched X' card isn't lying?" (Bind the template slot to the top attribution, then run a counterfactual check: remove X from the input and confirm the item actually drops out of the top-K. If it doesn't, the reason was fake — block it. This is the consistency guard you'd run in CI.)
- "How does explainability connect to fairness auditing?" (You can't audit what you can't attribute. Global SHAP across protected slices reveals whether an attribute or its proxy — coarse geo, device — is driving exposure. See lesson 20 · Fairness; explainability is the instrument that work reads from.)
- "Doesn't adding explanations cost accuracy?" (Usually overstated. Post-hoc keeps the accurate model; on structured data a GBDT with TreeSHAP is glass-box within a fraction of a percent of a deep net; and explanations buy accuracy back by surfacing leaked labels and train–serve skew faster. Ask which column you're in, not how much accuracy it costs. The one hard number: a ±1% AUC/NDCG neutrality gate the module may not breach.)
- "How would you measure whether your explanations actually work?" (Three layers: system — coverage + generation latency; faithfulness — attribution stability > 0.7 (Spearman of SHAP rankings across time windows), fidelity to the model > 0.7, decision-path coverage ≥ 85% vs the real behaviour log; user/business — ESS (5-pt Likert), adoption (CTR on explained items), ECR (conversion lift). Gate on ±1% AUC neutrality first, then attribute the lift causally with difference-in-differences in the A/B — subtract the control's trend so you don't credit the explanation for a platform-wide shock. The senior point: an unfaithful explanation is worse than none, so faithfulness is a release blocker, not a nice-to-have.)
- "In a multi-task ranker, how do you explain which objective drove a card — not which feature?" (Feature-SHAP can't answer it; you need attribution over the heads. LRP back-propagates the fused score through the fusion weights onto each task head — "57% watch-time, 14% diversity"; or read per-expert gate activations in PLE/MMoE to see when the model favoured retention over clicks. This is the lesson-12 intersection: when the feed tilts to clickbait, objective-attribution shows the watch-time head's share jumped, so you debug the fusion weights — confirm with a counterfactual on w_k — rather than chasing features.)
- "Would you let an LLM write the recommendation reason?" (Yes, for fluency — but it adds hallucination on top of the fake-reason trap: a fluent sentence describing behaviour that never happened, which reads more trustworthy than a clumsy true one. Clamp it both ends: constrain the input to the actual top-SHAP features / strongest KG path (paraphrase, don't retrieve), then parse named entities back out and verify against the grounded set + a counterfactual; any ungrounded entity → block and fall back to a deterministic template. Distill offline, serve light, so it's nearline not per-request.)