cswork / libraryOpen practice workspace

Interview guides · Aj Bell

Aj Bell Data Scientist Interview Questions & Guide 2026

Causal inference drills for Aj Bell data scientist prep: diff-in-diff, matching, instruments, and the limits of observed data.

The 60-second brief

As a Data Scientist at Aj Bell, you are stepping into a pivotal role at one of the UK’s leading investment platforms. Your work directly influences how the business understands customer behaviors, optimizes investment products, and streamlines operational efficiencies. By leveraging vast amounts of financial and user data, you help shape the strategic direction of the company and ensure that millions of customers have a seamless, insightful investing experience.

In modelling rounds the live question is usually why this model class for this problem, and how you would know six weeks after launch that it is still working. Deriving gradients by hand is rarely what is being probed.

Focus areas

  • Reconcile amounts in minor units and currency
  • Read vintage curves, not blended portfolio averages
  • Separate authorization, settlement and dispute outcomes cleanly

Overview

The impact of this position spans multiple products and teams. You will dive deep into complex problem spaces such as customer lifetime value modeling, churn prediction, marketing attribution, and risk analytics. Because Aj Bell operates at a significant scale within the highly regulated financial sector, the models and insights you produce must be both highly accurate and easily interpretable by non-technical stakeholders.

Expect a role that balances rigorous technical execution with high-level business strategy. You will not just be writing code in a silo; you will be acting as a key advisor to product managers, marketing leads, and executive leadership. This role is inherently cross-functional, requiring you to translate complex data narratives into actionable business decisions that drive growth and enhance platform stability.

The Aj Bell interview process

Aj Bell candidates report 2 rounds · ≈ 2-4 weeks. The stages below are what candidates describe, not a published process.

Screening Call

Most candidates lose this call inside the first two minutes, during the walkthrough of their own background. The account runs chronologically, sits at the level of tools and titles, and never arrives at a decision anyone could have disagreed with. Anchor on a problem instead of a timeline: what the team could not answer, what you did about it, what happened next. Ninety seconds is enough, and stopping on time leaves room for the half of the call that belongs to you. What you ask about how work gets prioritised signals your level more reliably than the walkthrough does.

What to demonstrate

  • Whether your background summary has a shape (problem, decision, consequence) or is a chronological list of tools and employers
  • Whether you can account for gaps, short stints and the reason you are looking, unprompted and without hedging
  • The substance of the questions you ask back, which an experienced screener reads as a level signal

How to prepare

  • Time your opening walkthrough against a clock. If it runs past two minutes, compress the earliest role into a single clause and spend the recovered time on the most recent one
  • Write one honest sentence for every gap or short stint visible on your resume and offer it before being asked about it
  • Prepare questions about how work arrives and gets prioritised: who writes the request, how often priorities change, and what happens to an analysis after it is delivered

Onsite Interview

A day of back-to-back interviews samples your floor, not your ceiling. Four hours in, the habits that carry a good answer are the first to go: restating the question before solving it, asking what the data would have to look like, checking a number before quoting it. What the day decides is whether the tired version of you is still someone to leave alone with an ambiguous problem. The round that sinks a candidate is usually not the hardest one. It is the one immediately after the round that went badly.

What to demonstrate

  • Whether the late rounds get the same clarifying questions as the first one, or whether you start answering immediately to save effort
  • Whether a weak answer stays in the room it happened in, instead of following you into the next conversation as apology or distraction
  • Whether the quality of your questions holds up, since fatigue removes curiosity about the problem before it removes knowledge of the method

How to prepare

  • Rehearse the length, not just the content: book four mock interviews of different types in one afternoon with short gaps, because the one you need to observe is the fourth
  • Put the two or three questions you ask at the start of any problem on a card in front of you, so that under fatigue it is a habit you run rather than a decision you make
  • Decide in advance what the gap between rooms is for: water, one line of notes on anything you promised to follow up, and an explicit close on the round that just ended so it does not travel
  • Prepare a different closing question for each interviewer, so the end of a long day does not produce the same one four times

Where candidates lose points

Reading the most recent months of fraud and dispute rates as final

Consumer dispute rights commonly run around 120 days from the transaction or expected delivery date, and several reason codes run considerably longer, so the disputes belonging to a recent transaction month have simply not been filed yet. Any chart attributed by transaction date therefore slopes down at the right edge regardless of what is happening. The fix is to report only matured cohorts, or to apply development factors estimated from completed months and to show the estimate as an estimate.

Counting authorizations instead of weighting them, and summing amounts across currencies

Declines skew toward high-value, cross-border and card-not-present transactions, so an unweighted approval rate can sit flat while approved value falls. Merchant retry logic also turns one declined purchase into several rows, inflating the denominator by an amount that varies by merchant and by decline reason. Amounts are held in the minor unit of the transaction currency and that unit is not always two decimals, since some currencies have none and some have three, so summing amount_minor across currencies produces a figure with no interpretation at all.

Never asking what decision the analysis will inform

Open with who makes the decision, what the options are, and by when. The answer determines the precision you need, the segments worth cutting, and whether an observational read suffices or an experiment is required.

Defining the cohort on a post-treatment condition

Ask how rows entered the table. Filtering on something that treatment itself influences, such as users who finished onboarding or accounts still active at ninety days, breaks comparability between arms; define the population at an entry point that precedes exposure and keep everyone in it.

Questions & practice

Explain the difference between L1 and L2 regularization and when you would use each.

Medium · statistics and probability

Approach

  1. Quantify uncertainty explicitly rather than reporting a point estimate alone.
  2. Sanity-check the answer against a simple bound or a simulated case.
  3. Write down the assumption the method needs before you use the method.

Follow-up

  • Which assumption here is most likely to be violated in practice?
  • How would you explain this result to someone who does not know statistics?

Walk me through your process for handling missing data in a large customer dataset.

Medium · statistics and probability

Approach

  1. Write down the assumption the method needs before you use the method.
  2. Say what the estimate is of, and over what population it generalises.
  3. Translate the result into the decision it informs, in one plain sentence.

Follow-up

  • What sample size would you need to detect an effect half this size?
  • Which assumption here is most likely to be violated in practice?

How do you determine if a model is overfitting, and what steps do you take to correct it?

Medium · machine learning and modelling

Approach

  1. Check what information would not exist at prediction time, and exclude it.
  2. Pick an evaluation metric that matches the cost of each error type, not a default.
  3. Set a baseline first, so any model has something honest to beat.

Follow-up

  • How would you choose the decision threshold, and who owns that choice?
  • Where could label leakage enter this setup?

How does this specific model translate into a tangible increase in customer retention for our platform?

Medium · machine learning and modelling

Approach

  1. Say how the offline result would be validated online before it is trusted.
  2. Frame the prediction: the label, the moment of prediction, and the action it triggers.
  3. Check what information would not exist at prediction time, and exclude it.

Follow-up

  • How would you choose the decision threshold, and who owns that choice?
  • Where could label leakage enter this setup?

Bootstrap a fraud loss rate that clusters within merchant

Medium · bootstrap · clustered resampling · heavy tails

You have a per-transaction frame with auth_id, merchant_id, settled_amount_reporting and net_loss_reporting, both already in one reporting currency. Most rows carry zero loss, a few carry large ones, and losses cluster within merchant. Using only numpy's random generator and no resampling helper from any library, write a bootstrap that returns a 95 percent interval for net fraud loss in basis points of settled volume, resampling merchants with replacement and taking all rows belonging to each drawn merchant. Also produce the naive row-level interval and state which you would report.

Approach

  1. State the estimator before writing it: total net loss divided by total settled volume, times 10,000. It is a ratio of sums, so each replicate recomputes both sums. Averaging per-transaction loss rates instead would weight a five-unit transaction like a five-thousand-unit one.
  2. Pre-aggregate loss and volume to merchant level once. For a ratio of sums, drawing merchants and taking all their rows is arithmetically identical to drawing merchant-level (loss_sum, volume_sum) pairs, so a replicate becomes one integer draw plus two vectorised sums rather than a groupby inside the loop.
  3. Draw B replicates of M merchant indices with replacement, where M is the observed merchant count, compute the ratio per replicate, and take the 2.5th and 97.5th percentiles. Say explicitly that this is a percentile interval and that BCa would correct the skew-induced bias if the decision is close.
  4. Repeat with independent row draws for the naive interval and compare widths on the same replicate count.
  5. Report the clustered interval. Rows within a merchant share an acceptance profile, a category code and a fraud exposure, so they are not independent, and the row-level interval understates variance by roughly the design effect.

Worked solution (30 min)

  1. Compute the point estimate directly on the full data and keep it for comparison.
  2. Aggregate to merchant-level loss and volume arrays, record M, and set B to 2,000 with a seeded numpy Generator.
  3. In a vectorised loop, draw integer indices of shape (B, M), index both arrays, sum along axis 1, and take the ratio times 10,000.
  4. Repeat for the row-level version using the per-transaction arrays and N draws.
  5. Take the 2.5 and 97.5 percentiles of each replicate array and report both intervals alongside the point estimate.

Expected result: Two intervals in basis points sharing the same point estimate. The clustered interval is materially wider, commonly two to four times, and is right-skewed because a heavy merchant can be drawn more than once in a replicate.

Verify it yourself

  • The point estimate equals the direct ratio on the full data and lies inside both intervals.
  • A synthetic input where every merchant holds exactly one transaction makes the clustered and naive intervals coincide; this is the test that the resampling unit is wired correctly.
  • Raising B from 2,000 to 10,000 shifts the endpoints by less than the reporting precision; if it does not, a handful of merchants is driving the tail and the estimate needs that caveat.
  • Replicate ratios never fall outside the range implied by drawing only the lowest-loss or only the highest-loss merchants.

Follow-up

  • Your clustered interval is three times wider. How do you explain that to someone who wanted a tighter number?
  • One merchant accounts for 40 percent of losses. What does that do to the interval, and what would you do about it?
  • How does this change if the question is whether two months differ rather than what this month's rate is?

Write a SQL query to find the top 5% of customers by trading volume over the last quarter.

Medium · sql and data manipulation

Approach

  1. Check whether any join is one-to-many before aggregating, or the sums inflate.
  2. Say which table is the grain you start from, and join outward from it.
  3. Compute rates by summing numerator and denominator separately, never by averaging rates.

Follow-up

  • What breaks if events arrive late or out of order?
  • How does the query change if the join becomes one-to-many?

Customers with no credit application, avoiding the NOT IN trap

Medium · null semantics · anti-join · scd type 2

Count current customers who have never submitted a credit application, broken out by segment. dim_customer is a slowly changing dimension type 2, so restrict to is_current = true, kyc_status = 'verified' and closed_at null. In fct_loan_application, customer_id is null for applicants who were not customers when they applied. Write the anti-join, return segment and customer_count, and state in one line what NOT IN (SELECT customer_id FROM fct_loan_application) returns against this table and why.

Approach

  1. Pin the dimension to one row per customer first: is_current = true already guarantees that, but say so out loud, because forgetting it multiplies every count by the number of attribute versions a customer has accumulated.
  2. Write the anti-join as NOT EXISTS with a correlated predicate on customer_id, which evaluates per row and is unaffected by nulls anywhere in the applications table.
  3. Name the failure explicitly: NOT IN against a nullable column compares each candidate to a set containing NULL, the comparison yields UNKNOWN rather than TRUE, and the whole predicate is therefore never satisfied, so the query returns zero rows.
  4. If NOT IN is required for some reason, add WHERE customer_id IS NOT NULL inside the subquery, which restores the intended semantics, and note that a LEFT JOIN with an IS NULL filter is equally safe.
  5. Group by segment and sanity-check the total against the unfiltered current-customer count minus the count of distinct applying customers.

Worked solution (20 min)

  1. SELECT segment, COUNT(*) FROM dim_customer c WHERE c.is_current AND c.kyc_status = 'verified' AND c.closed_at IS NULL.
  2. Add AND NOT EXISTS (SELECT 1 FROM fct_loan_application a WHERE a.customer_id = c.customer_id).
  3. Group by segment and order by the count descending.
  4. Run the NOT IN variant alongside it and record that it returns zero rows, then run it again with IS NOT NULL added to the subquery and confirm the counts match the NOT EXISTS version.

Expected result: One row per segment present in the current dimension (retail, sme, corporate), each with a non-zero customer_count. The NOT EXISTS and the null-guarded NOT IN forms agree exactly; the unguarded NOT IN form returns no rows at all.

Verify it yourself

  • COUNT(DISTINCT customer_id) equals COUNT(*) on the filtered dimension, which confirms is_current really collapsed the type 2 versions.
  • The total across segments plus COUNT(DISTINCT customer_id) from fct_loan_application restricted to current verified open customers equals the full current verified open customer count.
  • Swapping NOT EXISTS for the unguarded NOT IN changes the result from a populated set to an empty one, which is the whole point of the exercise.

Follow-up

  • Rewrite it as a LEFT JOIN with IS NULL and say when you would prefer that form to NOT EXISTS.
  • How does the answer change if you want customers who never applied as of a historical date rather than today?
  • The applications table has 40,000 rows with a null customer_id. What are those rows, and are they a data quality problem or a product fact?

Describe a situation where your project priorities suddenly changed. How did you adapt?

Medium · product sense and metrics

Approach

  1. Decompose the metric into the rates that drive it, and say which one you would check first.
  2. Name one primary metric, then the guardrail that stops it being gamed.
  3. Restate the decision this analysis has to support, and who acts on the answer.

Follow-up

  • How would you detect that the metric is being gamed rather than genuinely improving?
  • Which segment would you cut first, and what would that rule out?

Describe a time you used A/B testing to evaluate a new feature. How did you calculate statistical significance?

Medium · a/b testing and experimentation

Approach

  1. State the primary metric and the minimum effect worth shipping, then size the test.
  2. Name the guardrails that would stop a launch even on a positive primary result.
  3. Say whether units interfere with each other, and switch design if they do.

Follow-up

  • How would you handle interference between treated and control units?
  • What would you conclude if the result is positive but the test is underpowered?

Explain how you would scale this localized analysis to cover our entire user base.

Medium

Approach

  1. Clarify what is being asked and what a complete answer would contain.
  2. Work from the decision backwards to the evidence you would need.
  3. Say what you would check first and why it is the highest-information step.

Follow-up

  • What assumption would you test first?
  • How would you know your answer was wrong?

Design an authorization approval rate a team cannot game

Easy · approval rate · metric gaming · mix shift

A payments team is given authorization approval rate as its quarterly target, defined as approved authorizations over all authorizations in fct_payment_authorization. Using auth_id, card_token_id, merchant_id, amount_minor, transaction_currency, auth_result, is_reversal, parent_auth_id, channel, issuer_country and requested_at, list three ways the team can raise that number without a single additional customer purchase succeeding. Then write the definition you would put on the dashboard instead, with its exclusions, and name the one guardrail you would always read beside it.

Approach

  1. Enumerate the rows in the table that are not purchases: zero-amount account verifications, reversals (is_reversal = true), incremental authorizations (parent_auth_id not null) and merchant retries of a declined attempt. Each is a lever on the numerator or the denominator that no customer would ever notice.
  2. Name the mix levers. Recurring and card-present traffic approve at higher rates than ecommerce and cross-border, so routing changes or a marketing push into an easy channel move the blended rate with no change in decisioning quality at all.
  3. Work the retry arithmetic rather than asserting it. A declined purchase that is retried three times and succeeds on the fourth contributes one approval and four denominator rows, which is below a healthy blended rate, so suppressing retries raises the published number while some purchases that would have succeeded on a retry now simply fail.
  4. Replace the definition: dollar-weighted, retry chains collapsed to a single attempt per (card_token_id, merchant_id, amount_minor) within a 15-minute window, excluding reversals, zero-amount verifications and incremental authorizations, with all amounts converted into one reporting currency before summing because amount_minor is in the minor unit of transaction_currency and that unit is not always two decimals. Cut by channel and issuer_country so mix shift shows up as mix shift.
  5. Guardrail: net fraud loss in basis points of settled volume, read only on transaction months with at least 120 days of dispute maturity. The fastest way to approve more is to decline less risk, and that bill arrives two to four months later.

Worked solution (25 min)

  1. Compute the naive rate for one week: approved rows over all rows.
  2. Apply the exclusions one at a time (zero-amount, is_reversal, parent_auth_id not null), recording the rate after each, so you can say what each row type was worth to the headline number.
  3. Add a retry-collapsing CTE keyed on (card_token_id, merchant_id, amount_minor) over a 15-minute window, keeping the last attempt in each chain, and recompute.
  4. Recompute dollar-weighted in a single reporting currency, then split by channel and issuer_country.
  5. Write the final one-line definition with its exclusions, plus the guardrail sentence.

Expected result: Four rates for the same week (naive count, count after exclusions, count after retry collapsing, dollar-weighted after both), with the largest single gap attributed to a named row type, and a published definition that states every exclusion and the currency it reports in.

Verify it yourself

  • Excluding zero-amount verifications should lower the rate, since those rows approve at a higher rate than purchases. If it raises the rate, confirm that the amount_minor = 0 filter is not also catching rows with a null amount.
  • Collapsing retry chains raises the rate and shrinks the denominator. The numerator falls only by the number of chains that contained more than one approval.
  • Declines skew toward higher-value, cross-border and card-not-present transactions, so expect the dollar-weighted rate to sit below the count-weighted one. If it sits above, check for amounts summed across currencies before believing it.

Follow-up

  • The blended rate is flat but ecommerce cross-border fell 200 basis points. How do you present that?
  • Why weight by amount rather than by count, and when does the weighted version mislead?
  • Your 15-minute retry window merges two genuine purchases of the same amount at the same merchant. How would you bound that error?

Portfolio delinquency improving while the loan book doubles

Easy · vintage analysis · age mix · right censoring

The blended 90-plus days-past-due rate across fct_loan_performance_monthly fell from 3.1 to 2.2 percent over two quarters while monthly funded volume roughly doubled. Credit leadership wants to know whether underwriting improved. Columns: loan_id, as_of_month_end, origination_month, months_on_book, original_principal_minor, principal_balance_minor, days_past_due, delinquency_bucket, restructured_flag, charge_off_flag, charge_off_date. Produce the view that answers the question honestly, and state in one sentence what the blended rate can and cannot tell you.

Approach

  1. Name the mechanical floor first. A first instalment falls due roughly a month after funding, so a loan cannot reach dpd_90_plus until around its fourth month on book. Every recent origination therefore enters the denominator with a numerator that is structurally zero.
  2. Build a vintage table: rows origination_month, columns months_on_book, cell equal to the share of that cohort whose worst days_past_due reached 90 or more, or whose charge_off_flag became true, at or before that age.
  3. Use each loan's worst state to date rather than its current bucket, and take the pre-restructure worst state, because restructuring resets days_past_due and would otherwise read as a cure.
  4. Compare cohorts only at equal months_on_book, and render cells beyond a cohort's current maturity as absent rather than zero, so the table cannot be misread left to right.
  5. Decompose the blended move into an age-mix component and a within-age component, so the write-up states how much of the 0.9 point improvement is arithmetic rather than asserting it.

Follow-up

  • What does the diagonal of a vintage table represent, and when is reading it the right thing to do?
  • How would a change in charge-off timing policy show up in this table, and how would you separate it from credit quality?
  • Which single chart goes in front of the credit committee, and what do you say when someone asks for the blended series anyway?

Suggested practice checklist

Four days spend equal time on query work, statistics, modelling and product judgement at deliberately shallow depth, which produces a scored map of where you actually stand. The last three days spend everything on the two areas the role weights most, and close by re-running day one to measure movement.

Day 1 — Breadth pass: query fluency

  • Solve six prompts spanning aggregation, joins, window functions and date arithmetic in 60 minutes total, stopping at 10 minutes each whether or not it works, and mark every prompt as solved, solved slowly, or stuck.
  • For each unsolved prompt write the single blocking sentence (I lost the grain, I did not know the frame clause, I could not express the date boundary) instead of reading the solution.
  • Translate one pandas transformation you know well into SQL and one SQL query into pandas, checking that both return the same row count and the same totals.

Deliverable: A scored six-row table, one line per prompt, saved for the day-seven re-run.

Day 2 — Breadth pass: statistics and inference

  • Answer ten short questions in writing with nothing open: what a p-value is conditional on, what a 95 percent interval covers across repeated samples, when a paired test is the right one, what the bootstrap estimates, why multiple comparisons inflate false positives, how controlling the family-wise error rate differs from controlling the false discovery rate, what power depends on, what a missed real effect costs a product, the three situations where the central limit theorem does not rescue you (small n, very heavy tails, dependent observations), and what a standard error is the standard deviation of.
  • Grade yourself against a reference and count only the answers that were exactly right, not the ones that were nearly right.
  • Rewrite the two weakest answers the following morning from memory in full sentences.

Deliverable: Ten graded answers with an honest count of exact hits.

Day 3 — Breadth pass: modelling

  • Take one tabular dataset end to end in 90 minutes: a leakage-safe split, a baseline that is not a model (majority class or historical mean), one regularized linear model, one gradient-boosted tree, and a single evaluation metric chosen before you look at any result.
  • Write why that metric fits the cost structure: precision at a fixed recall for alerting, calibration for anything feeding a price or a threshold, ranking metrics for retrieval, and note that area under the ROC curve is insensitive to class balance in a way that can flatter a rare-positive problem.
  • Name the leak you were most likely to introduce (an encoding fit on all rows before splitting, or a feature computed after the label's timestamp) and write the check that would have caught it.

Deliverable: A notebook whose first cell states the metric and the baseline, plus two lines on what beat what and by how much.

Day 4 — Breadth pass: product judgement

  • Answer three case prompts aloud at 15 minutes each, timing how long passes before you state a success metric.
  • For one case write the first segmentation you would run and the row counts you expect per segment, so that a tiny segment cannot quietly drive the conclusion.
  • Take a metric definition you did not write, from a public dashboard, a textbook, or documentation you already have open, and list every place two analysts implementing it would diverge: which rows the denominator admits, whether the unit is an account or a person, what the time window is anchored to, and what happens to data that arrives late. Then write the one question that would close the largest of those gaps.

Deliverable: Three recorded case answers plus an ambiguity list for a metric someone else defined, ending in the single question you would ask about it.

Day 5 — Depth, first area

  • Rank the four areas by how many bullet points in the role description each one covers, pick the top one, and spend the entire day inside it.
  • Work the six hardest problems you can find in that area and for each write the generalizable move you should have reached for first, rather than the answer.
  • Re-solve the two you failed the same evening with notes closed.

Deliverable: Six generalizable moves written as instructions to yourself, not as solutions.

Day 6 — Depth, second area, and the seam between them

  • Repeat the depth protocol on the second-ranked area with the same six-problem structure.
  • Construct one problem that requires both areas at once, for example a metric redefinition whose effect you must validate with a test whose readout you then have to query.
  • Solve your own combined problem end to end and note where the handoff between the two areas cost you time.

Deliverable: One combined problem, solved end to end, with the handoff failure written down.

Day 7 — Integration and re-measurement

  • Re-run the six prompts from day one under the same clock and compare both correctness and time.
  • Run a 60-minute mixed mock that moves between areas without warning, since switching cost is what breadth passes do not train.
  • Write the two areas you would still fail on, and the sentence you will use in the interview when you hit one of them.

Deliverable: A before-and-after score table plus a written plan for the two remaining gaps.

Ambiguous requests are the test

Most of the questions in this section reduce to one thing: can you be handed a vague request and come back with something useful? Prepare an example where the ask was underspecified, you chose an interpretation, and you said out loud which interpretation you chose. Describing how you narrowed the question matters more than the technique you eventually used.

How do you manage your time when you have multiple stakeholders requesting insights simultaneously?

Medium · behavioural and stakeholder questions

Approach

  1. Pick a story where you drove the decision, not one where you observed it.
  2. Close with what you would do differently, concretely.
  3. Quantify the outcome, including what you would not claim credit for.

Follow-up

  • How did you know the outcome was caused by your change?
  • What did you decide not to do, and why?

Turn a one-line fraud-number request into a scoped brief

Easy · scoping · metric definition · denominators

A stakeholder messages: what is our fraud rate, and is it going up? You have fct_payment_authorization, fct_card_dispute and dim_customer. At least four defensible answers exist: count-weighted or value-weighted, attributed to the transaction month or to the dispute filing month, and gross or net of recoveries and successful representments. You get one reply before someone else produces an uncaveated number. Write that reply: the clarifying questions you ask, the single default you will produce if nobody answers, and what the default excludes.

Approach

  1. Establish the decision behind the question first, because a risk-rule change, a board number and a merchant contract negotiation need different denominators, and asking which one is not stalling.
  2. Offer a short menu rather than an open question: a stakeholder can choose between two named options but cannot specify a denominator from scratch.
  3. Commit to a default so the reply is useful even if nobody answers, for example net fraud loss in basis points of settled volume, attributed to the requested_at month, matured months only.
  4. State the exclusions in the same breath as the default: non-fraud dispute categories, transaction months with less than 120 days of maturity, and first-party abuse that arrives coded as consumer_dispute.
  5. Give a delivery time for the default and a longer one for the fuller cut, so the choice between them carries a visible cost.

Follow-up

  • They come back wanting it by merchant for a contract negotiation. What changes in the definition and in the maturity rule?
  • How would you separate first-party abuse from third-party fraud in this data, and what would you refuse to conclude from the split?

Explain an incomplete dispute chart to a non-technical executive

Easy · dispute maturity · stakeholder communication · right-censoring

A finance lead is looking at first-chargeback rate by transaction month, built from fct_card_dispute joined to fct_payment_authorization on auth_id and attributed to requested_at. The last three months slope sharply down and the lead wants to announce a fraud improvement at tomorrow's review. Consumer dispute rights commonly run around 120 days from the transaction or expected delivery date, so those months are not complete. In five minutes, with no statistics vocabulary, explain why the decline is not yet evidence and say exactly what you would put on the slide instead.

Approach

  1. Lead with the mechanism in the listener's own terms, not with the statistical name for it: a dispute is attributed to the month the transaction happened, but it can be filed up to roughly 120 days later, so recent months contain only the disputes filed so far.
  2. Show completeness rather than arguing about the rate: for each transaction month, plot the share of its eventual disputes already filed, estimated from months that are fully matured. The last three months will sit visibly below 100 percent.
  3. Replace the chart with two artefacts: a matured series that stops 120 days back and is labelled final, and a development-factor estimate for the immature months drawn as a dashed range and labelled an estimate.
  4. Hand over one sentence the executive can repeat without you in the room: the recent months look better because the disputes have not arrived yet, not because fewer will arrive.
  5. Offer a weekly signal they can watch instead, such as the risk-score mix of approved volume or the decline-rule hit rate, and state up front what it does and does not predict.

Follow-up

  • The deck ships tomorrow regardless. What exactly goes on the slide, and what wording do you insist on?
  • How would you estimate the development factors, and how would you notice if they had shifted?