Interview guides · American Family Insurance
American Family Insurance Data Scientist Interview Questions & Guide 2026
American Family Insurance data scientist prep: probability, sampling distributions, and stating the assumption behind every test you run.
The 60-second brief
At American Family Insurance, a Data Scientist plays a pivotal role in transforming traditional insurance practices into data-driven, predictive operations. Insurance is fundamentally an industry built on assessing, pricing, and mitigating risk. By leveraging vast amounts of structured and unstructured data—ranging from telematics and property images to customer interactions and policy histories—data scientists build the predictive models that power the company's core products and strategic decisions.
Seniority shifts the scope more than the words in the title do. Earlier-career loops mostly check that you execute a well-posed analysis correctly; senior loops check that you can decide which question is worth answering and defend what you chose not to do.
Focus areas
- Decompose expected loss into PD, LGD, EAD
- Reconcile amounts in minor units and currency
- Set fraud thresholds by expected cost
Overview
The impact of this role is felt across the entire customer lifecycle. Your work will directly influence how policies are priced, how claims are triaged and automated, and how the company detects fraudulent activity. For instance, teams within the organization apply computer vision to assess property damage from aerial imagery, utilize natural language processing (NLP) to extract insights from policy documents, and build classic machine learning models to predict customer churn and lifetime value.
This is an inspiring yet highly rigorous environment. You will not just be training models in a vacuum; you will be solving complex, real-world problems that protect millions of families. To succeed, you must blend deep technical expertise in statistical modeling and software engineering with a strong business acumen, translating complex algorithmic outputs into actionable strategies for underwriters, actuaries, and product leaders.
The American Family Insurance interview process
American Family Insurance candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.
Recruiter Screen
A screening call is a matching exercise run by someone who will not evaluate your statistics. They are checking that the work described on your resume is work you personally did, and that its scope matches the level the role is written for. Logistics get settled in the same half hour so nobody spends an interviewer's afternoon on a mismatch. The answer that fails is the one narrated in the plural. If every sentence is 'we built' and 'the team decided', there is nothing specific to write down about you. Name the piece that was yours, the decision you made inside it, and what changed after.
What to demonstrate
- Whether the ownership implied by your resume survives one round of follow-up about who actually did which part
- Whether your described scope (data size, stakeholders, what shipped) matches the seniority the role is written at
- Whether timeline, location and compensation expectations make the rest of the loop worth scheduling
How to prepare
- Rewrite your top three resume bullets in the first person singular, each with the decision you made and what moved afterwards, then say them out loud once so the 'we' does not return under pressure
- Attach one number to each project: the baseline, the change, and the window it was measured over. Where impact was never measured, say that plainly rather than inventing a figure
- Settle your compensation range before the call and give it as a range with a reason behind it, such as current total comp or a competing timeline, instead of deflecting the question twice
Technical Evaluation
This round decides whether someone can hand you a schema and a question and trust the number that comes back. Correctness under a clock is the bar, not clever syntax. The habit that separates strong from weak answers is checking the grain: after every join, know how many rows you expect and whether the count moved. Most wrong answers in this format are not wrong logic, they are a fan-out from a key that turned out not to be unique, or a filter applied before an aggregate when it belonged after. Say what you expect before you run it.
What to demonstrate
- Whether your row counts survive each join, and whether you notice on your own when they do not
- Deliberate handling of rows that fail to match, including whether the question needs an inner join or a left join with the non-matches kept and counted
- Whether NULLs are treated on purpose, given that a NULL compares equal to nothing and that COUNT of a column skips it
- Reaching a defensible answer inside the window instead of a refined one after it
How to prepare
- Take a two-table schema, write a join that fans out on purpose, then fix it by collapsing the many-side to one row per key before joining. Repeat until the fix is reflex rather than recall.
- Write a funnel as one query and print the distinct user count at each stage, then confirm each stage is a subset of the one above it rather than assuming it
- Do a few timed runs in a plain text box with no autocomplete and no formatter, since assessment editors often have neither
Final Interview Rounds
Where a loop includes a partner from outside the data team, that conversation usually carries the same weight as the technical ones and gets the least preparation. The person opposite you will not follow a derivation and does not need to. They are working out whether having you involved would make their decisions better or slower. The failure mode is not being too technical. It is answering a question about a decision with a description of your method, leaving the translation to them. What they carry into the debrief is the sentence you handed them, not the analysis underneath it.
What to demonstrate
- Whether a statistical result arrives as something the partner could act on, with the one caveat that would change their decision kept and the rest left out
- Whether you can state what you need from their side, in their terms: instrumentation that does not exist yet, a definition they own, or a holdout they have to agree to
- Whether uncertainty is given as a range someone can plan against, rather than as hedging that invites them to ignore the result
- Whether you ask what decision is actually on the table before explaining anything
How to prepare
- Take a result you know well and write the version for someone who stops reading after one sentence, then the three-minute version, and check the short one is not the long one with the qualifications stripped out
- For a past project, list everything you asked a non-technical partner for and how you phrased it, then rewrite each ask so it names what goes unmeasured without it
- Practise saying where a result does not apply, out loud, in one sentence that a partner could repeat accurately to someone else
Where candidates lose points
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.
Assuming a model is fair because protected attributes are not among its inputs
Postcode, device, tenure, income proxies and even transaction patterns correlate with protected characteristics, so a model can produce a disparate outcome without ever reading the attribute. Credit decisions additionally carry an explainability obligation in many jurisdictions, since a denial has to be accompanied by its principal reasons, which constrains model form and feature engineering rather than being a reporting afterthought. Treating fairness testing and reason-code generation as design constraints from the first model version is far cheaper than retrofitting them to a deployed one.
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.
Ending an analysis without a recommendation or next step
Close with what you would do and what would change your mind, stated as a condition you can check later. If the evidence is genuinely inconclusive, recommend the specific next measurement and say what it costs in time or exposure.
Questions & practice
How do you handle extreme class imbalance when training a classification model for fraud detection?
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.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
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?
Walk me through a machine learning model you deployed to production. What were the data processing challenges, and how did you overcome them?
Medium · machine learning and modelling
Approach
- Check what information would not exist at prediction time, and exclude it.
- 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
- 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?
Estimate a delinquency roll-rate matrix and project twelve months
Hard · roll rates · markov chain · survivorship
fct_loan_performance_monthly gives loan_id, as_of_month_end, months_on_book, delinquency_bucket, charge_off_flag, prepaid_in_full_flag and restructured_flag. Build a month-to-month transition matrix over the five delinquency buckets plus absorbing charged_off and prepaid states. Loans that stop appearing must be routed to an absorbing state rather than dropped. Project the current book forward 12 months by repeated matrix multiplication and report the projected share reaching charge-off. Handle restructured_flag explicitly, and name one place the Markov assumption fails on this data.
Approach
- Build consecutive month pairs per loan by shifting as_of_month_end within loan_id, then verify the shifted value is exactly one month later. A gap is not a transition, it is an exit you have not resolved yet.
- Resolve exits before counting anything. A loan whose last row carries charge_off_flag moves to charged_off, one carrying prepaid_in_full_flag moves to prepaid, and one that disappears with neither is a data question to raise rather than silently discard, because discarding it is survivorship that inflates every cure rate.
- Count pairs into a 7 by 7 matrix and row-normalise. Assert every row sums to one and the two absorbing rows are the identity; a row that does not sum to one means exits were dropped.
- Decide and state the restructure rule. Restructuring resets days_past_due, so a dpd_60_89 to current move on a restructured loan is not a cure. Either give restructured loans their own state or carry the pre-restructure bucket, but do not let that move land in the cure cell.
- Project by taking the current bucket distribution as a row vector and multiplying by the matrix twelve times. Report the charged_off entry, and report it again from an all-current starting vector so the reader can see how much of the projection comes from loans that are already delinquent today.
- State the homogeneity failure plainly: transition rates depend strongly on months_on_book, so one pooled matrix applied to a book with a young mix understates early-life delinquency. If the mix is moving, estimate separate matrices by seasoning band.
Worked solution (45 min)
- Sort by loan_id and as_of_month_end, shift to form (from_state, to_state) pairs, and flag pairs whose month gap is not exactly one.
- For each loan's final row, assign the absorbing destination from charge_off_flag or prepaid_in_full_flag, and list loans that vanish with neither as an exception count to report.
- Apply the restructure rule, then build the 7 by 7 count matrix with a cross-tabulation over ordered state categories and row-normalise it.
- Assert row sums equal one and absorbing rows are the identity, then take the current month's bucket distribution as a row vector.
- Multiply twelve times, report the charged_off component, and repeat from an all-current vector for comparison.
Expected result: A 7 by 7 row-stochastic matrix with identity rows for charged_off and prepaid, a current-to-current diagonal typically above 0.95, roll rates rising with bucket depth, and a 12-month projected charge-off share of a few percentage points from an all-current start and materially higher from the actual book.
Verify it yourself
- Every row sums to one within floating-point tolerance, and both absorbing rows are exactly the identity.
- No mass sits in cells that skip a bucket upward, such as dpd_1_29 to dpd_60_89 in one month; if there is, the pairs are not actually consecutive months.
- The projection from an all-current start is strictly below the projection from the real book distribution.
- Backtest by estimating on months up to t minus 12 and comparing the projected distribution with the realised one at t; a systematic optimistic gap points at dropped exits or at seasoning, not at noise.
Follow-up
- How would you validate the projection against what actually happened, and over what window?
- The cure rate out of dpd_30_59 rose five points last quarter. What are the candidate explanations and how would you separate them?
- When would you prefer a vintage curve to a roll-rate projection, and why?
Write a SQL query to join policyholder data with claims history and find the average claim amount per region.
Medium · sql and data manipulation
Approach
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- Say which table is the grain you start from, and join outward from it.
- 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?
Implement a function to detect anomalies in a time-series dataset of policy transactions.
Medium · sql and data manipulation
Approach
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- State the window function and its partition and ordering out loud before writing it.
- Say which table is the grain you start from, and join outward from it.
Follow-up
- What breaks if events arrive late or out of order?
- How does the query change if the join becomes one-to-many?
Write a Python function to parse and clean a raw, unstructured text log of customer service interactions.
Medium · sql and data manipulation
Approach
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- Say which table is the grain you start from, and join outward from it.
- State the window function and its partition and ordering out loud before writing it.
Follow-up
- What breaks if events arrive late or out of order?
- How does the query change if the join becomes one-to-many?
Given an array of integers, find the contiguous subarray with the largest sum.
Medium · sql and data manipulation
Approach
- State the window function and its partition and ordering out loud before writing it.
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
Follow-up
- How would you verify this result without re-running the same query?
- What breaks if events arrive late or out of order?
Count-weighted and dollar-weighted approval rates on one currency
Easy · aggregation · denominators · minor units
Using fct_payment_authorization, report the trailing 7-day authorization approval rate two ways for transaction_currency = 'EUR': count-weighted, and dollar-weighted on amount_minor. Exclude is_reversal = true, exclude incremental authorizations (parent_auth_id not null), and exclude zero-amount account verifications. auth_result = 'approved' is the numerator; the four declined_* values make up the rest of the denominator. Return channel, attempts, approved_attempts, approval_rate_count and approval_rate_value. State every exclusion and its reason before you write the SELECT.
Approach
- Say the denominator out loud first: attempts on a single transaction currency, excluding reversals, incremental authorizations and zero-amount verifications, because none of those is a purchase attempt a merchant is trying to get approved.
- Filter requested_at against a half-open interval (>= start AND < end) so the boundary day is neither dropped nor double counted.
- Compute both rates in one pass with FILTER clauses: COUNT() FILTER (WHERE auth_result = 'approved') over COUNT(), and SUM(amount_minor) FILTER (WHERE auth_result = 'approved') over SUM(amount_minor).
- Cast one side of each ratio to numeric before dividing, since amount_minor and the counts are integers and integer division silently truncates to zero.
- Group by channel and sort by the value-weighted rate, then read the gap between the two rates as a statement about where the declines sit rather than as noise.
Worked solution (20 min)
- Write the exclusion list as comments above the query: is_reversal = false, parent_auth_id is null, amount_minor > 0, transaction_currency = 'EUR'.
- Build a single aggregate query over fct_payment_authorization with a half-open requested_at predicate and those four filters.
- Emit attempts, approved_attempts, approval_rate_count and approval_rate_value with FILTER clauses and a numeric cast on the numerator.
- Group by channel, order by approval_rate_value ascending so the worst channel is on top.
Expected result: One row per channel present in the window, with attempts and approved_attempts as integers and both rates as numerics strictly between 0 and 1. approval_rate_value is typically lower than approval_rate_count on ecommerce and moto, because declines concentrate in higher-value card-not-present traffic.
Verify it yourself
- SUM(attempts) across channels equals a separate COUNT(*) run with the same four filters and no GROUP BY.
- Dropping the amount_minor > 0 filter raises attempts and moves approval_rate_count while leaving approval_rate_value unchanged, which confirms the zero-amount rows were only ever affecting the count-weighted figure.
- Both rates are strictly less than 1 unless a channel had no declines at all in the window.
Follow-up
- The two rates diverge by four points on the ecommerce channel but agree on card_present. What does that tell you, and what would you cut next?
- How would you extend this to all currencies without summing amount_minor across them?
- Which of the four decline reasons belong in the denominator of a rate you would put in front of a risk team, and which are really the network's problem?
Read a segment-sliced result with a fading first-week lift
Medium · multiple comparisons · novelty effects · mix shift
A three-week test of an in-app credit-limit-increase offer had one pre-registered primary metric. The readout also slices 24 secondary segment-by-metric cells, of which three are significant at 0.05 with p-values 0.011, 0.028 and 0.041. The treatment effect on the primary was plus 8.1 percent in calendar week one, plus 3.4 percent in week two and plus 1.5 percent in week three. Say which claims survive, what the decay does and does not prove, and what you tell the sponsor.
Approach
- Compute what chance alone produces before interpreting any cell. With 24 tests at 0.05 the expected number of false positives is 1.2, the probability of at least one is 1 - 0.95^24 = 0.708, and the probability of three or more under an independence approximation is about 0.12. Three hits is an unremarkable outcome, not a signal.
- Apply a stated correction rather than a vibe, and be precise about which one the reported numbers can settle. Holm and Bonferroni both begin at 0.05 / 24 = 0.00208, so the smallest p-value alone decides them. Benjamini-Hochberg sorts all m p-values ascending and finds the largest k with p(k) <= k * q / m; at q = 0.10 and m = 24 the rank-k threshold k / 240 starts at 0.00417 and rises to 0.10 at k = 24, so it is a step-up test over the whole family and its verdict cannot be read off the three cells that happened to fall below 0.05. Ask for all 24 p-values, report the surviving set, which may be empty, and demote the rest to hypotheses for a future test.
- Refuse to call the decay novelty until the competing explanations are ruled out. Three things produce a falling weekly effect: a genuine novelty response from existing users that reverts, a mix shift because week three's exposed population is not week one's, and an effect that is correctly one-shot because a limit increase is taken once per customer.
- Separate them with concrete cuts. Plot the effect against time since first exposure instead of calendar week, which removes the mix shift. Compare users onboarded during the test, who never saw the previous experience and therefore cannot show novelty, against existing users. Hold back a small fraction of traffic for a long-run read.
- Fix the estimand to match the mechanism. For a one-shot offer the meaningful quantity is cumulative take-up per exposed user over a fixed horizon, not a weekly rate, and under that estimand a declining weekly rate is exactly what a working feature looks like.
- Give the sponsor one number with its interval, name the decision it supports, and list the exploratory cells separately under a heading that says they are not results.
Follow-up
- The three significant cells are all in the same segment. Does that change your reading, and how would you test whether it is a real interaction rather than three correlated slices of one population?
- Design the long-term holdback: what size, for how long, and what does it cost you in foregone treatment?
- If cumulative take-up is the estimand, what is the right horizon and how do you keep it from being chosen after seeing the data?
Diagnose a sample ratio mismatch before reading the result
Easy · sample ratio mismatch · instrumentation · chi-square
A two-week test of a new risk rule logged 512,340 exposures in treatment and 508,110 in control against an intended 50/50 split. The dashboard reports a 1.8 percent relative lift in the count-weighted authorization approval rate, p equals 0.004. Exposures are written by the events pipeline at the point the rule is evaluated. Before anyone reads the lift, test whether the split is consistent with 50/50, state your verdict, rank the mechanisms that would produce this imbalance, and say what you do with the two weeks of data.
Approach
- Run the test rather than eyeballing the ratio: a chi-square goodness-of-fit on one degree of freedom against the expected 50/50, or equivalently a binomial test on the treatment share. A 0.42 percent imbalance looks trivial and is not, because at a million exposures the null distribution is extremely tight.
- Declare the result uninterpretable rather than adjusting it. An SRM means units are missing from one arm conditional on something, and the something is usually correlated with the outcome, so reweighting or trimming does not restore exchangeability; it just hides the selection.
- Localise the mismatch before hypothesising about it: recompute the split by day, by channel, by issuer_country and by whether the rule actually fired. An SRM confined to one slice points straight at the code path that produced it.
- Rank mechanisms by how often they are the cause here. First, exposure logged downstream of a step the treatment changes, so any arm-specific drop-off before the log line silently deletes units. Second, assignment keyed on something mutable or nullable, such as card_token_id across a reissue or a null customer_id on guest traffic. Third, bot or fraud filtering applied after assignment and hitting arms unequally. Fourth, retry rows deduplicated after assignment rather than before. Fifth, a ramp or a rollback that moved mid-test.
- Close the loop with an A/A run on the fixed pipeline before rerunning the A/B, and add a continuous SRM check with an alert threshold so the next occurrence is caught on day one instead of at readout.
Worked solution (15 min)
- Total exposures N = 1,020,450, so expected per arm E = 510,225 and the absolute deviation is 2,115 in each direction.
- Chi-square = 2 * 2115^2 / 510225 = 2 * 4,473,225 / 510,225 = 2 * 8.767 = 17.53 on one degree of freedom.
- Convert: sqrt(17.53) = 4.19 standard deviations, so p is about 3e-5. The observed treatment share is 0.50208 against a null standard error of 0.000495, which is the same statement in another form.
- Declare SRM, withhold the 1.8 percent lift from any decision, and produce the per-day and per-channel split table that localises the cause.
Expected result: Chi-square is about 17.5 on one degree of freedom, p is about 3e-5. This is a sample ratio mismatch. The correct output is a defect report with a localisation table, not a treatment effect; the 1.8 percent lift is not reported as a result even with a caveat.
Verify it yourself
- The binomial standard error of the treatment share is sqrt(0.25 / 1020450) = 4.95e-4; the observed share 0.50208 sits 4.19 standard errors from 0.5, matching the chi-square.
- Re-running the same test on the assignment log rather than the exposure log should show a clean 50/50 if the randomiser is sound and the loss is downstream, which immediately narrows the search.
- Summing the per-day chi-square contributions should reproduce the total; a single day dominating the sum is a deploy, not a design flaw.
Follow-up
- Suppose the mismatch is entirely in one issuer_country and the treatment adds a 3-D Secure step there. What is the most likely code path, and what does that imply about the sign of the observed lift?
- What SRM alert threshold would you set for a daily check, and how do you keep it from firing constantly across many concurrent tests?
- If the split is exactly 50/50 but the two arms have different distributions of mcc and channel, is that an SRM? What is it, and what do you do about it?
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
- 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.
- 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.
- 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.
- 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.
- 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
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.
Where your data came from
Data people depend on systems owned by other teams, and much of the job is negotiating for instrumentation, access, or a fix to a broken pipeline. Prepare an example of getting something changed upstream that you did not control. Describe what you asked for, what you traded, and how you worked while you waited.
Describe your experience working with cloud environments. How would you architect a pipeline to train and deploy models using Google Cloud Platform (GCP)?
Medium · behavioural and stakeholder questions
Approach
- Pick a story where you drove the decision, not one where you observed it.
- Name the disagreement or constraint, and how you resolved it with evidence.
- Close with what you would do differently, concretely.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Describe a situation where you identified a business problem that could be solved with data science, took the initiative, and delivered the solution.
Medium · behavioural and stakeholder questions
Approach
- State the situation in two sentences and spend the rest on your reasoning.
- Name the disagreement or constraint, and how you resolved it with evidence.
- 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 would you do differently if you ran that project again?
Allocate one analyst-week across three competing risk requests
Medium · prioritisation · decision deadlines · stakeholder negotiation
Three requests land in the same week and you have one analyst-week. Payments wants a merchant-level decline teardown before a contract renewal in nine days. Credit wants a swap-set analysis on a cutoff change scheduled to ship in six weeks. Insurance wants accident-quarter loss ratios at 12 months development for a reserving review with no fixed date. Each sponsor believes theirs is first, and each has escalated before. Produce the allocation, the reasoning you would say out loud to all three at once, and what you explicitly drop.
Approach
- Score each request on the decision it unblocks rather than on effort or on how loudly it arrived: what changes if it is late, and is that change reversible.
- Separate deadline from value. The nine-day renewal is a hard, irreversible date with a bounded prize; the six-week cutoff has slack but a much larger downside if it ships unmeasured; the reserving number has no date but feeds external reporting, which is its own kind of hard.
- Hunt for the cheap partial in each: a decline teardown restricted to the top merchants by declined value usually answers the contract question at a fraction of the full cut.
- Sequence by hard date first, then by largest irreversible downside, and deliver the trade-off to all three sponsors in one message rather than three, so nobody negotiates privately against a version you told someone else.
- Name what is dropped and who now owns that consequence, in writing, so the trade-off is visible rather than silently absorbed by you.
Follow-up
- The credit sponsor escalates to your manager. What do you change, and what do you refuse to change?
- How would you make this allocation reproducible so the next contested week is a rule application rather than a negotiation?