Imagine your clinic screened a group of patients for diabetes and recorded several measurements for each: glucose, blood pressure, BMI, age, and so on. Now the question: which of these measurements actually predicts who has diabetes? And by how much?
This is where most analyses go wrong. Clinicians eyeball correlations, compare group means, or worse: treat every biomarker as equally important. But correlation isn't prediction. A variable can look impressive in a t-test and contribute nothing once you control for other factors. Before you build a risk score, screen patients, or design an intervention, you need to know which predictors carry independent signal.
That's what diabetes risk factors analysis does. It's logistic regression with a focus: rank biomarkers by their independent predictive power, quantify each one's effect as an odds ratio, and evaluate how well the combined model classifies patients. You're not asking "are diabetics different?". You're asking "which measurements, holding all others constant, predict diabetes, and by how much?"
Here's how to run a proper analysis, interpret the results, and avoid the methodological traps that make most risk models unreliable in practice.
Worked Example: Four Made-Up Measures and a Yes/No Result
Question: In made-up patient data, how well can four inputs rank a yes/no result?
Inputs: Simulated data, seed 2026. The script makes four standardized measures and a yes/no result for 600 cases, then a random 70/30 train/test split. The script builds in these effects on the log-odds: intercept -0.25, and effects of 0.85, 0.55, 0.00 and -0.35 for measures 1 to 4. Measure 3 has no effect by design. Exponentiated, the built-in odds ratios per SD are about 2.34, 1.73, 1.00 and 0.70.
Method: Fit a logistic model (links inputs to a yes/no result) on the train rows. Show odds ratios (odds of yes) for a one SD (unit of spread) change. Check AUC (a rank score) and the share right on the test rows.
import numpy as np
SEED = 2026
rng = np.random.default_rng(SEED)
n = 600
# Four simulated, standardized measures and a binary outcome.
X = rng.normal(size=(n, 4))
beta = np.array([0.85, 0.55, 0.0, -0.35])
intercept = -0.25
logit = intercept + X @ beta
prob = 1.0 / (1.0 + np.exp(-logit))
y = rng.binomial(1, prob)
# Make a reproducible random train/test split.
order = rng.permutation(n)
cut = int(0.7 * n)
train_idx, test_idx = order[:cut], order[cut:]
X_train, y_train = X[train_idx], y[train_idx]
X_test, y_test = X[test_idx], y[test_idx]
# Fit logistic regression by Newton updates, with an intercept and no penalty.
A_train = np.column_stack([np.ones(len(X_train)), X_train])
coef = np.zeros(A_train.shape[1])
for _ in range(100):
z = A_train @ coef
p = 1.0 / (1.0 + np.exp(-z))
w = np.clip(p * (1.0 - p), 1e-9, None)
grad = A_train.T @ (y_train - p)
hessian = (A_train.T * w) @ A_train
step = np.linalg.solve(hessian, grad)
coef += step
if np.max(np.abs(step)) < 1e-10:
break
A_test = np.column_stack([np.ones(len(X_test)), X_test])
test_prob = 1.0 / (1.0 + np.exp(-(A_test @ coef)))
test_pred = (test_prob >= 0.5).astype(int)
accuracy = np.mean(test_pred == y_test)
# AUC as the probability a positive test case ranks above a negative one,
# with half credit for tied scores.
pos = test_prob[y_test == 1]
neg = test_prob[y_test == 0]
auc = np.mean((pos[:, None] > neg[None, :])
+ 0.5 * (pos[:, None] == neg[None, :]))
print(f"Simulated data, seed {SEED}")
print(f"Records: {n}; measures: 4; positive outcomes: {int(y.sum())}; "
f"negative outcomes: {int(n-y.sum())}")
print(f"Split: train {len(train_idx)}, test {len(test_idx)}")
print("Simulated log-odds inputs: intercept -0.25; "
"measure effects 0.85, 0.55, 0.00, -0.35")
print("Fitted odds ratios per 1 SD on training data:")
for i, val in enumerate(np.exp(coef[1:]), start=1):
print(f" measure_{i}: {val:.3f}")
print(f"Test AUC: {auc:.3f}")
print(f"Test accuracy at probability 0.5: {accuracy:.3f}")
Printed output:
Simulated data, seed 2026
Records: 600; measures: 4; positive outcomes: 264; negative outcomes: 336
Split: train 420, test 180
Simulated log-odds inputs: intercept -0.25; measure effects 0.85, 0.55, 0.00, -0.35
Fitted odds ratios per 1 SD on training data:
measure_1: 2.185
measure_2: 1.882
measure_3: 1.157
measure_4: 0.638
Test AUC: 0.746
Test accuracy at probability 0.5: 0.689
Result: The fitted odds ratios are 2.185, 1.882, 1.157 and 0.638 for measures 1 to 4, close to the built-in 2.34, 1.73, 1.00 and 0.70 for measures 1, 2 and 4. Measure 3 has no effect built in, so its fitted 1.157 is chance, not a signal: its place above 1.0 in the ranking is a product of noise in 420 training rows. On the 180 test rows the AUC is 0.746 and the share right at probability 0.5 is 0.689. With only 180 test rows, both figures would shift on a new draw. Looking only at the point estimates, a reader could take measure 3 for a real risk factor, which is why you read each odds ratio's likely range and not just its size.
Limit: Made-up data cannot show how a model will work in a real clinic. A missed built-in effect on a small sample means low power, not no effect.
Sources
- Cox DR (1958). The Regression Analysis of Binary Sequences. Journal of the Royal Statistical Society Series B. doi:10.1111/j.2517-6161.1958.tb00292.x. This source backs who published logistic regression for binary results and when; the numbers above come from the script.
The Experimental Question: Prediction, Not Just Association
Let's be clear about what we're testing. The research question is: Given a patient's biomarker profile, what is their probability of having diabetes, and which biomarkers contribute most to that prediction?
This is a prediction problem, not an experimental one. You're working with observational data: cross-sectional measurements from patients who either have diabetes or don't. You didn't randomize patients to different glucose levels or BMI values. That means you can identify associations and build predictive models, but you cannot make causal claims.
Can you say "high glucose predicts diabetes"? Yes. Can you say "lowering glucose prevents diabetes"? Not from this analysis. For causal claims, you need randomized experiments. What you can do is rank risk factors by predictive strength, which tells you where to focus intervention research.
The Right Question
Prediction: "Which biomarkers best predict diabetes status, and what probability does this patient have?"
Causation: "Does lowering glucose prevent diabetes?", requires a randomized experiment, not observational analysis.
This analysis answers the first question. Use it to prioritize screening, build risk scores, and pick candidate targets for intervention research. Then design experiments to test those interventions.
Sample Size: How Many Patients Do You Need?
Before you run a single regression, check that you have enough positive cases for the number of predictors. Too few, and logistic regression produces unstable coefficients, wide confidence intervals, and odds ratios that swing wildly between datasets. You're wasting everyone's time.
The rule of thumb: 10-15 events (positive cases) per predictor variable. If you're testing 8 biomarkers, you need at least 80-120 patients with diabetes. If 35% of your patients have diabetes, that is roughly 229-343 patients in total. Events per variable is a rough heuristic for limiting overfitting, not a power calculation: whether you can detect a given odds ratio depends on its size, the predictor's spread, and the significance level, and needs a formal sample-size calculation with those assumptions stated.
If your diabetes prevalence is lower, say 10%, you'd need 800-1,200 patients total to get the same 80-120 events. If you're below the threshold, either collect more data or reduce the number of predictors (use univariate screening to pick a few).
What happens if you ignore this? Your model overfits. Coefficients are biased away from zero. Odds ratios look impressive in your training data and shrink when you check them on new patients. Don't be that study.
Sample Size Checklist (Rule of Thumb)
- Count positive cases: How many patients have diabetes?
- Count predictors: How many biomarkers are you testing?
- Calculate ratio: Events per variable = diabetic patients ÷ predictors
- Target: the 10-15 rule of thumb above
- If underpowered: Collect more data or reduce predictors
How Logistic Regression Ranks Risk Factors
Logistic regression models the log-odds of diabetes as a linear combination of biomarkers:
log(P(diabetes) / (1 - P(diabetes))) = β₀ + β₁·Glucose + β₂·BMI + β₃·Age + ...
Each coefficient (β) tells you how much the log-odds change when that biomarker increases by one unit, holding all other biomarkers constant. Exponentiate the coefficient and you get an odds ratio: the multiplicative change in odds for a one-unit increase.
Why odds ratios? Because they're interpretable. An odds ratio of 2.185 for measure_1 in the worked example above means: increase measure 1 by one standard deviation, and the odds of a yes result multiply by 2.185. If a patient's baseline odds are 1:2 (33% probability), moving up one SD changes the odds to 2.185:2 (52% probability).
The key phrase: holding all other biomarkers constant. That's what makes this a ranking of independent effects. If two measures are correlated, comparing diabetics with non-diabetics on one alone mixes its effect with the effect of everything it moves with. Logistic regression isolates each measure's unique contribution.
Here's what the model does step-by-step:
- Standardize predictors: Convert each biomarker to z-scores (mean=0, SD=1) so coefficients are comparable.
- Fit coefficients: Find the β values that maximize the likelihood of the observed diabetes outcomes.
- Calculate odds ratios: Exponentiate each β to get the odds multiplier for a 1-SD increase.
- Test significance: Compute 95% confidence intervals; if the CI includes 1.0, the effect is not statistically significant.
- Rank by magnitude: Sort odds ratios from largest to smallest to identify top risk factors.
Model Performance: AUC and Classification Accuracy
Odds ratios tell you which biomarkers matter. But how well does the model actually predict diabetes? For that, you need classification metrics: AUC (area under the ROC curve), sensitivity, specificity, and overall accuracy.
AUC is the probability that a randomly selected diabetic patient has a higher predicted probability than a randomly selected non-diabetic patient. It ranges from 0.5 (coin flip) to 1.0 (perfect separation). There is no single cutoff that makes a model good: what counts depends on the use, and the figure must come from held-out patients. In the worked example the test AUC is 0.746, measured on 180 rows the model did not see. A test set that small gives an uncertain figure.
Accuracy is the percentage of patients correctly classified (true positives + true negatives) ÷ total. In the worked example the share right at a 0.5 probability threshold is 0.689 on the test rows. But accuracy alone is misleading if classes are imbalanced: in that example 336 of 600 cases are negative, so predicting "no" for every case would already be right 56% of the time (336/600). If 90% of patients are non-diabetic, that same trick achieves 90% accuracy while being clinically useless.
That's why you also report sensitivity (true positive rate: what % of diabetics are correctly identified) and specificity (true negative rate: what % of non-diabetics are correctly identified). For diabetes screening, you typically optimize for high sensitivity (catch most diabetics) while accepting lower specificity (some false alarms), which means lowering the threshold below 0.5.
Classification Metrics Cheat Sheet
- AUC: Overall discriminative ability; check it on held-out data
- Accuracy: % correct; can be misleading with class imbalance
- Sensitivity: % of diabetics caught; optimize for screening
- Specificity: % of non-diabetics correctly ruled out; avoid false alarms
- Trade-off: Adjust threshold to balance sensitivity vs specificity for your use case
Risk Factor Ranking by Odds Ratio
The odds ratios answer the question: which biomarkers predict diabetes, and by how much? Each odds ratio is for a one-standard-deviation increase in that biomarker, reported with a 95% confidence interval. Variables are ranked here from strongest to weakest.
In the worked example the fitted order is measure_1 (2.185), measure_2 (1.882), measure_3 (1.157), then measure_4 (0.638). A ratio below 1.0, as for measure 4, means higher values go with lower odds of a yes result (an effect of -0.35 was built in). Measure 3 sits above 1.0 only by chance, since its built-in effect is zero. The script does not print intervals, so on this page you know that only because the data were built that way. With real data, a confidence interval that includes 1.0 is how you would see it.
If you're building a minimal risk score, you'd start with the measures whose intervals stay clear of 1.0, add others if they improve performance on held-out patients, and drop the marginal variables.
Here's what this tells you, and what it doesn't: the measures with the largest ratios carry the most predictive signal in this data, so they are the strongest candidates for intervention research. The ranking does not show that changing one of them would reduce diabetes risk the most; observational data cannot answer that, and a randomized study can. That's the value of ranked effect sizes: they tell you which hypotheses to test first.
Measurement Distributions by Diabetes Status
Before you trust the logistic regression, look at the raw distributions. Compare each biomarker's distribution split by diabetes status. The key question: how much do the distributions separate?
Why look at distributions if you're already running regression? Because distributions reveal data quality problems. If you see bimodal distributions, outliers, or floor/ceiling effects, you need to investigate before modeling. If you see zero separation (distributions perfectly overlapping), that variable is useless and should be dropped. If you see perfect separation (no overlap), logistic regression will fail (complete separation problem) and you need exact methods.
Feature Correlation Matrix
Multicollinearity, high correlation between predictors, inflates standard errors and makes individual coefficients unstable. Before you interpret odds ratios as "independent effects," check the correlation matrix. If two variables are very strongly correlated, you have a problem.
Should you drop one of a correlated pair? Depends on your goal. If you're building a prediction model (maximize AUC), keep both, even redundant variables can add marginal signal. If you're building an interpretable risk score (understand independent effects), and two variables are strongly correlated, pick the one with stronger univariate performance and drop the other.
The formal diagnostic is variance inflation factor (VIF). VIF = 1 ÷ (1 - R²), where R² is the R-squared from regressing that predictor on all other predictors. A large VIF means the other predictors explain that predictor well. If your data shows a large VIF, consider dropping variables or using regularized regression (LASSO/ridge).
When This Analysis Fails
Logistic regression assumes several things. When those assumptions break, the analysis produces garbage. Here's what to watch for:
1. Complete or quasi-complete separation. If a predictor perfectly separates diabetics from non-diabetics (e.g., everyone with glucose above 200 is diabetic, everyone below is not), the maximum likelihood estimate of the coefficient diverges to infinity. The algorithm fails to converge or produces absurdly large odds ratios. Solution: use Firth's penalized logistic regression or exact methods.
2. Outliers and influential points. A single patient with extreme biomarker values can pull the regression line. Check Cook's distance and DFBETAs to identify influential points. If removing one patient changes the odds ratios a lot, you have a problem. Solution: investigate the outlier (data entry error?), winsorize extreme values, or use robust regression.
3. Non-linear effects. Logistic regression assumes log-odds are linear in the predictors. If the true relationship is curved (e.g., diabetes risk is flat at low glucose, then spikes above some level), a linear model will miss it. Solution: add polynomial terms (Glucose²), splines, or use generalized additive models (GAM). Test linearity by binning continuous variables and plotting empirical log-odds.
4. Class imbalance. If diabetes prevalence is 1%, your model will achieve 99% accuracy by predicting "non-diabetic" for everyone. Odds ratios remain unbiased, but classification performance is misleading. Solution: report AUC instead of accuracy, use stratified sampling to balance classes, or adjust decision thresholds to optimize sensitivity/specificity trade-offs.
5. Missing data. If many patients are missing insulin measurements, the regression will drop them (listwise deletion) or impute values. Dropping cases loses power and biases results if missingness is related to diabetes status (e.g., diabetics are more likely to have insulin measured). Solution: use multiple imputation, inverse probability weighting, or full information maximum likelihood.
Before you trust the model, run diagnostics: check residual plots, calculate VIF, test linearity, inspect Cook's distance, and check performance on a holdout set. If the model performs well on training data but collapses on test data, you overfitted.
From Analysis to Action: Building a Clinical Risk Score
You've run the analysis and found your top predictors. Now what? How do you turn regression coefficients into a clinical tool?
The simplest approach: build a risk score. Multiply each biomarker by its coefficient, sum them up, and add the intercept. That's the log-odds of diabetes. Exponentiate to get the odds, then convert to probability.
log-odds = intercept + β₁·x₁ + β₂·x₂ + ...
odds = exp(log-odds)
probability = odds / (1 + odds)
For clinical deployment, you'd check this score on an external dataset (different hospitals, different populations), calibrate it (does predicted probability match observed frequency?), and decide on decision thresholds (what probability triggers action?).
How to Interpret Your Results
When you run diabetes risk factors analysis on your own data, here's the checklist:
1. Check sample size. Do you have enough diabetic patients per predictor (the 10-15 rule of thumb above)? If not, reduce predictors or collect more data. Underpowered analyses produce unreliable odds ratios.
2. Examine odds ratios and confidence intervals. Which variables have OR significantly above 1.0? Those are your signal. Which have wide CIs crossing 1.0? Those are uncertain, don't trust them. A measure can show an odds ratio above 1.0 by chance, as measure 3 does in the worked example, so read the interval and not only the size.
3. Evaluate model performance. What's the AUC on held-out data? There is no single cutoff, so compare it with a simple baseline. What's the accuracy, sensitivity, and specificity at your chosen threshold? Do they meet clinical requirements?
4. Check for multicollinearity. Look at the correlation matrix and VIF. If two variables are very strongly correlated, consider dropping one. If a VIF is large, use regularization or remove correlated variables.
5. Check on held-out data. Split your data into training and test sets, or use cross-validation. Does the model perform similarly on held-out data? If, for example, training AUC is 0.85 and test AUC is 0.65, you overfitted, simplify the model.
6. Compare to univariate distributions. Do the variables with highest odds ratios also show the best univariate separation in the group comparisons? They should. If a variable has a strong univariate effect but a weak odds ratio, it's being explained away by other predictors (multicollinearity or mediation).
7. Check the decision boundary. Does it make clinical sense? If the model predicts diabetes for patients with low glucose and low BMI, something's wrong: check for data errors or model misspecification.
8. Calculate predicted probabilities for reference patients. Plug in typical high-risk and low-risk profiles. Does a clearly high-risk profile get a probability near 100%? Does a clearly low-risk profile get a probability near 0%? If not, the model may be poorly calibrated or misspecified.
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
Common Questions
What sample size do I need for reliable diabetes risk factor analysis?
A common rule of thumb for logistic regression with 6-8 biomarkers is at least 10-15 positive cases (diabetic patients) per predictor variable, to limit overfitting; it is not a formal power calculation. If you're testing 8 variables, that's 80-120 diabetic patients minimum. With a 35% diabetes prevalence, you'd need roughly 229-343 total patients. Underpowered analyses will miss real associations and produce unstable odds ratios.
Can I use this analysis to prove a biomarker causes diabetes?
No. Logistic regression on observational data identifies associations, not causation. High glucose is associated with diabetes, but that does not prove reducing glucose prevents diabetes. To make causal claims, you need randomized experiments. This analysis tells you which factors predict risk: use that to design interventions, then test them experimentally.
What AUC (Area Under Curve) indicates a good diabetes prediction model?
There is no single AUC cutoff that makes a model good. AUC is the chance that a randomly chosen yes case gets a higher score than a randomly chosen no case: 0.5 is a coin flip and 1.0 is perfect ranking. Judge it on held-out data, and remember a small test set gives an uncertain figure. In the worked example on this page, the test AUC is 0.746 on 180 held-out rows.
How do I interpret odds ratios for continuous variables like glucose?
An odds ratio of 2.185 for measure_1 in the worked example on this page means: for every 1-standard-deviation increase in that measure, the odds of a yes outcome multiply by 2.185. If baseline odds are 1:2 (33% risk), moving up one SD changes them to 2.185:2 (52% risk). For interpretability, standardize continuous predictors before modeling, then all odds ratios represent the same-sized change and can be directly compared.
Should I remove correlated biomarkers before running logistic regression?
Not necessarily. Multicollinearity (correlation between predictors) inflates standard errors and makes individual coefficients unstable, but doesn't bias predictions. If your goal is prediction (AUC maximization), keep correlated variables. If your goal is understanding independent effects (odds ratios), and two variables are very strongly correlated, consider dropping one or using regularization (LASSO/ridge). Check variance inflation factors, which flag predictors that the other predictors explain well.