As a Data Scientist at Lyra Health, you are at the intersection of clinical excellence and advanced computational modeling. You will work on high-impact initiatives that directly improve mental health outcomes for millions, translating complex health data into actionable insights that guide product strategy and patient care.
Your work is central to Lyra Health’s mission. Whether you are optimizing provider matching algorithms, measuring the efficacy of digital interventions, or designing experiments to improve patient engagement, your technical output directly influences the business’s ability to scale high-quality care. You will collaborate closely with Product Managers, Engineers, and Clinical Leads, making this role a blend of rigorous technical execution and cross-functional leadership.
Preparation focus
editorialNo 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
PracHub editorial advice for the preparation topics above.
Ignoring clustering by provider, facility, or site
Patients within a provider panel, and subjects within a trial site, are correlated on both case mix and practice pattern. Standard errors computed as if observations were independent are too narrow by roughly the design effect, 1 + (m - 1) * ICC, where m is the average cluster size. With 50 patients per provider and an intracluster correlation of only 0.02, variance is understated by about a factor of two, which manufactures significant provider differences out of noise. Cluster-robust errors or a random intercept per provider, and cluster-level randomisation when you design the test, are the corrections.
Treating clinical measurements as missing at random
A lab result, a vital sign, or a screening exists because someone ordered it, and ordering tracks suspicion of disease, visit frequency, and site workflow. Imputing the mean or dropping incomplete rows biases the population estimate and can flip the sign of an association, because the untested are systematically healthier or systematically disengaged. The presence indicator is often more predictive than the value, which is a warning sign rather than a feature win: a model that learns test ordering will not transfer to a site with different protocols.
Accepting a metric definition without asking about the denominator
Pin down the denominator, the eligibility filter and the time window before computing anything: conversion rate per session, per user, per eligible user and per new user are four different numbers with different behaviour. Restate the definition in one sentence and get agreement before you analyse.
Analysing at a different unit than the one randomised
Say out loud what was randomised (user, device, account, cluster) and make the analysis unit match, or account for the clustering with cluster-robust standard errors, the delta method, or aggregation up to the randomised unit. Randomising users and then running a test over sessions understates variance and inflates the false-positive rate.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Collapse claim versions before summing allowed amounts by member
You are given medical_claim_line as a pandas DataFrame: claim_line_id, claim_id, claim_version, frequency_code (1 original, 7 replacement, 8 void), member_id, service_start_date, procedure_code, allowed_amount, claim_status. Return total allowed_amount per member for service dates in one stated calendar month, counting each claim once at its surviving version and excluding any claim whose surviving version is a void. Multi-line claims must keep every line of that surviving version. Output columns: member_id, allowed_amount, sorted descending. Do not deduplicate on claim_id alone.
Approach
- Separate the two grains out loud before writing code: versions live at the claim level, dollars live at the line level. Every bug in this exercise comes from mixing them.
- Compute the surviving version per claim with a groupby transform of max over claim_version, then keep the lines whose claim_version equals that value. A transform keeps the frame at line grain, which a sort plus head(1) does not.
- Drop whole claims whose surviving version carries frequency_code 8. A void is not a zero-dollar line, it retracts the claim, so filtering rows rather than claims leaves the prior version's lines behind.
- Filter to claim_status 'paid' and state the assumption: denied, pended and reversed lines carry an allowed_amount that never became a liability, so including them overstates cost.
- Restrict service_start_date to the month boundaries, then groupby member_id and sum. Sort descending and return.
Worked solution 20 min
- Build a max-version lookup per claim_id with groupby('claim_id')['claim_version'].transform('max') and keep rows where claim_version equals it.
- From the surviving rows, collect the claim_ids whose frequency_code is 8 and drop those claim_ids entirely.
- Filter claim_status to 'paid' and service_start_date into the month window.
- Group by member_id, sum allowed_amount, sort descending, reset the index.
Follow-up
- A claim has versions 1, 7, 7 where the second replacement has fewer lines than the first. What does your code return and is that correct?
- How would you handle a claim whose lines span two calendar months at the boundary of the reporting window?
- The same logic has to run over 400 million lines in a warehouse. What changes, and what stays the same?
Simulate how ignoring clustering inflates the false positive rate
Simulate a provider-level comparison with no true effect. 40 providers, 60 members each, a continuous outcome with total variance 1 and intraclass correlation 0.02. Randomise providers 20 to 20, not members. Over 5,000 replications, report the share of replications where a two-sample t-test run on all 2,400 individual observations, ignoring provider, returns p below 0.05. Report the same share when the unit of analysis is the 40 provider means. Then state how the first number follows from the design effect 1 + (m - 1) x ICC.
Approach
- Decompose the variance explicitly rather than tuning it: provider variance = ICC = 0.02, residual variance = 1 - ICC = 0.98. Draw u_j once per provider and e_ij per member, so the outcome is u_j + e_ij and the correlation between two members of one provider is 0.02 by construction.
- Randomise at the provider level. That is the entire mechanism: the treatment indicator is constant within a provider, so in any single replicate the provider intercepts are confounded with the arm, and the naive test reads that confounding as signal.
- Vectorise over replications with a (reps, providers, members) array. 5,000 x 2,400 normals is trivial in numpy, and a Python loop is what tempts people to cut replications to 500 and report a number with Monte Carlo noise of plus or minus 0.017.
- Predict the answer before running it: design effect = 1 + (60 - 1) x 0.02 = 2.18, naive standard errors are too small by sqrt(2.18) = 1.476, so the rejection rate at nominal 0.05 is about 2 x (1 - Phi(1.96 / 1.476)) = 0.18. Agreement between prediction and simulation is what makes the result a demonstration rather than an anecdote.
- Run the provider-mean analysis as the control. Recovering 0.05 there proves the generator is correct and isolates the failure to the analysis unit.
Follow-up
- How many providers would you need for 80 percent power on a 0.2 SD difference with 60 members each and this ICC?
- Cluster sizes are unequal in reality. The design effect approximation becomes 1 + ((1 + CV^2) x mbar - 1) x ICC. Which direction does that move your sample size and why?
- The intervention cannot be withheld from any provider. Sketch a design that still yields a defensible estimate.
Proportion of days covered with shifted, truncated refill intervals
pharmacy_claim has fill_id, member_id, therapeutic_class_code, fill_date, days_supply, reversal_flag, reversed_fill_id. For one therapeutic class and a fixed 12-month window, compute proportion of days covered per member: distinct days on which a dispensed days_supply covers the day, divided by days from the member's first in-window fill through the window end. An early refill shifts coverage forward rather than stacking, and coverage is truncated at the window end. Drop both rows of every reversed pair. Return member_id, pdc, and the share at pdc >= 0.80 among members with at least 2 fills and at least 91 days of follow-up.
Approach
- Remove reversals as pairs first. Drop every row with reversal_flag true, and also drop the fill_ids those rows point at through reversed_fill_id. Dropping only the flagged row leaves a dispense that was never collected in the exposure.
- Walk fills per member in fill_date order carrying a cursor: start = max(fill_date, previous_end + 1 day), end = start + days_supply - 1. The shift is path dependent, so a plain cumsum over days_supply does not reproduce it. Use itertools.accumulate or a per-member loop over numpy arrays, not a row-wise apply over the whole frame.
- Truncate the last interval at the window end before measuring. Without truncation a 90-day fill dispensed on the final day pushes the covered-day count past the denominator and PDC above 1.0.
- Use the denominator the definition states: first in-window fill_date through window end, inclusive. Not a flat 365, and not first fill to last fill, which is a different metric that rewards early discontinuation.
- Apply the eligibility filter before computing the >= 0.80 share, and report the size of that denominator next to the share. A share without its denominator is not reviewable.
Follow-up
- How does PDC differ from medication possession ratio, and which of the two can exceed 1.0?
- A member switches to a different ingredient inside the same therapeutic class mid-window. Should the intervals chain, and what does that do to the class-level number?
- Members who die or lose coverage mid-window get a short denominator and often a high PDC. If you then compare mortality by adherence category, what bias have you built in and how do you remove it?
How would you structure a SQL query to identify patient churn patterns…
How would you structure a SQL query to identify patient churn patterns given this specific table schema?
Approach
- Say which table is the grain you start from, and join outward from it.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
- 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 would you verify this result without re-running the same query?
How do you optimize a query that is running slowly on a large database…
How do you optimize a query that is running slowly on a large database?
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- State the window function and its partition and ordering out loud before writing it.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
Follow-up
- How does the query change if the join becomes one-to-many?
- What breaks if events arrive late or out of order?
Can you explain the difference between window functions and joins in a…
Can you explain the difference between window functions and joins in a real-world analytics scenario?
Approach
- 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.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
Follow-up
- How does the query change if the join becomes one-to-many?
- What breaks if events arrive late or out of order?
Given a dataset with missing values, how would you approach data clean…
Given a dataset with missing values, how would you approach data cleaning and imputation?
Approach
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
- 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?
Deduplicate claim versions before totalling allowed amounts
medical_claim_line holds one row per service line per claim version: claim_line_id, claim_id, claim_version, frequency_code (1 original, 7 replacement, 8 void), member_id, service_start_date, procedure_code, allowed_amount, claim_status and adjudicated_at. Adjusted claims appear more than once, so summing every row double counts them. Return total allowed_amount by procedure_code for service_start_date in Q1 2025, counting only lines with claim_status 'paid' on the surviving version of each claim, which is the highest claim_version per claim_id, and dropping the claim entirely when that surviving version carries frequency_code 8. Resolve survivorship with a window function, not a self-join.
Approach
- Resolve survivorship at claim_id, not claim_line_id. Carry MAX(claim_version) OVER (PARTITION BY claim_id) alongside every line and keep lines where claim_version equals it, because a replacement version can contain a different number of lines than the original.
- Read the frequency_code of the surviving version only. A frequency_code 8 removes the claim outright; it does not revert payment to the prior version, so a void must delete the claim rather than promote version n-1.
- Apply claim_status and the date filter after survivorship is resolved. Filtering paid lines first can strip the surviving version and silently elect a superseded one.
- Group by procedure_code and sum allowed_amount, then state the paid-through date on the output because Q1 amounts keep moving until adjudication runout completes.
- Sanity check the shrinkage: report how many claim_ids and how many dollars the dedup removed, so the reviewer can see the step did something.
Worked solution 20 min
- Build a CTE that adds surviving_version = MAX(claim_version) OVER (PARTITION BY claim_id) and surviving_freq = the frequency_code of the row at that version, to every line.
- Filter to claim_version = surviving_version so all lines of the surviving version survive together.
- Drop claims whose surviving_freq is 8, then apply claim_status = 'paid' and service_start_date between 2025-01-01 and 2025-03-31.
- Group by procedure_code, sum allowed_amount, and emit the count of distinct claim_ids contributing.
- Run the naive SUM over all rows beside it and report the difference as the double count that was removed.
Follow-up
- Two rows share a claim_id and claim_version but differ on adjudicated_at. What do you do, and what does that imply about the extract?
- How does the query change if the request is allowed_amount by paid_date rather than service_start_date, and which basis does a finance reconciliation want?
- A void arrives for a claim already published in a closed month. How do you restate without rewriting history in the warehouse?
Write a function to calculate the lift of a marketing campaign compare…
Write a function to calculate the lift of a marketing campaign compared to a control group.
Approach
- State the primary metric and the minimum effect worth shipping, then size the test.
- Name the guardrails that would stop a launch even on a positive primary result.
- Say whether units interfere with each other, and switch design if they do.
Follow-up
- What would you do if you could not randomise at all?
- How would you handle interference between treated and control units?
Evaluate a book-wide benefit change with no untreated members
On 1 January a therapeutic class moves from formulary tier 2 to tier 3, raising member cost share, for the entire commercial group book at once. No untreated subset of that book exists. You have 36 months of pharmacy_claim and member_enrollment covering that book plus the Medicare Advantage and Medicaid managed books, which are unaffected. Outcomes are class fills per 1,000 member-months and the share of members with PDC at or above 0.80. Give the design, the identifying assumption, and how you would test it.
Approach
- Rule out the single-series interrupted time series first and say why. The change lands on 1 January, which is also when deductibles reset, benefit designs change, and members switch plans, so a level shift at the new year is confounded with the entire annual benefit cycle. Any design that cannot separate those two is not usable here.
- Build an event-study difference-in-differences with the unaffected product books as controls, estimating month-by-month coefficients relative to December. The lead coefficients are the test of the identifying assumption, not decoration: they should be indistinguishable from zero, and you should say in advance what magnitude of lead violation would make you abandon the design.
- State what the control books are doing for you and what they are not. They experience the same January reset, which is precisely why they are useful, but they differ in population age, cost-sharing structure, and eligibility churn, so parallel counterfactual trends is a real assumption and residual confounding should be named rather than waved at.
- Add a synthetic control as the robustness check: construct a weighted combination of donor series (other product books crossed with other therapeutic classes) that tracks the treated series through the pre-period, and do inference by permutation, assigning the intervention to each donor and comparing post-to-pre RMSPE ratios. Require that the treated pre-period sits inside the convex hull of the donors, and abandon the approach if pre-period fit is poor.
- Fix the population before estimating anything. If the tier move pushes members out of the book, the post-period population differs from the pre-period one, so restrict to members continuously enrolled across the window with a stated allowable gap, and report sensitivity to that gap. Note that pharmacy claims adjudicate in days, so unlike a medical-cost series this outcome is essentially complete within weeks.
Worked solution 45 min
- Build a monthly panel of fills per 1,000 member-months and PDC share by product book, restricted to members continuously enrolled across the window with a 45-day allowable gap.
- Plot the treated and control series for 24 pre-period months and inspect visually before fitting anything.
- Estimate an event-study DiD with month-relative-to-January coefficients, product fixed effects, and calendar-month fixed effects, clustering standard errors at the product-book level or higher.
- Run the placebo: re-estimate as if the change happened on the prior 1 January, which isolates the annual reset from the tier move.
- Fit a synthetic control on donor product-class series, check pre-period RMSPE, and run the permutation inference across donors.
Follow-up
- The lead coefficients are not flat: the treated book was already drifting down for six months. What do you do without abandoning the question?
- Therapeutic substitution is expected. How do you tell a true reduction in therapy from members moving to a cheaper drug in the same class?
- How would you report the result so a clinical committee can act on it, given that fills per 1,000 member-months is not an outcome anyone treats?
Pooled persistency fell but no one lost coverage
Pooled 12-month enrollment persistency fell from 0.78 to 0.66 for the cohort anchored in a single month. member_enrollment carries span_id, member_id, plan_id, product_type, effective_date, termination_date, termination_reason_code, dual_eligible_flag and region_code. The metric allows at most one gap of 45 days or fewer. Product mix in that anchor month was not stable. Determine how much of the fall is real disenrollment rather than span bookkeeping or mix, and deliver a persistency series a contract owner could act on.
Approach
- Inspect the query's unit of analysis first. Spans are not members, and a benefit or plan change closes one span and opens the next on the same day, so any logic that treats a non-null termination_date as loss of coverage counts an administrative event as churn.
- Rebuild member-level coverage by unioning all spans per member and merging adjacent or overlapping ones, then apply the 45-day gap rule to the merged intervals rather than per span.
- Cut the terminations by termination_reason_code. plan_change and eligibility_redetermination have entirely different meanings for a contract, and death is not churn you can address.
- Split by product_type and stop pooling. Commercial open enrollment and managed medicaid redetermination produce structurally different churn on different calendars, and the pooled average of the two is a number that describes nobody.
- Compare the anchor month to the same month in the prior year rather than to the adjacent month, because enrollment is strongly seasonal and an anchor month sitting on an open-enrollment or redetermination boundary is not comparable to its neighbour.
- Apply the Kitagawa decomposition across product_type to separate how much of the 12 point fall is mix, meaning the anchor cohort simply contained more of a high-churn product, from how much is within-product deterioration.
Follow-up
- Why 45 days, and what would change if the allowable gap were 30 or 60?
- A member terminates and re-enrolls 90 days later under a different plan_id. Are they retained? Defend your answer against the opposite one.
- What guardrail would catch someone improving persistency by declining to enroll members likely to churn?
For someone who has spent the last year in notebooks, dashboards or modelling work and has not written raw SQL under time pressure. The first four days rebuild query fluency against a fixture you control and can verify by hand; the last three attach that fluency to the rest of the loop.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Build a fixture you can check answers against
- Create a local Postgres or SQLite database with four tables (users, sessions, events, orders) holding roughly 200 rows you generated yourself, so you know the contents well enough to predict every result.
- Deliberately seed the cases that break queries: a user with no sessions, a session with no events, two orders sharing a timestamp, a NULL in one join key, and one duplicated user row.
- Before writing any SQL, hand-compute five answers on paper (how many users placed at least one order, median orders per ordering user, and three others) and save them as the ground truth for the week.
Deliverable: A one-command seed script plus a text file of five hand-computed answers to grade every later query against.
Practice prompt ↗Practice prompt ↗Worked solution ↗02Joins, filters and NULL semantics
- Answer "which users have no orders" three ways (LEFT JOIN with IS NULL, NOT EXISTS, NOT IN) and confirm that the NOT IN version returns zero rows once the subquery contains a NULL, because the comparison is never TRUE.
- Reproduce the LEFT JOIN that silently collapses to an inner join by putting a right-table predicate in WHERE, then fix it by moving the predicate into the ON clause, and record both row counts.
- Create a fan-out bug on purpose by joining orders to order_items and summing the order total, then correct it with a pre-aggregated subquery and explain in one line which table changed the grain.
Deliverable: One annotated .sql file holding the three join traps, each with the wrong result and the corrected result side by side.
Practice prompt ↗Practice prompt ↗03Window functions and frames
- Write three window queries against the fixture: a running order total per user, the rank of each order within its user by value, and the day gap to that user's previous order, then check each against the day-one ground truth.
- Run ROW_NUMBER, RANK and DENSE_RANK over a column containing ties, print all three side by side, and write one sentence on when each is the correct choice.
- Switch one query from the default frame (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, which is what you get when ORDER BY is present and no frame is written) to ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and explain why the output differs only when the ORDER BY column has duplicates.
Deliverable: Three verified window queries plus a short note explaining the RANGE versus ROWS difference in your own words.
Practice prompt ↗Practice prompt ↗04The four analytical query patterns
- Write a monthly retention grid: first order month per user, then months-since-first as the column, and verify that month zero equals the cohort size exactly.
- Sessionize the events table under a 30-minute inactivity rule using LAG plus a cumulative sum over a new-session flag.
- Build a four-step funnel that counts distinct users rather than events at each step, and state the rule you applied to a user who reaches step three without ever logging step two.
Deliverable: One file with the retention, sessionization and funnel patterns, each carrying a one-line note on the assumption it bakes in.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Write SQL the way you will have to write it live
- Set a 12-minute timer and solve three medium prompts in a plain editor with no execution and no autocomplete, then run them and tally syntax errors separately from logic errors.
- Narrate one solution aloud while writing it, stating the grain of each intermediate result (one row per user, one row per user-day) before you type its body.
- Rewrite your slowest solution as a CTE chain where every CTE name states its grain, and time yourself re-solving it from blank.
Deliverable: A recording of one narrated solution plus an error tally that separates syntax from logic.
Practice prompt ↗Practice prompt ↗06One day for everything that is not SQL
- Write the preconditions of the two-sample t-test from memory, then check them: independent observations, and a difference in means whose sampling distribution is approximately normal, which at large sample sizes follows from the central limit theorem rather than from normality of the raw values.
- Write the difference between an odds ratio from logistic regression and a relative risk, and state the condition under which the two are close (low outcome prevalence).
- Prepare a 90-second answer to "how would you know this model is any good" that names the metric, the baseline you would beat, and the cost of the errors you care about.
Deliverable: One page of notes covering test preconditions, the odds-ratio caveat and the model-quality answer.
Practice prompt ↗Practice prompt ↗07Full loop rehearsal
- Run a 45-minute mock with someone willing to interrupt: 20 minutes of SQL, 15 minutes defining a metric, 10 minutes on a past project.
- Re-solve from blank the two queries you were slowest on this week and compare the times against day five.
- Write a five-line answer to "walk me through a project" that puts a number in the first sentence and names the decision the work changed.
Deliverable: Mock feedback notes plus a timed project narrative you can deliver without reading it.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
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.
Disagree with a product manager about an adherence nudge
A product manager proposes shipping a refill-reminder feature to the whole member base, citing an internal analysis: members with 12-month proportion of days covered at or above 0.80 had 31 percent fewer admissions than members below it. The roadmap date is three weeks out and engineering is scoped. You believe the comparison builds survival and continuous coverage into the exposure definition, and is separately confounded by the kind of member who refills on time. Deliverable: what you say in the room, what you send afterwards, and the smallest study you would accept as sufficient to ship.
Approach
- The probe is whether you can be specific and non-territorial at once. A disagreement that arrives as 'the analysis is flawed' costs you the room; one that names a mechanism and offers a cheaper path keeps it.
- Name the two defects separately, because they have different fixes. Classifying a member as adherent over 12 months requires them to stay alive and stay covered for those 12 months, and that guaranteed event-free interval is assigned to the adherent group. Separately, members who refill on schedule differ from those who do not in ways claims never record.
- Show rather than assert. Rerun the same comparison as a landmark analysis: classify adherence over days 1 to 90, start follow-up at day 91 for everyone still enrolled and event-free, and report how much of the 31 percent survives.
- Separate the association claim from the intervention claim out loud. Nothing in the analysis speaks to whether a reminder changes refill behaviour, which is the actual product question and is separately testable.
- Offer the shippable path: a randomised holdout on a subset with proportion of days covered as the primary endpoint, powered on the plausible effect of a reminder rather than on the 31 percent, with a stated read date.
Follow-up
- The landmark rerun still shows a 20 percent difference. Do you ship?
- The product manager says a holdout delays launch. How do you cost that argument?
- What primary endpoint do you choose, and why not admissions?
Sequence three urgent requests with one analyst-week available
Three requests land on Monday and you have one week. An actuarial team needs incurred-claims completion factors restated before a filing deadline on Thursday. A clinical programme owner wants a deterioration model refreshed because its calibration has drifted in one region. A trial operations team wants site enrolment forecasts for a portfolio review in two weeks. Each requester believes theirs is blocking. Deliverable: your sequence with the reasoning, the message you send to whoever is deprioritised, and the smaller artefact you hand each of the two you cannot fully serve.
Approach
- The probe is whether you prioritise on consequence and reversibility rather than on who asked loudest or most recently.
- Classify each request by what happens if it slips. A regulatory or contractual deadline is irreversible on its date, a drifting model is causing harm every day it keeps running, and a portfolio review can absorb a provisional number. That ordering is defensible to all three requesters because it does not depend on your preferences.
- Take the deadline-bound work first, but scope it to the minimum defensible output, because completion factors feeding a filing carry a different error tolerance than a slide.
- Do not let the drifting model simply wait. Quantify the harm cheaply by comparing calibration in the affected region against the rest, and if it is materially miscalibrated propose flagging or suppressing its output for that region within the hour rather than at the end of a refresh.
- Give each deprioritised requester something real: a provisional forecast with its uncertainty and a refresh date, or a diagnostic that tells them whether their problem is urgent. Say no explicitly with a date rather than going quiet, because silence is what produces escalation.
Follow-up
- The programme owner escalates to your manager. What do you want your manager to be able to say?
- Midweek the actuarial work needs two more full days than you estimated. What gives?
- How does your answer change if the drifting model drives a clinical outreach list rather than a report?
Explain an incomplete cost series to a non-technical executive
An executive opens a dashboard showing risk-adjusted allowed PMPM down 6 percent across the last three incurred months and asks whether the cost initiative is working. You know pharmacy adjudicates within days, professional claims within weeks, and inpatient facility claims over months, so those three months are both undercounted and mix-shifted toward cheap services. There is also a genuine movement of roughly 1.5 percent in the older, complete months. Deliverable: a two-minute spoken answer, the change you make to the chart, and what you commit to telling them and when.
Approach
- The probe is whether you can be honest about uncertainty without sounding evasive. Executives read hedging as not knowing, so the answer has to end in a commitment.
- Separate the two claims immediately. The 6 percent is an artefact of incomplete data, and there is a smaller real movement in the months that are complete. Delivering only the debunk leaves them holding nothing.
- Explain the lag in their terms: the bills for the most expensive care arrive last, so an incomplete month always looks cheap and always looks like it is improving. Keep the phrase completion factor out of the first pass.
- Fix the chart instead of explaining around it. Shade or omit the incomplete months, print the paid-through date on the axis, and overlay the same series as it looked at equivalent maturity a year earlier so the shape is comparable rather than merely lower.
- Close with a date and a magnitude. Commit to a restated figure once runout matures, say roughly how far you expect the 6 percent to shrink, and name what you would need to see to call the initiative working.
Follow-up
- They ask for your best guess today, knowing it is provisional. What do you say?
- The restated number comes back at 1 percent. How do you handle having flagged the 6 percent at all?
- How do you stop this dashboard producing the same conversation next quarter?
- 01
A product manager proposes shipping a refill-reminder feature to the whole member base, citing an internal analysis: members with 12-month proportion of days covered at or above 0.80 had 31 percent fewer admissions than members below it. The roadmap date is three weeks out and engineering is scoped. You believe the comparison builds survival and continuous coverage into the exposure definition, and is separately confounded by the kind of member who refills on time. Deliverable: what you say in the room, what you send afterwards, and the smallest study you would accept as sufficient to ship.
- 02
Three requests land on Monday and you have one week. An actuarial team needs incurred-claims completion factors restated before a filing deadline on Thursday. A clinical programme owner wants a deterioration model refreshed because its calibration has drifted in one region. A trial operations team wants site enrolment forecasts for a portfolio review in two weeks. Each requester believes theirs is blocking. Deliverable: your sequence with the reasoning, the message you send to whoever is deprioritised, and the smaller artefact you hand each of the two you cannot fully serve.
- 03
An executive opens a dashboard showing risk-adjusted allowed PMPM down 6 percent across the last three incurred months and asks whether the cost initiative is working. You know pharmacy adjudicates within days, professional claims within weeks, and inpatient facility claims over months, so those three months are both undercounted and mix-shifted toward cheap services. There is also a genuine movement of roughly 1.5 percent in the older, complete months. Deliverable: a two-minute spoken answer, the change you make to the chart, and what you commit to telling them and when.
Is this an official Lyra Health interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Lyra Health. Rounds and questions reflect what candidates have reported, not a process Lyra Health has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult are the technical interviews?
They are considered challenging and require a strong grasp of both fundamentals and applied problem-solving. Expect the technical depth to be high, especially regarding statistical concepts and SQL efficiency.
PracHub interview research ↗What is the focus of the final round?
The final round is often a mix of behavioral assessments and a case study presentation. It is designed to ensure you are a cultural fit and that you can communicate your technical work effectively to a broad, cross-functional audience.
PracHub interview research ↗Is there a specific emphasis on machine learning?
While machine learning is used, the core of the role is often rooted in rigorous statistical analysis, causal inference, and product analytics. Focus on mastering these foundational areas first.
PracHub interview research ↗How long does the process take?
While it varies, the process is generally efficient. Candidates have reported receiving timely communication, often within days of their technical interviews.
PracHub interview research ↗Sources & methodology 3 sources ↗
No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
PracHub page · Accessed 2026-09-22 - 02PracHub Data Scientist practice ↗
Cross-company practice questions for this role.
PracHub page · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
PracHub page · Accessed 2026-09-22