Interview guides · Agero
Agero Data Scientist Interview Questions & Guide 2026
Data scientist prep for Agero: practice defining a payments and lending metric, picking its guardrails and defending the tradeoff.
The 60-second brief
As a Data Scientist at Agero, you are at the intersection of complex logistics, massive-scale automotive data, and life-saving service delivery. Agero provides critical roadside assistance and accident management services, meaning your work directly influences the speed, safety, and efficiency with which people receive help during their most stressful moments on the road.
Nearly every loop contains a round whose deliverable is a recommendation to someone non-technical. Practise stating a conclusion, the confidence attached to it, and the cost of being wrong in each direction, because that triple is the artifact being graded.
Focus areas
- Reconcile amounts in minor units and currency
- Separate authorization, settlement and dispute outcomes cleanly
- Read vintage curves, not blended portfolio averages
Overview
You will be responsible for extracting actionable insights from vast datasets to optimize dispatch algorithms, improve service prediction models, and drive operational efficiency. This role is not just about building models; it is about solving high-stakes, real-world problems that have a tangible impact on customer outcomes. You will work in a fast-paced environment where your ability to translate raw data into strategic business value is paramount.
The most successful candidates at Agero demonstrate a balance between high-level analytical thinking and the ability to roll up their sleeves to write clean, production-ready code.
Where to focus your preparation
Treat the sections below as preparation areas and confirm the format with your recruiter.
Preparation focus
No round sequence has been reported for this company, so work the categories below and confirm the format with your recruiter.
What to demonstrate
- Breadth across SQL, experimentation and product reasoning
- Ability to state assumptions before choosing a method
How to prepare
- Drill the practice exercises below and time yourself
- Prepare three quantified stories about decisions you drove
Where candidates lose points
Averaging delinquency across a book that is growing
A loan three months old cannot be 90 days past due, so a portfolio with many recent originations reports a low blended 90+ rate purely from age mix. The blended rate falls fastest exactly when originations grow fastest, which is precisely when credit quality most needs watching, so the metric moves in the reassuring direction during the riskiest period. Only comparisons at equal months on book are valid, which is what a vintage or roll-rate view enforces.
Recalibrating an underwriting cutoff on approved and funded applicants only
Rejected applicants have no repayment outcome, and they were rejected because the incumbent model scored them badly, so the missingness depends directly on the outcome being modelled. Reject inference by augmentation or parcelling fills the gap using the incumbent model's own assumptions, which means it can confirm those assumptions but cannot test them. The only genuinely new information about the reject region comes from bureau performance on rejects who borrowed elsewhere, or from a deliberately randomised approval band around the cutoff.
Interpreting a change before checking data quality and logging
Spend the first pass on row volume by day, null rates, duplicate keys, and whether the step change lands on a release or tracking-migration date. A discontinuity that coincides with a deploy is an instrumentation hypothesis before it is a behavioural one.
Writing SQL without stating NULL and tie-breaking behaviour
Before calling a query finished, say what it does with NULLs, ties and empty groups. NOT IN against a subquery containing a single NULL returns no rows at all, and RANK, DENSE_RANK and ROW_NUMBER differ precisely on ties, so name which one the question requires.
Questions & practice
Can you explain the intuition behind a specific algorithm you have used in your past projects?
Medium · machine learning and modelling
Approach
- Say how the offline result would be validated online before it is trusted.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Pick an evaluation metric that matches the cost of each error type, not a default.
Follow-up
- Where could label leakage enter this setup?
- How would you choose the decision threshold, and who owns that choice?
How do you evaluate the performance of a model when the cost of a false negative is high?
Medium · machine learning and modelling
Approach
- Say how the offline result would be validated online before it is trusted.
- Check what information would not exist at prediction time, and exclude it.
- Set a baseline first, so any model has something honest to beat.
Follow-up
- What would you monitor after launch to know the model is still valid?
- How would you choose the decision threshold, and who owns that choice?
How would you handle imbalanced datasets in a roadside assistance prediction model?
Medium · machine learning and modelling
Approach
- Set a baseline first, so any model has something honest to beat.
- Say how the offline result would be validated online before it is trusted.
- 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?
- What would you monitor after launch to know the model is still valid?
Collapse retry chains and compute a dollar-weighted approval rate
Medium · sessionisation · window functions · dollar-weighted rates
fct_payment_authorization gives auth_id, card_token_id, merchant_id, amount_minor, transaction_currency, requested_at, auth_result, is_reversal, channel and issuer_country. Two reference frames give the minor-unit exponent per currency and a daily rate to one reporting currency. Collapse retry chains first: attempts sharing card_token_id, merchant_id and amount_minor whose consecutive gaps are under 15 minutes form a single attempt, whose outcome is its last row. Exclude reversals and zero-amount verifications. Return a 7-day rolling dollar-weighted approval rate by channel and issuer_country.
Approach
- Filter before grouping: drop is_reversal rows and zero-amount verifications, since neither is a purchase attempt and both would otherwise sit in the denominator.
- Sort by card_token_id, merchant_id, amount_minor and requested_at, take the gap to the previous row within that key, mark a chain start where the gap exceeds 15 minutes or the key changes, and label chains with a cumulative sum of that flag. This is a gap rule between consecutive attempts, not a fixed clock bucket, so a chain may span more than 15 minutes in total.
- Keep each chain's terminal row by requested_at. If a retry was approved, the purchase was approved; keeping the first row reports the decline that caused the retry as the outcome.
- Convert amounts exactly once: amount_minor divided by 10 to the power of the currency exponent, multiplied by the reference rate for the authorization date. Do not reach for settlement_fx_rate, which is null on precisely the declined rows the denominator needs.
- Build the rolling window as a ratio of two rolling sums, approved value over total value, per channel and issuer_country. A rolling mean of daily ratios weights a quiet Sunday the same as a busy Friday.
Worked solution (35 min)
- Filter out reversals and zero-amount rows, then sort by the chain key and requested_at.
- Compute the within-key time difference, derive the chain start flag and the chain id, and take the last row per chain with groupby(chain_id).tail(1) after sorting.
- Join the exponent and daily rate tables, compute value_reporting, and assert no nulls remain after the join.
- Aggregate approved value and total value to a daily grain by channel and issuer_country, reindex to a complete date range per group so missing days are zero rather than absent.
- Take 7-day rolling sums of both columns and divide, then confirm one hand-picked group-day against a direct filter.
Expected result: A DataFrame keyed by date, channel and issuer_country with approved_value, total_value and approval_rate. The collapsed attempt count is materially below the raw row count, with the gap concentrated in declined ecommerce rows, and ecommerce sits below card_present.
Verify it yourself
- Within every chain, all consecutive requested_at gaps are under 15 minutes; across chains with the same key, at least one gap is not.
- Chain count is strictly below raw attempt count, and the difference is concentrated in declined rows rather than spread evenly.
- Total converted value on a single-currency single-day subset equals the raw amount_minor sum divided by that currency's exponent power, times that day's rate.
- The rolling rate on one chosen day matches a direct filter-and-divide over the preceding seven days.
Follow-up
- The count-weighted rate is flat while the dollar-weighted rate falls 80 basis points. What do you look at first?
- How would you choose the 15-minute window rather than inheriting it?
- A merchant moves from two retries to five. Which of your two rates moves, and is that a real change in approval quality?
Derive a mathematical equation to represent a specific operational scenario (e.g., service time optimization).
Medium · sql and data manipulation
Approach
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- Compute rates by summing numerator and denominator separately, never by averaging rates.
Follow-up
- How would you verify this result without re-running the same query?
- What breaks if events arrive late or out of order?
Vintage ninety-plus rate at twelve months on book
Medium · vintage analysis · window functions · right censoring
From fct_loan_performance_monthly, build a vintage table keyed on origination_month: the share of each cohort that ever reached days_past_due of 90 or more, or charge_off_flag = true, at or before months_on_book = 12. Restructuring resets days_past_due, so for any loan with restructured_flag true, evaluate only the month ends strictly before its first restructured month. Return origination_month, loans_funded, bad_loans and bad_rate. Exclude any cohort that does not yet have a months_on_book = 12 observation for every loan still on book.
Approach
- Establish the cohort denominator from the first month end each loan appears at, months_on_book = 0, so a loan is counted once in its origination_month rather than once per monthly row.
- Find each loan's first restructured month with MIN(as_of_month_end) FILTER (WHERE restructured_flag) OVER (PARTITION BY loan_id), or the equivalent grouped subquery, and keep it null for loans never restructured.
- Flag a loan bad if any row with months_on_book <= 12 and as_of_month_end earlier than that first restructured month has days_past_due >= 90 or charge_off_flag = true, which is what 'pre-restructure worst state' means in practice.
- Gate maturity by requiring the cohort's newest month end to be at least 12 months after origination_month, and report immature cohorts as incomplete rather than letting them appear at a flattering low rate.
- Aggregate to one row per origination_month and read the column downward, not across calendar time, because the whole point is comparing cohorts at equal age.
Worked solution (35 min)
- CTE 1: per loan_id, derive origination_month, the first restructured month end, and the maximum months_on_book observed.
- CTE 2: join back to the monthly rows, filter to months_on_book <= 12 and to month ends before any restructure, then flag bad with a BOOL_OR.
- CTE 3: aggregate to origination_month with COUNT() as loans_funded and COUNT() FILTER (WHERE is_bad) as bad_loans.
- Apply the maturity gate and compute bad_rate with a numeric cast.
Expected result: One row per matured origination_month with loans_funded, bad_loans and a bad_rate between 0 and 1. The most recent immature cohorts are absent from the output entirely rather than present with a small bad_rate.
Verify it yourself
- SUM(loans_funded) across reported cohorts equals COUNT(DISTINCT loan_id) restricted to those same origination months.
- Recomputing without the months_on_book cap raises bad_rate monotonically for every cohort, and raises it most for the oldest, which is the seasoning effect made visible.
- No cohort in the output has a maximum months_on_book below 12.
Follow-up
- Should a restructure inside 12 months count as bad in its own right? Argue both sides and say what you would actually ship.
- A loan that prepaid in full at month 4 never had a chance to go 90 days past due. In or out of the denominator, and why?
- The 2025-11 cohort is two points worse at month 12 than its neighbours. What three queries do you run before you call it a credit-quality change?
Monitor a rollout daily without inflating false positives
Medium · peeking · sequential testing · alpha spending
A risk-rule change is ramped to 50 percent and the team reads the dashboard every morning for twenty business days, intending to stop the first time the two-sided p-value on the count-weighted approval rate falls below 0.05. Quantify how much that inflates the false positive rate, propose a monitoring scheme that still permits an early stop for harm, and explain what dispute maturity does to the matured fraud basis points guardrail when it is read on day twenty.
Approach
- Quantify rather than assert. Repeatedly applying a fixed-horizon test at nominal two-sided 0.05 inflates the family-wise type I error to roughly 8 percent at 2 looks, 14 percent at 5, 19 percent at 10 and about 25 percent at 20 equally spaced looks. Under continuous monitoring with no stopping rule the probability of crossing at some point tends to 1.
- Pick a scheme matched to how the team actually behaves. If looks are on a fixed schedule, use a group-sequential design with an alpha-spending function: O'Brien-Fleming spends almost nothing early so the final boundary stays near nominal, which suits a team that mostly wants to ship at the end; Pocock spends evenly and buys genuine early-stopping power at the cost of a stricter final boundary. If looks are truly continuous and ad hoc, use an always-valid confidence sequence such as a mixture sequential probability ratio test, which is valid at every moment in exchange for a larger fixed-horizon sample at equal power.
- Treat the harm stop as a separate, asymmetric decision. Stopping a change because it looks harmful costs one abandoned experiment; failing to stop costs real loss every day it runs. Run the guardrail as a one-sided monitor at a looser alpha with its own pre-registered stop rule, and do not spend the primary metric's alpha budget on it.
- Fix the schedule before launch: the number of looks, their timing, the boundaries, and the maximum sample. Boundaries computed after the fact from however many times someone opened the dashboard are not a correction.
- Separate peeking from immaturity on the fraud guardrail. Disputes on a transaction can be filed for roughly 120 days, and some reason codes run longer, so a day-twenty read covers transactions with at most twenty days of dispute exposure. The number is not low, it is incomplete. Either report only matured transaction months, or apply development factors estimated from completed months and label the result an estimate with its interval.
Follow-up
- Under an O'Brien-Fleming boundary you cross on day three. What do you say about the effect size, and why is the naive point estimate biased?
- How would you set the stopping rule for the fraud guardrail given that its true value is not observable inside the test window?
- The team argues that they are only looking, not deciding, so peeking is harmless. Under what precise condition is that true, and how would you verify it?
Evaluate a staggered country rollout without a randomised control
Hard · difference-in-differences · synthetic control · staggered adoption
A step-up authentication rule was enabled for ecommerce traffic in three issuer_country markets on three different dates across five months; twelve comparable markets never received it. You have fct_payment_authorization and fct_card_dispute at daily grain and cannot randomise. Estimate the effect on the dollar-weighted authorization approval rate and on matured fraud basis points, name the estimator and why the obvious one is wrong here, and justify your inference given that there are only three treated clusters.
Approach
- Rule out the default first. A two-way fixed effects regression with a single post-times-treated indicator is not valid under staggered adoption with effects that vary over time, because it constructs comparisons that use already-treated markets as controls for later-treated ones and can assign negative weights to some of those comparisons, so the coefficient need not lie inside the range of the true effects.
- Use an estimator built for staggered timing: Callaway and Sant'Anna group-time average treatment effects, or the Sun and Abraham interaction-weighted estimator, restricting the comparison group to the twelve never-treated markets and aggregating into an event study indexed on time since adoption.
- Defend parallel trends with evidence, not a single test. Show the pre-period leads with their intervals and state their magnitude relative to the post-period effect, because pre-trend tests are underpowered and failing to reject is not evidence of parallelism. Pre-register the maximum pre-period lead you would tolerate before abandoning the design.
- Fix the inference problem directly. With three treated clusters, cluster-robust standard errors are severely anti-conservative. Fit a separate synthetic control for each treated market against the twelve donors, with non-negative weights summing to one fitted on pre-period outcomes and predictors, then use in-space placebo permutation and the ratio of post-period to pre-period root mean squared prediction error as the test statistic. With twelve donors the smallest attainable one-sided permutation p-value is 1 / 13, about 0.077, so say that before anyone asks for p below 0.05.
- Split the two outcomes by maturity. The dollar-weighted approval rate is observable immediately and can be read on the full post window. Matured fraud basis points require at least 120 days of dispute maturity from the transaction month, so the fraud event study must terminate at the last matured month and the immature months must be marked incomplete rather than plotted as low.
- Enumerate and test the confounds specific to this setting: network mandates or regulatory deadlines that landed on the same dates, merchant-side changes in the treated markets, currency mix and settlement FX, and seasonality. Exclude donors subject to a concurrent mandate, and confirm that donors and treated markets do not share an acquirer whose outage would move both.
Worked solution (45 min)
- Build a market-by-day panel of the dollar-weighted approval rate from fct_payment_authorization, applying the retry-collapsing and reversal exclusions and converting to one reporting currency at a pinned rate table so FX movement is not mistaken for effect.
- Fit Callaway and Sant'Anna group-time ATTs with the twelve never-treated markets as the comparison group, and aggregate into an event study with at least six pre-period leads and the full post window.
- Fit a separate synthetic control per treated market on the pre-period outcome plus predictors, verify weights are non-negative and sum to one, and record the pre-period root mean squared prediction error.
- Run in-space placebos by applying the same procedure to each of the twelve donors and rank the treated markets' post-over-pre RMSPE ratios among them to obtain permutation p-values.
- Repeat the whole pipeline for matured fraud basis points from fct_card_dispute attributed to the authorization's requested_at month, truncating the series at the last month with 120 days of maturity.
- Report both event studies side by side, state the permutation p-value floor of about 0.077, and present the approval-rate gain against the matured fraud change in the north-star units.
Expected result: A Callaway and Sant'Anna event study on the dollar-weighted approval rate using never-treated donors, corroborated by per-market synthetic controls with in-space placebo inference, plus a matured fraud basis points event study truncated at 120 days of dispute maturity. Inference is by permutation, not cluster-robust standard errors, and the candidate states up front that with twelve donors the smallest one-sided p-value attainable is about 0.077.
Verify it yourself
- Pre-period event-study leads should be small relative to the post-period effect and jointly indistinguishable from zero; a visible pre-trend invalidates the design regardless of the post-period estimate.
- Synthetic control pre-period RMSPE must be small relative to post-period RMSPE, otherwise the post-period gap is fit error rather than effect.
- Donor weights must be non-negative and sum to one, and leave-one-donor-out refits should not move the estimate materially.
- A placebo adoption date three months before the real one should produce no jump; if it does, something else changed in those markets.
Follow-up
- Your synthetic control for one market puts 80 percent of the weight on a single donor. What do you do, and what does the leave-one-out check tell you?
- The approval rate rises and matured fraud basis points also rise. How do you express the trade-off in a single decision-grade number, and what does that require you to assume about the value of a declined good transaction?
- Suppose a fourth market adopts mid-analysis. How does that change the estimator, the donor pool and the permutation inference?
Manual review rate doubles on the day two changes ship
Hard · definition change · model version · population stability
Manual review rate on fct_loan_application, defined as decided_by = 'manual' over decisions in ('approve','decline'), stepped from 9 to 18 percent on a single day. That day a new model_version went live, and the same release changed which referral paths are recorded as manual. Columns: submitted_at, channel, bureau_score, model_pd_12m, model_version, policy_rule_hits, decision, decided_by, decision_at. Attribute the step across definition, model and population, with a number against each.
Approach
- Establish the shape before the cause. A definition or code change produces a step at the deploy timestamp; a population change produces a ramp. Plot at hourly granularity either side of the release and read which one this is.
- Dual-run the definition. Recompute the metric under both the old and the new recording rules across several months of history. If the historical series under the new rule sits near 18 percent throughout, that part of the step is definitional and should be restated, not investigated.
- Hold the model constant and decompose the residual by policy_rule_hits identifier. A referral rule keyed to a score threshold shows its own step, and naming the rule is what makes the finding actionable to the policy owner.
- Test the score, not the applicants. Compare model_pd_12m distributions by model_version on the same applications where shadow scores exist; otherwise compare adjacent weeks with a population stability index, treating the customary 0.1 and 0.25 marks as heuristics rather than tests, and assess calibration separately from ranking.
- Test the applicants, not the score. Compare channel mix, bureau_score distribution and null-bureau share across the boundary. If those are stable, population is not a driver and should be reported as approximately zero rather than left unquantified.
- Deliver three components that sum to the observed step, each with the team that owns it.
Follow-up
- If the new model is better calibrated, is a higher referral rate the correct outcome or a threshold nobody retuned?
- How would you have caught the recording change before it reached the dashboard?
- What is the swap set here, and which swap group would you inspect first?
Suggested practice checklist
Roughly 90 minutes a night on weekdays with one longer weekend block. The plan deliberately cuts scope rather than compressing everything, on the assumption that finishing one thing a night beats half-starting four.
Day 1 — Fix the scope and set a baseline
- Read the role description and write the three things the loop will almost certainly test, then write an explicit not-doing list for everything else and keep it visible all week.
- Take one 20-minute SQL prompt and one 10-minute metric question cold, and write the single sentence that says what blocked each attempt, since that sentence is what decides which two topics get the most evenings.
- Set the week's one rule: one problem finished to completion every night, including the night you only have 40 minutes.
Deliverable: A one-page scope with an explicit not-doing list and two cold attempts, each carrying one sentence on what blocked it.
Day 2 — One query pattern, written three times
- Choose the single pattern most likely to appear (a cohort retention grid, or a funnel counted by user) and write it three times from a blank file rather than editing the previous attempt.
- On the third attempt, write the grain of every CTE as a comment before writing its body.
- Stop at 90 minutes even if the third version is imperfect, and write the one thing you would fix with another hour.
Deliverable: Three independent versions of the same query plus a note on what changed between them.
Day 3 — Only the statistics you will be asked to defend
- Write, in under 200 words, how you would decide whether a difference between two groups is real: the test, its assumptions, and what you would switch to when an assumption fails.
- Compute a 95 percent confidence interval for a difference in proportions by hand on realistic numbers, then write in one sentence what changes if the two samples are paired rather than independent.
- Write your answer to "what does a p-value mean", check it against a definition, and delete the version that describes it as the probability the hypothesis is true.
Deliverable: A 200-word written answer and one hand-computed interval you can reproduce under pressure.
Day 4 — One case, and the assumptions holding it up
- Answer one product case aloud in 20 minutes with a recording running, then listen back with a pen and mark every claim you asserted without saying what it rested on: an assumed user behaviour, an assumed data source, an assumed baseline rate, an assumed grain.
- Pick the three assumptions the recommendation actually depends on, write how you would check each one against data, and say which one being wrong would flip the recommendation rather than merely weaken it.
- Write the four-step structure you used onto a card small enough to hold in working memory when you are nervous.
Deliverable: One recording, three load-bearing assumptions each with a written check, and a four-step structure card.
Day 5 — Your own work, timed
- Write a 90-second version and a four-minute version of your main project, and time both out loud rather than reading them.
- Prepare answers to the two follow-ups that always come: what you would do differently, and how you knew it worked.
- Put one number in the first sentence and be able to say exactly where that number came from and what it excludes.
Deliverable: Two timed narratives with one defensible number in the opening line.
Day 6 — The one full rehearsal, in a longer weekend block
- Run a 60-minute mock covering query work, a case and a behavioural question in a single sitting with no breaks, because sustained attention is the thing evenings have not trained.
- Immediately afterwards, and before hearing any feedback, write the three moments you lost the thread.
- Spend the rest of the block only on those three moments, and on nothing you merely feel shaky about.
Deliverable: Mock notes naming three failure moments with a specific fix written under each.
Day 7 — Taper
- Write the 20-minute warm-up you will actually do on the morning of the interview: one query you can already write from a blank file, one metric you can define out loud, and nothing you have never seen before.
- Re-read only your own notes from this week, and open no new material.
- Write down the logistics: the tool you will be asked to work in, whether lookups are allowed, and the sentence you will use when you do not know something.
Deliverable: A one-page card holding the case structure, the project numbers, and the logistics.
Stories where someone disagreed with you
Have two ready. In one, the data was on your side and you had to move someone who outranked you. In the other, the pushback was correct and you changed position. The second is the harder story and it lands better, because it shows you separate being right from being attached to an answer. Name the person's actual objection.
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
- 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.
- 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.
- 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.
- 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.
- 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?
Defend a vintage finding that contradicts the portfolio dashboard
Medium · vintage analysis · mix shift · stakeholder pushback
The lending dashboard shows blended 90-plus days-past-due falling for four consecutive quarters while originations grew 60 percent. Using fct_loan_performance_monthly, you build a vintage view keyed on origination_month by months_on_book and find the three most recent vintages are worse than their predecessors at the same age. The business lead presents that dashboard weekly and pushes back hard, suggesting you picked favourable cohorts. You get one meeting and the vintage table. Present the finding so it survives the cherry-picking objection and ends in a decision.
Approach
- Reconcile before you contradict: show that aggregating your vintage table along the calendar diagonal reproduces the published blended series, so the disagreement is about age mix rather than about data quality.
- Make the mechanism arithmetic rather than rhetorical: a loan cannot reach 90 days past due before it is 90 days old, so rapid origination growth shifts weight onto young months-on-book where the rate is structurally near zero.
- Show every vintage rather than a selected pair, all indexed at months_on_book equal to 12, with cohort sizes printed beside each curve so nobody can claim the divergence rests on a thin cohort.
- Handle restructuring explicitly, because restructured_flag resets days_past_due: count each loan on its worst pre-restructure state, or recent vintages will look better than they are.
- Close on the decision rather than the chart: state what the divergence implies for the cutoff or the channel mix, and state in advance what evidence would make you withdraw the claim.
Follow-up
- Two cohorts differ at month 12. How do you separate a seasoning effect from a genuine credit-quality effect?
- Someone argues the recent vintages are simply a broker-channel mix shift. How do you test that, and what would confirm it?
Disagree with a product manager over an approval-rate target
Medium · metric design · denominators · influence without authority
A product manager proposes a quarterly goal of raising card authorization approval rate by 150 basis points, measured as approved authorizations divided by all authorizations in fct_payment_authorization. You believe that metric can be hit with no customer benefit, because merchant retry chains, zero-amount verification authorizations, incremental authorizations and reversals all sit in the denominator, and declines skew toward high-value cross-border ecommerce. You support the underlying goal. In one working session, change the metric without killing the initiative, and name the guardrail you would accept.
Approach
- Separate the goal from the metric out loud and agree with the goal first, so the disagreement stays narrow and technical rather than becoming positional.
- Demonstrate the failure rather than asserting it: compute the proposed metric and the dollar-weighted collapsed version over the same recent window, and find a period where they moved in opposite directions.
- Propose the replacement precisely: sum of approved amount_minor over sum of attempted amount_minor, after collapsing retries to one attempt per card_token_id, merchant_id and amount_minor within a 15-minute window, excluding is_reversal rows and zero-amount verifications, with everything converted to one reporting currency before summing.
- Attach the guardrail that makes the target honest: matured first-chargeback rate and net fraud loss in basis points of settled volume, read only on transaction months carrying at least 120 days of maturity.
- Give the product manager something back: the replacement metric cuts cleanly by channel and issuer_country, which makes a roadmap of merchant-specific and authentication fixes legible in a way the blended rate never was.
Follow-up
- How do you identify a retry chain when the merchant varies the amount slightly between attempts?
- The product manager wants a weekly read on the guardrail. What is the earliest defensible signal, and how do you label it?