Here's the problem every HR leader faces: you know people are quitting, but you don't know why, at least not with the rigor you'd bring to a pricing experiment or a marketing A/B test. You can't randomize employees to "high overtime" and "low overtime" conditions just to measure causal effects on attrition. Ethics and employment law prevent the clean experimental designs we prefer. Yet decisions still need to be made: Should you cap overtime? Raise salaries across the board or target specific roles? Invest in manager training or fix work-life balance first?

This article shows how to estimate the adjusted association of each driver with attrition using logistic regression, with a worked example on made-up data so that every number can be reproduced. It also explains where XGBoost with SHAP values fits, and what none of these methods can settle on their own. Upload a CSV and get this analysis free →

Worked Example (Simulated): Does Overtime Go With Leaving?

Question: In this made-up sample, do more staff leave when they work overtime?

Inputs: Simulated data, seed 136. The code makes 1,200 made-up staff rows with three inputs: overtime (yes or no), time on the job, and a team flag. It then sets who left by using chosen odds. The script builds in log-odds of -2.4, plus 0.85 for overtime, minus 0.07 per step of time on the job, plus 0.35 for team. The built-in odds ratio for overtime is therefore e to the power 0.85, about 2.34. These are made-up data, not work records.

Method: First, find the leave rate for each overtime group. Then fit a logistic regression, a model for a yes-or-no result, on overtime, time on the job and team. The code does not scale the inputs, so the number it prints is an odds ratio for overtime with time on the job and team held fixed.

import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression

SEED = 136
rng = np.random.default_rng(SEED)
n = 1200
overtime = rng.binomial(1, 0.30, n)
tenure = rng.integers(0, 16, n)
team = rng.binomial(1, 0.45, n)
log_odds = -2.4 + 0.85 * overtime - 0.07 * tenure + 0.35 * team
prob = 1 / (1 + np.exp(-log_odds))
left = rng.binomial(1, prob)
data = pd.DataFrame(
    {"left": left, "overtime": overtime, "tenure": tenure, "team": team}
)

rates = data.groupby("overtime")["left"].mean()
counts = data.groupby("overtime")["left"].agg(["sum", "count"])
crude_or = (
    counts.loc[1, "sum"] / (counts.loc[1, "count"] - counts.loc[1, "sum"])
) / (
    counts.loc[0, "sum"] / (counts.loc[0, "count"] - counts.loc[0, "sum"])
)
# No penalty and no scaling, so exp(coefficient) is an odds ratio per one step.
model = LogisticRegression(penalty=None, max_iter=1000)
model.fit(data[["overtime", "tenure", "team"]], data["left"])
adjusted_or = float(np.exp(model.coef_[0][0]))

print(f"Simulated data, seed {SEED}")
print(f"Rows: {n}; left: {int(data['left'].sum())}")
print(
    f"Overtime group: {int(counts.loc[1, 'count'])} people; "
    f"{int(counts.loc[1, 'sum'])} left; rate {rates.loc[1]:.3f}"
)
print(
    f"No-overtime group: {int(counts.loc[0, 'count'])} people; "
    f"{int(counts.loc[0, 'sum'])} left; rate {rates.loc[0]:.3f}"
)
print(f"Crude odds ratio, overtime vs no overtime: {crude_or:.3f}")
print(
    "Adjusted odds ratio for overtime (tenure and team held fixed): "
    f"{adjusted_or:.3f}"
)

Printed output:

Simulated data, seed 136
Rows: 1200; left: 103
Overtime group: 348 people; 46 left; rate 0.132
No-overtime group: 852 people; 57 left; rate 0.067
Crude odds ratio, overtime vs no overtime: 2.124
Adjusted odds ratio for overtime (tenure and team held fixed): 2.140

Result: The leave rate is 0.132 for staff with overtime and 0.067 for staff with no overtime. The raw (crude) odds ratio, which compares the two groups' odds, is 2.124. The adjusted odds ratio for overtime is 2.140, close to the crude 2.124, because overtime was drawn apart from the other inputs. The built-in value is 2.34; one run of 103 leavers gives an estimate near it but not equal to it. The estimate carries sampling noise, and the script prints no confidence interval.

Limit: The data follow chosen rules, so they cannot show what happens at work. They also cannot show that overtime makes people leave, because here the rule that made the data is known and a real workplace is not.

Sources

  • Riley R, Ensor J, Snell K, Harrell F, Martin G, Reitsma J, et al. (2020). Calculating the sample size required for developing a clinical prediction model. BMJ. doi 10.1136/bmj.m441. Cited for who published guidance on prediction-model sample size and when.

Why Observational Data Can Still Inform Causal Questions

In experimental design, randomization breaks the correlation between your treatment (e.g., overtime) and confounders (e.g., job level, department). In observational HR data, you don't have that luxury. Instead, you use multivariable regression to statistically control for confounders: "What's the effect of overtime on attrition, holding constant job role, income, years at company, and satisfaction?" The estimates are adjusted associations. They can be read causally only if every relevant confounder is measured and correctly modeled, an assumption the data cannot check, and unmeasured confounding (workload or manager quality, for example) can still bias every coefficient. This is weaker than a randomized experiment.

Sample size matters here. With few attrition events, use a simpler model and state how unsure the result is. Check the result with more data before using it to guide a policy.

The Research Question: Which Retention Levers Might Work?

HR teams drown in correlations: "Employees with low satisfaction quit more." "Overtime workers have higher attrition." "Sales reps leave faster than lab technicians." None of that tells you what to do. The question behind attrition driver analysis is causal: If you intervene on variable X (reduce overtime, raise pay, improve manager quality), what happens to the attrition rate? Observational data can only point to candidates for that question; a pilot answers it.

To answer that, you need to separate signal from noise and correlation from causation. Logistic regression does part of this by estimating the adjusted association of each predictor while holding the others constant. The output is an odds ratio, such as the 2.140 for overtime in the worked example. That points to where to look. Turning it into a forecast, such as the attrition drop from removing overtime, takes extra assumptions that the model does not test.

XGBoost is a tree model for forecasts. SHAP values show how much each input shapes the model's forecasts. They can show patterns and input pairs that a simple straight-line model may miss. Maybe overtime only matters when combined with frequent business travel, or the effect of income changes across its range.

Reading the Odds Ratios

A logistic regression reports each predictor as an exponentiated coefficient (odds ratio). An odds ratio of 1.0 means no association; values above 1.0 raise the odds of attrition, values below 1.0 lower them. If the 95% confidence interval for an odds ratio crosses 1.0, the interval includes no association, so treat that predictor as uncertain. An odds ratio from observational data describes association; it is not a causal effect without further assumptions. Categories with few people, such as a rare job role, give wide intervals and unstable estimates; collapse them into "Other" or exclude them.

Here's how to use an odds ratio: imagine you're designing a retention experiment (or a policy intervention that mimics one). If overtime were the cause, removing it would shrink the odds of attrition by that factor, and you could convert it to a percentage-point change using a baseline rate. That is a scenario, not a forecast: the model shows an adjusted association and cannot say how much attrition would fall. Use the odds ratio to choose where to run a pilot, and let the pilot measure the effect.

The Full Coefficient Table

The full model table should show each estimate, its scale, its error, its test result, and its confidence range. Each row is a predictor; columns show the coefficient (on the log-odds scale), standard error, z-statistic, p-value, and 95% confidence interval. Read the interval first: it shows both the size of the association and how unsure the estimate is. A coefficient of -0.05 per year, for example, means odds multiply by e^(-0.05) per year, about 0.95; the scale matters, so say whether an estimate is per step, per dollar or per standard deviation.

Some predictors will not be significant. For those variables the data did not show a clear association after accounting for the others, which can also reflect limited data or an imprecise estimate. Whether to keep them depends on your goal and model plan; at minimum, don't build retention programs around them on this evidence alone. The goal isn't to include every possible predictor. It's to find the candidate levers (overtime, travel policy, compensation) whose adjusted associations are worth testing in a pilot.

This table shows association, not proof of cause. You can't say "we proved overtime causes attrition" with the certainty of a randomized experiment, but you can say "after adjusting for the other predictors, overtime is associated with higher attrition odds, with this confidence interval." That is strong enough to justify a pilot program capping overtime hours and measuring the downstream attrition change.

XGBoost and SHAP Feature Importance

SHAP (SHapley Additive exPlanations) values measure each feature's contribution to XGBoost predictions, averaged across all employees. XGBoost can pick up non-linear relationships and interactions: threshold effects, diminishing returns, conditional dependencies. A SHAP ranking answers "how much does this feature move predictions, on average?"

Its ranking can differ from the logistic regression ranking. One plausible explanation is that XGBoost picks up a non-linear or interaction effect of a variable that a constant per-unit logistic term cannot. If JobRole and Department rank higher in SHAP than in logistic regression, that may suggest interaction effects, such as a role effect that is stronger together with overtime. Logistic regression estimates an average effect for each role; SHAP shows how that effect varies depending on other features.

Here's the practical takeaway: use logistic regression for your executive summary and policy memos (clear, interpretable odds ratios), then use SHAP to refine targeting. If SHAP shows income has high importance, dig into the distribution: is there an income range where attrition risk changes? If SHAP elevates Age or YearsAtCompany, consider age- or tenure-specific retention bonuses rather than uniform raises.

Overtime by Department: Checking for Interactions

Cross-tabulating Overtime (Yes/No) by Department and filling the cells with attrition rate answers a critical question: Is the overtime effect uniform across departments, or is it concentrated in one area? If overtime-driven attrition is a one-department problem, you'd target overtime reduction there; if it's company-wide, you'd need a universal policy change.

Interaction heatmaps like this are an exploratory check for Simpson's Paradox and confounding; they do not control for it, so follow up with an adjusted analysis such as the regression above. If overtime increased attrition only in one department, you'd suspect confounding: maybe that department hires younger employees who were going to quit anyway, and overtime is correlated but not causal. A gap that appears in every department makes a single-department confounder less likely, but it does not rule out confounding.

How to Interpret Your Results

Translate the numbers into decisions with this framework:

1. Prioritize High-Magnitude, High-Confidence Levers

Look for a large estimate with a tight interval; that is the first thing to test with a pilot. If a variable such as monthly income shows no linear effect in the logistic model, do not assume a pay rise alone will cut attrition. Satisfaction and workload are things you can influence in ways you cannot influence tenure.

2. Distinguish Between Levers You Can Pull and Indicators You Monitor

You can change overtime policy, adjust compensation, and reduce business travel. You can't directly change Age or YearsAtCompany. Those are outcomes of retention, not inputs. If Age or YearsAtCompany rank high in your SHAP plot, that suggests tenure and experience are associated with attrition, which may point toward a focus on early-career retention. But don't write "Age" into your action plan; write "retention bonuses that vest over time" or "structured career ladders for junior roles."

3. Check for Interaction Effects Before Scaling Interventions

If overtime is associated with higher attrition in every department, an overtime cap is a reasonable candidate to pilot everywhere. But if SHAP ranks Department or JobRole high, investigate whether certain roles need tailored interventions. Use SHAP and interaction heatmaps to identify these subgroups, then design A/B tests (or quasi-experiments with matched controls) to test targeted interventions.

4. Build Business Cases with Counterfactual Scenarios

CFOs don't care about p-values; they care about ROI. To size an intervention, convert the odds ratio back to a probability with your own baseline rate (see the pitfall below), multiply by the headcount affected, and price the difference with your own cost per hire. Then subtract the cost of the intervention, such as extra headcount to cover reduced overtime hours. Every input there is yours, and the result assumes overtime causes attrition, so present it as a scenario and let a pilot confirm it before you commit budget.

5. Plan a Pilot (Even If It's Not a True Experiment)

Observational analysis identifies candidates for intervention; it doesn't prove causation with experimental certainty. Once you've chosen a lever (e.g., overtime reduction), implement it in a pilot group and track attrition over a period you set in advance. Ideally, use a matched control group (employees similar in role, tenure, income, but not subject to the policy change) or a staggered rollout (different departments adopt the policy at different times) to approximate experimental conditions. Measure the before-after difference and compare it to what your model implied. If the observed drop is far from the model's scenario, revisit your assumptions: maybe unobserved confounders (manager quality, team culture) were driving the original association.

Correlation vs. Causation: What This Analysis Can and Can't Claim

Can claim: "After adjusting for the other predictors, overtime is associated with higher attrition odds. Piloting an overtime cap is the first intervention this model suggests testing."

Cannot claim: "Overtime definitively causes attrition with the certainty of a randomized experiment." Unobserved confounders (e.g., employees in high-stress projects are assigned overtime and are already disengaged) could bias estimates. Logistic regression assumes you've measured the relevant confounders; if you missed one, the coefficient could be inflated.

Mitigation: Use domain knowledge to include plausible confounders (satisfaction scores, manager tenure, promotion history). Conduct sensitivity analyses: how much would an unobserved confounder need to matter to eliminate the overtime effect? If the answer is "implausibly large," you're on firmer ground.

When Logistic Regression and SHAP Disagree, Investigate Non-Linearities

If logistic regression gives a variable a small odds ratio while the importance ranking puts it near the top, that's not a contradiction. It's a signal to dig deeper. SHAP captures the total contribution of a variable across its full range, including threshold effects and diminishing returns. Logistic regression gives you a single coefficient assuming a constant log-linear effect per unit. If income has a step-function or interaction shape, an importance measure will rank it high because the big change dominates the average, while logistic regression will estimate a modest linear slope that averages over the whole range.

To reconcile, plot attrition rate by income bins. If you see a hockey-stick curve, you've found a non-linearity. Check your own data before acting on it.

Similarly, if SHAP elevates Department or JobRole above their logistic regression ranking, check for interaction effects. Maybe a role has a large SHAP value because its effect depends on overtime. Logistic regression estimates separate main effects for JobRole and OverTime; SHAP can reflect the interaction. Use interaction heatmaps (like Overtime × Department) to surface these patterns, then add interaction terms to your logistic regression to quantify the effect and test significance.

The Statistical Power Question: Could This Be Noise?

Before you commit budget to an overtime reduction program, ask: What's the smallest effect we could reliably detect with this sample? Power analysis answers that. Power depends on the number of attrition events, the baseline rate, and how correlated the predictors are, so run the calculation for your own data. A missed effect in a small sample means low power, not that there is no effect.

If you were analyzing a rare outcome (e.g., attrition among senior executives, where you have few events), you could only detect very large effects. In that scenario, you'd need to either (a) collect more data (wait another year, pool data across divisions), (b) simplify your model (use only a few predictors), or (c) accept that you can only detect very large effects and might miss moderate ones. With few events, focus on univariate comparisons and simple models; resist the temptation to throw many variables into XGBoost and cherry-pick whatever looks significant.

What to Do When You Can't Randomize

Employment law, ethics, and practicality prevent you from randomly assigning employees to "overtime" vs. "no overtime" just to measure causal effects. You're stuck with observational data. Here are three ways to strengthen a causal reading anyway:

1. Propensity Score Matching. Instead of controlling for confounders in a regression, match each overtime employee to a similar non-overtime employee (same role, tenure, income, satisfaction) and compare their attrition rates. This creates balanced groups on the measured variables. If matched overtime employees still have higher attrition, you've strengthened the causal claim for the measured confounders only.

2. Difference-in-Differences. If overtime policy changes over time or varies by department, use a before-after comparison with a control group. Example: one department adopts a no-mandatory-overtime policy while another continues as usual. Compare the attrition trend of the first (before vs. after) to that of the second over the same period. A relative drop is causal evidence, under the assumption that both would have moved together without the policy.

3. Instrumental Variables. Find a variable that affects overtime but doesn't directly affect attrition (an "instrument"). Use the instrument to isolate exogenous variation in overtime. This is advanced and requires strong assumptions that are hard to check.

None of these methods are as clean as a randomized experiment, but they're better than ignoring confounders. Apply them when the stakes are high and you need defensible causal claims for board-level decisions or legal compliance.

Common Pitfalls and How to Avoid Them

Pitfall 1: Treating Prediction Accuracy as Evidence of Causal Validity

A model can predict well who quits and still not identify causal drivers. Maybe it's picking up on proxies: "employees who update their LinkedIn profiles quit more", true, but changing LinkedIn isn't a lever you can pull. Focus on interpretable models (logistic regression) and test causal claims with domain knowledge and quasi-experimental designs.

Pitfall 2: Ignoring Base Rates When Interpreting Odds Ratios

An odds ratio multiplies the odds, not the risk, so it translates differently depending on baseline attrition. With a 1% baseline, an odds ratio of 4 gives about 3.9% attrition, still low. With a 40% baseline it gives about 73%, not 160%, which is why an odds ratio must not be read as a risk multiplier. Always convert odds ratios back to probabilities using the baseline rate: P(attrition | overtime) = baseline × OR / (1 + baseline × (OR − 1)). Use the baseline for the group you are asking about, not the overall rate.

Pitfall 3: Over-Controlling and Washing Out Real Effects

If you include too many correlated predictors, you risk "controlling away" the effect you care about. Example: if you add "employee engagement score" (which is probably caused by overtime), you'll underestimate the overtime coefficient because engagement mediates the effect. Solution: draw a causal diagram (DAG) to distinguish confounders (variables that cause both overtime and attrition) from mediators (variables caused by overtime that then cause attrition). Control for confounders; don't control for mediators if you want the total effect of overtime.

Pitfall 4: Using Attrition Analysis to Justify Layoffs

Attrition driver analysis identifies retention levers, variables that predict voluntary quits. Do not use it to predict "who should we fire?" That's a different problem (performance prediction) with different ethics and legal constraints. If you build a "flight risk score" to preemptively terminate high-attrition employees, you'll face wrongful termination lawsuits and destroy trust. Use these models to retain talent, not to preempt it.

Your turn

Bring your own data and the question you actually need answered.

MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai

Frequently Asked Questions

Why can't you run a randomized experiment on employee attrition?

You can't ethically or practically randomize employees to "high overtime" vs. "low overtime" conditions just to measure attrition. HR analytics relies on observational data. You measure what actually happened, adjust for confounders statistically, and look for patterns worth testing. Logistic regression and SHAP values estimate the adjusted association of each driver after accounting for correlations, which is not proof that changing a driver changes attrition.

What's the difference between logistic regression odds ratios and SHAP values?

Logistic regression gives you directional, interpretable coefficients. In the worked example above, overtime has an adjusted odds ratio of 2.140 with time on the job and team held fixed. It assumes each input acts in a straight line on the log-odds scale. XGBoost is a tree model for forecasts. SHAP values show how much each input shapes the model's forecasts. They can show patterns and input pairs that a simple straight-line model may miss. Use logistic regression for clear talking points; use SHAP when you suspect thresholds or interaction effects.

How large a sample do you need for employee attrition analysis?

There is no single number. The data and the model set the sample size, and Riley and co-authors published guidance on prediction-model sample size in BMJ in 2020 (see Sources). With few events, use a simpler model and state how unsure the result is. Check the result with more data before using it to guide a policy.

Should you treat attrition analysis as a prediction problem or a causal inference problem?

Both, but start from the causal question. Predictive accuracy (AUC, precision/recall) tells you if you can forecast who quits. Logistic coefficients and propensity matching give adjusted associations that suggest which levers to test, but they do not show that pulling a lever changes attrition. Most HR teams care about the second question: if we reduce mandatory overtime in one department, does attrition fall? Treat the model as a way to choose a pilot that can answer it, then build risk scores for targeting interventions.

What do you do when SHAP and logistic regression disagree on which variables matter?

Investigate interaction effects and non-linearities. If SHAP ranks "MonthlyIncome" higher than logistic regression does, check for threshold effects (plot attrition rate by income band to see whether any exist). If SHAP ranks "Department" higher, look for Department × Overtime interactions. Use logistic regression for your executive summary; use SHAP to find the nuances that justify targeted programs.

Final Takeaway: From Correlation to Action

Employee attrition analysis shows what rigorous observational analysis looks like when experiments are off the table. You can't randomize overtime, but you can control for confounders statistically, estimate adjusted associations with logistic regression, look for non-linearities with XGBoost SHAP, and check for interactions with segment-level heatmaps. The result isn't proof of causation, that requires an experiment, but it's evidence that can justify a pilot program.

Upload your own employee data (attrition status, job role, salary, tenure, overtime, satisfaction scores) and run this analysis. You'll get logistic regression odds ratios, SHAP feature importance, segment attrition rates, and interaction heatmaps. Just clean data and a question: which retention levers might work?