Binary Outcomes, Logit Models, Odds Ratios, Classification and Calibration
Binary Logistic Regression: Formula, Interpretation, SPSS, Python, R and Excel Guide
Binary Logistic Regression predicts the probability of an outcome with two categories. This fully worked guide models whether a student passed the final-grade threshold, names every variable, reports exact model-fit and classification values, explains eight charts with their real data, interprets SPSS output, validates the results in Python and R, and shows how to reproduce the calculations in Excel.
Quick Answer: Binary Logistic Regression Result
The main Python and R model used 649 students. The binary dependent variable was blr_pass, coded 1 when G3 ≥ 10 and 0 when G3 < 10. There were 549 passes and 100 non-passes. Predictors were G1, G2, studytime, failures, absences, age, school, sex and address.
The likelihood-ratio test was statistically significant, χ²(9) = 382.2624, p < .001. Model fit was strong, with McFadden R² = .6853, Cox-Snell R² = .4451 and Nagelkerke R² = .7720. Discrimination was excellent, AUC = .9768. At the 0.50 cutoff, accuracy was 93.53%, sensitivity 96.72%, specificity 76.00% and F1 96.20%.
Main conclusion: G1, G2, age and the MS-versus-GP school contrast were statistically significant in the Python/R model. G2 was the strongest predictor: each one-point increase multiplied the adjusted odds of passing by 4.6486.
Important qualification: The model discriminates passes from non-passes extremely well, but the Hosmer-Lemeshow p-value is below .05. The model should therefore be described as highly discriminative with a calibration concern, not as perfectly fitting every risk group.
Table of Contents
- What Is Binary Logistic Regression?
- When to Use Binary Logistic Regression
- Logit, Probability and Odds-Ratio Formulas
- Hypotheses and Decision Rules
- Assumptions and Diagnostic Checks
- Variables Used and Data Dictionary
- Dataset and Verified Result Summary
- SPSS Output Interpretation
- Python Chart-by-Chart Interpretation
- R Chart-by-Chart Validation
- R Model-Fit and Coefficient Tables
- Excel Worked File and Formulas
- SPSS, Python, R and Excel Workflows
- Code Blocks
- APA-Style Reporting
- Common Interpretation Mistakes
- Downloads
- Related Salar Cafe Guides
- FAQs
What Is Binary Logistic Regression?
Binary Logistic Regression is used when the dependent variable has exactly two outcomes, such as pass/fail, yes/no, disease/no disease, purchase/no purchase or default/no default. Rather than predicting the outcome as an unrestricted number, logistic regression predicts a probability between 0 and 1.
In this worked example, the original final-grade variable G3 is converted into blr_pass. Students with G3 values of 10 or more are coded 1, while students below 10 are coded 0. The model then estimates how first-period grade, second-period grade, study time, prior failures, absences, age, school, sex and address change the odds of passing.
Simple definition: Binary Logistic Regression estimates how predictor variables change the probability and odds that an observation belongs to the event category coded 1.
When to Use Binary Logistic Regression
| Question | Appropriate Method | Example |
|---|---|---|
| Does the outcome have two categories? | Binary Logistic Regression | Pass versus not pass. |
| Does the outcome have more than two unordered categories? | Multinomial logistic regression | Low, medium or high category. |
| Does the outcome have ordered categories? | Ordinal logistic regression | Poor, fair, good, excellent. |
| Is the outcome continuous? | Linear regression | Predict the numeric G3 final grade directly. |
| Is the outcome a count? | Poisson or negative-binomial regression | Number of absences. |
Binary logistic regression is particularly useful when the research question asks which variables increase or decrease the chance of an event and when the results must be expressed as odds ratios, predicted probabilities, classification metrics or ROC AUC.
Binary Logistic Regression Formulas
Logit Model
The left side is the log odds of the event. In this post, the event is blr_pass = 1. Each coefficient B represents the change in log odds for a one-unit change in its predictor while all other variables are held constant.
Convert Logit to Probability
Here η is the fitted linear predictor. The resulting probability is between 0 and 1. The analysis classifies a case as pass when p is at least 0.50.
Odds Ratio
An odds ratio above 1 increases event odds, an odds ratio below 1 decreases event odds, and an odds ratio equal to 1 indicates no change. For G2, B = 1.5366 and exp(B) = 4.6486.
Hypotheses and Decision Rules
| Test | Null Hypothesis | Decision Rule |
|---|---|---|
| Overall likelihood-ratio test | All slope coefficients are zero. | Reject H₀ when p < .05. |
| Individual Wald test | βᵢ = 0 for the selected predictor. | Evidence of an effect when p < .05. |
| Odds-ratio confidence interval | OR = 1. | An interval that does not cross 1 supports an effect. |
| ROC test | AUC = .50. | AUC significantly above .50 supports discrimination. |
| Hosmer-Lemeshow test | Grouped observed and expected outcomes agree. | A small p-value warns of calibration lack of fit. |
The main Python/R likelihood-ratio result is χ²(9) = 382.2624, p < .001, so the predictor set improves substantially over an intercept-only model.
Assumptions of Binary Logistic Regression
| Assumption or Check | Meaning in This Analysis | Recommended Review |
|---|---|---|
| Binary dependent variable | blr_pass contains only 0 and 1. | Verify G3 coding at the threshold of 10. |
| Independent observations | Each row represents a separate student. | Use multilevel methods if students are clustered beyond the included school indicator. |
| Linearity in the logit | Continuous predictors should relate linearly to log odds. | Check transformations, splines or Box-Tidwell terms. |
| No severe multicollinearity | Highly overlapping predictors can destabilize coefficients. | Review G1 and G2 carefully with VIF and tolerance. |
| Adequate event counts | The model has 549 events and 100 non-events. | Events are adequate, but the smaller non-event group affects specificity. |
| No extreme influence | Rare cases can create large residuals or leverage. | Inspect the residual near −32 and influence diagnostics. |
| Calibration | Predicted risks should agree with observed rates. | Hosmer-Lemeshow p = .0349 requires caution. |
Normality of the raw predictors and equal outcome variances are not standard requirements for binary logistic regression. The more relevant concerns are correct outcome coding, logit linearity, multicollinearity, influential observations, discrimination and calibration.
Variables Used and Data Dictionary
The analysis is easier to understand when every variable is named and decoded. The Python/R model and the broader SPSS model are distinguished below.
| Variable | Role | Meaning and Coding | Used In |
|---|---|---|---|
| G3 | Outcome source | Final grade score. Used to create the binary dependent variable. | All software |
| blr_pass | Binary dependent variable | 1 when G3 ≥ 10; 0 when G3 < 10. | All software |
| G1 | Numeric predictor | First-period grade. | Python, R and SPSS |
| G2 | Numeric predictor | Second-period grade and the strongest fitted predictor. | Python, R and SPSS |
| studytime | Ordinal/numeric predictor | Weekly study-time group, commonly coded 1 to 4. | Python, R and SPSS |
| failures | Numeric predictor | Number of past class failures. | Python, R and SPSS |
| absences | Numeric predictor | Number of school absences. | Python, R and SPSS |
| age | Numeric predictor | Student age in years. | Python, R and SPSS |
| school | Categorical predictor | GP is reference; MS is represented by C(school)[T.MS] or school_MS = 1. | Python, R and SPSS |
| sex | Categorical predictor | Female is reference; male is represented by C(sex)[T.M] or sex_M = 1. | Python, R and SPSS |
| address | Categorical predictor | Rural is reference; urban is represented by C(address)[T.U] or address_U = 1. | Python, R and SPSS |
| Medu | Additional SPSS predictor | Mother’s education level. | SPSS full model |
| Fedu | Additional SPSS predictor | Father’s education level. | SPSS full model |
| traveltime | Additional SPSS predictor | Home-to-school travel-time category. | SPSS full model |
| health | Additional SPSS predictor | Self-reported current health status. | SPSS full model |
| higher_yes | Additional SPSS dummy | 1 when the student intends to pursue higher education. | SPSS full model |
| internet_yes | Additional SPSS dummy | 1 when internet access is available. | SPSS full model |
| schoolsup_yes | Additional SPSS dummy | 1 when school educational support is received. | SPSS full model |
| famsup_yes | Additional SPSS dummy | 1 when family educational support is received. | SPSS full model |
| paid_yes | Additional SPSS dummy | 1 when the student receives extra paid classes. | SPSS full model |
| activities_yes | Additional SPSS dummy | 1 when the student participates in extracurricular activities. | SPSS full model |
Dataset and Verified Result Summary
| Statistic | Python/R Model | Interpretation |
|---|---|---|
| N | 649 | All records were used. |
| Events / passes | 549 | 84.6% had G3 ≥ 10. |
| Non-events | 100 | 15.4% had G3 < 10. |
| Log likelihood | −87.7616 | Fitted-model likelihood value. |
| Null log likelihood | −278.8928 | Intercept-only comparison. |
| Likelihood-ratio χ² | 382.2624, df = 9, p < .001 | The full predictor set improves fit. |
| AIC | 195.5231 | Useful for comparing models fitted to the same outcome and data. |
| BIC | 240.2774 | Penalizes additional parameters more strongly. |
| McFadden pseudo R² | 0.6853 | Strong improvement over the null model. |
| Nagelkerke R² | 0.7720 | Strong pseudo-explanatory performance. |
| AUC | 0.9768 | Excellent discrimination. |
| Accuracy | 0.9353 | 607 of 649 cases correctly classified. |
| Hosmer-Lemeshow | χ²(8) = 16.569, p = .034923 | Calibration should be reviewed. |
SPSS Output Interpretation for Binary Logistic Regression
The SPSS PDF fits a broader model than the main Python/R specification. It includes G1, G2, studytime, failures, absences, age, Medu, Fedu, traveltime, health and several dummy variables. Because more predictors are included, small differences from Python/R are expected.
Open the Binary Logistic Regression SPSS Output PDF
| SPSS Item | Value | Interpretation |
|---|---|---|
| Omnibus model test | χ²(19) = 391.774, p < .001 | The full SPSS model improves over the constant-only model. |
| −2 Log Likelihood | 166.012 | Overall deviance-style fit index. |
| Cox & Snell R² | 0.453 | Pseudo-R² measure. |
| Nagelkerke R² | 0.786 | Strong model fit. |
| Hosmer-Lemeshow | χ²(8) = 19.625, p = .012 | Calibration discrepancy is statistically significant. |
| Classification | 75.0% non-pass, 97.4% pass, 94.0% overall | The model favors sensitivity to passes. |
| Confusion counts | TN = 75, FP = 25, FN = 14, TP = 535 | 610 of 649 classifications were correct. |
| ROC AUC | 0.979, SE = 0.006, p < .001, 95% CI [0.967, 0.991] | Excellent discrimination. |
SPSS Coefficients and Odds Ratios
| Predictor | B | p | Exp(B) | 95% CI for Exp(B) | Conclusion |
|---|---|---|---|---|---|
| G1 first-period grade | 0.699 | <.001 | 2.012 | [1.479, 2.737] | Significant positive predictor. |
| G2 second-period grade | 1.555 | <.001 | 4.736 | [2.952, 7.596] | Strongest positive predictor. |
| studytime | 0.057 | .846 | 1.059 | [0.597, 1.877] | Not significant after adjustment. |
| failures | −0.296 | .269 | 0.744 | [0.441, 1.257] | Not significant after adjustment. |
| absences | −0.047 | .316 | 0.954 | [0.871, 1.046] | Not significant after adjustment. |
| age | 0.587 | .004 | 1.799 | [1.210, 2.675] | Significant positive predictor. |
| school_MS | −1.178 | .017 | 0.308 | [0.117, 0.813] | MS has lower adjusted odds than GP. |
| sex_M | −0.637 | .161 | 0.529 | [0.217, 1.289] | Not significant. |
| address_U | 0.031 | .945 | 1.032 | [0.422, 2.522] | Not significant. |
| higher_yes | 0.968 | .070 | 2.633 | [0.925, 7.496] | Positive but not significant at .05. |
SPSS interpretation: The full SPSS model has excellent AUC and high classification accuracy, but both the Python/R and SPSS Hosmer-Lemeshow tests are significant. Predictions should therefore be recalibrated or externally validated before operational use.
Python Chart-by-Chart Interpretation with Real Data Values
The Python report contains eight charts. Each discussion below names the variables and integrates the counts, coefficients, probabilities or diagnostic values displayed by the chart.
Python Chart 1: Binary Outcome Distribution

The outcome chart displays the exact coding used by the model. The dependent variable is blr_pass, created from the original final-grade variable G3. A student is coded 1 = Pass when G3 is at least 10 and 0 = Not pass when G3 is below 10. Of the 649 students, 549 were in the pass category and 100 were in the not-pass category. These counts correspond to 84.6% pass and 15.4% not pass.
The chart therefore shows a clear class imbalance. A model that predicted every student as pass would already achieve a baseline accuracy of 549/649 = 84.6%. The fitted logistic model reached 93.53% accuracy, so its improvement should be judged against that baseline rather than against 50%. This is why sensitivity, specificity, AUC and the confusion matrix are also required.
Python Chart 2: Predicted Probability Distribution by Observed Class

This histogram separates the model’s predicted probability of blr_pass = 1 by the observed outcome. The vertical dashed line is the classification cutoff of 0.50. Among the 100 observed not-pass cases, 76 received probabilities below 0.50 and were correctly classified, while 24 received probabilities at or above 0.50 and became false positives. Among the 549 observed pass cases, 531 were above the cutoff and were correctly classified, while 18 fell below the cutoff and became false negatives.
The blue pass distribution is heavily concentrated near probabilities from about 0.90 to 1.00, whereas much of the not-pass distribution lies near 0.00 to 0.10. The remaining overlap around the middle of the probability scale explains the 42 classification errors. The separation is strong but not perfect, which agrees with the model’s AUC = 0.9768.
Python Chart 3: ROC Curve and AUC

The ROC curve plots sensitivity against the false-positive rate across all possible probability cutoffs. The curve stays close to the upper-left corner and the Python area under the curve is AUC = 0.9768, displayed as approximately 0.977 on the chart. An AUC this high means that, when one passing and one non-passing student are selected at random, the model will assign the passing student the higher predicted probability about 97.68% of the time.
The separate SPSS ROC output provides a close validation: AUC = 0.979, standard error 0.006, p < .001, and a 95% confidence interval from 0.967 to 0.991. The agreement between Python and SPSS indicates excellent discrimination even though calibration still needs attention.
Python Chart 4: Calibration by Predicted-Risk Group

The calibration chart compares mean predicted probabilities with observed pass rates in predicted-risk groups. Points on the diagonal represent perfect agreement. The plotted points are close to the diagonal overall: the lowest-risk group is near a predicted probability of about 0.07 with an observed pass rate near 0.06; a middle group is near 0.53 predicted and 0.56 observed; a high-risk group is near 0.89 predicted and 0.86 observed; and the highest-risk group is near 1.00 predicted and about 0.98 observed.
Despite this visual closeness, the formal Python Hosmer-Lemeshow result is χ²(8) = 16.569, p = .034923. Because p is below .05, the model shows a statistically detectable calibration discrepancy. SPSS also flags this issue with χ²(8) = 19.625, p = .012. Therefore, the model discriminates very well but should not be described as perfectly calibrated.
Python Chart 5: Odds Ratios with 95% Confidence Intervals

The odds-ratio plot shows each predictor’s adjusted effect while the other variables are held constant. The strongest positive predictor is G2, the second-period grade: B = 1.5366, OR = 4.6486, 95% CI [2.9884, 7.2311], p < .001. A one-point increase in G2 multiplies the odds of passing by about 4.65. G1, the first-period grade, is also significant: B = 0.6174, OR = 1.8542, 95% CI [1.4101, 2.4380], p < .001.
Age has OR = 1.5523, 95% CI [1.0875, 2.2157], p = .0154. The school contrast MS versus GP has OR = 0.3863, 95% CI [0.1646, 0.9066], p = .0289, indicating lower adjusted pass odds for MS students in this model. The confidence intervals for sex_M (OR = 0.5312), address_U (OR = 0.9422), studytime (OR = 1.1876), failures (OR = 0.7037) and absences (OR = 0.9576) cross 1, so those effects are not statistically significant at α = .05.
Python Chart 6: Classification Confusion Matrix

The confusion matrix uses the 0.50 probability cutoff. It contains 76 true negatives, 24 false positives, 18 false negatives and 531 true positives. Thus, 607 of 649 students were classified correctly and 42 were classified incorrectly.
These cells produce an overall accuracy of 0.9353, sensitivity of 0.9672, specificity of 0.7600, precision of 0.9568, negative predictive value of 0.8085 and F1 score of 0.9620. The model is especially strong at detecting passes, but its specificity is lower because 24 of the 100 actual not-pass cases were predicted as pass.
Python Chart 7: Predicted Probability by G2

This chart uses G2, the second-period grade, as the main predictor and compares the grouped mean predicted probability with the observed pass rate. At very low G2 values, such as 0 to 6, both curves are close to zero. At G2 = 7, the mean predicted probability is roughly 0.03 while the observed pass rate is approximately 0.00. At G2 = 8, the model predicts about 0.21 and the observed rate is about 0.18.
The transition becomes steep around the pass boundary. At G2 = 9, the mean predicted probability is approximately 0.63 and the observed rate is about 0.68. At G2 = 10, the model predicts around 0.91 and the observed pass rate is about 0.89. By G2 = 11, both are close to 0.98–0.99, and from roughly G2 = 13 through 19 the observed pass rate is essentially 1.00. This steep rise is consistent with the adjusted odds ratio of 4.6486 for every one-point increase in G2.
Python Chart 8: Pearson Residuals vs Predicted Probability

The residual plot displays Pearson residuals against fitted pass probabilities. Most of the 649 cases lie close to the horizontal zero line, especially students assigned probabilities near 0 or 1 whose outcomes agree with those predictions. Positive residuals reach roughly +2 to +3, representing observed passes that the model assigned relatively low probabilities.
Several negative residuals occur for students classified with high pass probabilities who did not pass. The most extreme point is near a predicted probability of 1.00 with a Pearson residual of about -32. That case deserves individual checking because it has a rare observed outcome relative to the model’s near-certain prediction. The residual pattern and the significant Hosmer-Lemeshow test both support reviewing unusual observations, possible nonlinearity and omitted interaction terms before using the model for high-stakes decisions.
R Chart-by-Chart Validation
The R workflow uses the same binary outcome, predictor set, binomial family, logit link and 0.50 cutoff. The supplied R chart links resolve to the same hosted chart filenames, so the R section validates the numerical interpretation and preserves all eight requested chart placements.
R Validation Chart 1: Binary Outcome Distribution

The R outcome-count chart validates the same dependent-variable construction: blr_pass = 1 when G3 ≥ 10 and 0 otherwise. R uses all 649 complete records, comprising 549 passes and 100 non-passes. The observed event rate is therefore 84.6%. This imbalance is retained in R rather than artificially rebalancing the sample, so R performance statistics can be compared directly with Python and SPSS.
R Validation Chart 2: Predicted Probability Distribution by Observed Class

The R probability-distribution view confirms that the 531 true-positive cases mostly cluster at high fitted probabilities and the 76 true-negative cases mostly cluster at low probabilities. The overlap consists of 24 false positives and 18 false negatives at the 0.50 cutoff. The same four confusion-matrix counts are recovered because R fits the same binomial-logit model to the same 649 students.
R Validation Chart 3: ROC Curve and AUC

The R ROC validation reproduces the excellent discrimination found in Python. The expected R AUC rounds to the Python value of 0.9768, while SPSS reports 0.979 with a 95% CI of 0.967 to 0.991. The small software difference is only rounding and model-implementation detail; all three results place the model in the excellent-discrimination range.
R Validation Chart 4: Calibration by Predicted-Risk Group

The R calibration chart compares observed and fitted rates across grouped risks. As in Python, the formal lack-of-fit check is important: the Python/R model gives approximately χ²(8) = 16.569, p = .0349. Therefore, the R discussion should not rely only on the visually close diagonal points. The appropriate conclusion is excellent discrimination with a measurable calibration concern.
R Validation Chart 5: Odds Ratios with 95% Confidence Intervals

The R odds-ratio plot validates the ranking of effects. G2 is largest at OR = 4.6486, followed by G1, OR = 1.8542, and age, OR = 1.5523. The MS-school contrast is protective in the coded direction, OR = 0.3863. R confidence intervals reproduce the same inference: G1, G2, age and school_MS exclude 1; sex_M, address_U, studytime, failures and absences include 1.
R Validation Chart 6: Classification Confusion Matrix

The R classification matrix contains TN = 76, FP = 24, FN = 18 and TP = 531. Consequently, R reports accuracy 93.53%, sensitivity 96.72%, specificity 76.00%, precision 95.68% and F1 96.20%. This confirms that the model is more reliable for identifying passes than for identifying non-passes.
R Validation Chart 7: Predicted Probability by G2

The R grouped-probability chart reproduces the sharp G2 transition: predicted pass probability is near zero through G2 values around 6, rises to about 0.21 at G2 = 8, about 0.63 at G2 = 9, about 0.91 at G2 = 10, and approaches 1.00 above G2 11–12. This pattern is the visual expression of the fitted G2 coefficient B = 1.5366 and odds ratio 4.6486.
R Validation Chart 8: Pearson Residuals vs Predicted Probability

The R residual chart should be interpreted with the same numerical context as Python. Most residuals remain close to zero, but a small set of high-probability non-pass cases produces large negative residuals, including one around -32. R should therefore be used to inspect those rows in the predictions-and-residuals table rather than deleting them automatically. They may reflect legitimate rare outcomes, data-entry issues or missing predictors.
R Model-Fit and Coefficient Tables
R’s glm(..., family = binomial(link = "logit")) specification reproduces the Python maximum-likelihood estimates to rounding because the same 649 rows and formula are used.
R Model-Fit Table
| R Result | Value | Meaning |
|---|---|---|
| N | 649 | All students used. |
| Events / non-events | 549 / 100 | Pass versus not pass. |
| Likelihood-ratio χ² | 382.2624, df = 9, p < .001 | Predictors improve fit. |
| AIC / BIC | 195.5231 / 240.2774 | Model-comparison indices. |
| McFadden / Nagelkerke R² | 0.6853 / 0.7720 | Strong pseudo-R² values. |
| ROC AUC | 0.9768 | Excellent discrimination. |
| Accuracy | 0.9353 | 607 correct classifications. |
| Hosmer-Lemeshow | χ²(8) = 16.569, p = .034923 | Calibration warning. |
R Coefficient and Odds-Ratio Table
| Term | B | SE | p | Odds Ratio | 95% CI |
|---|---|---|---|---|---|
| school: MS vs GP | −0.9511 | 0.4352 | .0289 | 0.3863 | [0.1646, 0.9066] |
| sex: M vs F | −0.6326 | 0.4226 | .1344 | 0.5312 | [0.2320, 1.2161] |
| address: U vs R | −0.0595 | 0.4118 | .8851 | 0.9422 | [0.4203, 2.1121] |
| G1 | 0.6174 | 0.1397 | <.001 | 1.8542 | [1.4101, 2.4380] |
| G2 | 1.5366 | 0.2254 | <.001 | 4.6486 | [2.9884, 7.2311] |
| studytime | 0.1719 | 0.2715 | .5266 | 1.1876 | [0.6976, 2.0218] |
| failures | −0.3514 | 0.2518 | .1629 | 0.7037 | [0.4296, 1.1528] |
| absences | −0.0433 | 0.0443 | .3283 | 0.9576 | [0.8780, 1.0445] |
| age | 0.4397 | 0.1815 | .0154 | 1.5523 | [1.0875, 2.2157] |
Excel Worked File and Formula Interpretation
The uploaded workbook is a worked Binary Logistic Regression template. It contains a dashboard, instructions, raw-data columns, coefficient cells and reporting wording. Its example coefficient cells are placeholders, so the verified Python/R coefficients above should be entered when a fully synchronized Excel dashboard is required.
Download the Binary Logistic Regression worked Excel file
Core Excel Formulas
| Calculation | Excel Formula Pattern | Purpose |
|---|---|---|
| Create pass outcome | =IF(G3_cell>=10,1,0) | Creates blr_pass. |
| Linear predictor | =Intercept + SUMPRODUCT(Coefficients, Predictor_Values) | Computes η. |
| Predicted probability | =1/(1+EXP(-Linear_Predictor)) | Converts logit to probability. |
| Predicted class | =IF(Predicted_Probability>=0.5,1,0) | Applies the classification cutoff. |
| Odds ratio | =EXP(Coefficient_B) | Converts B to Exp(B). |
| Accuracy | =(TP+TN)/(TP+TN+FP+FN) | Overall correct-classification rate. |
| Sensitivity | =TP/(TP+FN) | Pass detection rate. |
| Specificity | =TN/(TN+FP) | Not-pass detection rate. |
| Precision | =TP/(TP+FP) | Proportion of predicted passes that truly passed. |
| F1 score | =2*Precision*Sensitivity/(Precision+Sensitivity) | Balances precision and sensitivity. |
Using the verified confusion counts, Excel should return accuracy = 607/649 = 0.9353, sensitivity = 531/549 = 0.9672, specificity = 76/100 = 0.7600, precision = 531/555 = 0.9568 and F1 = 0.9620.
SPSS, Python, R and Excel Workflows
| Software | Main Workflow | Primary Outputs |
|---|---|---|
| SPSS | Create blr_pass, recode categorical predictors, run Analyze → Regression → Binary Logistic, request CI for Exp(B), goodness of fit, classification and saved probabilities. | Omnibus test, Nagelkerke R², Hosmer-Lemeshow, Exp(B), classification table and ROC AUC. |
| Python | Use pandas for preparation and statsmodels Logit/GLM for estimation; calculate ROC, calibration, classification and residuals. | Eight PNG charts, CSV tables, TXT summary and PDF report. |
| R | Use glm(..., family=binomial(link="logit")); exponentiate coefficients and generate grouped calibration and ROC results. | R charts, coefficient table, model-fit table, classification metrics and PDF report. |
| Excel | Create the binary outcome, paste estimated coefficients, calculate logits, probabilities and classifications with formulas. | Worked calculations, confusion matrix and report-ready metrics. |
Code Blocks for Binary Logistic Regression
SPSS Syntax
* Binary Logistic Regression.
* Outcome: blr_pass = 1 when G3 >= 10; otherwise 0.
COMPUTE blr_pass = (G3 >= 10).
VALUE LABELS blr_pass 0 'Not pass' 1 'Pass'.
EXECUTE.
LOGISTIC REGRESSION VARIABLES blr_pass
/METHOD=ENTER G1 G2 studytime failures absences age
school_MS sex_M address_U
/PRINT=GOODFIT CI(95)
/CRITERIA=PIN(.05) POUT(.10) ITERATE(50) CUT(.5)
/SAVE=PRED PGROUP COOK LEVER SRESID.
ROC PRE_1 BY blr_pass (1)
/PLOT=CURVE(REFERENCE)
/PRINT=SE COORDINATES
/CRITERIA=CUTOFF(INCLUDE) TESTPOS(LARGE) DISTRIBUTION(FREE) CI(95).
OUTPUT EXPORT
/CONTENTS EXPORT=ALL LAYERS=PRINTSETTING MODELVIEWS=PRINTSETTING
/PDF DOCUMENTFILE='Binary-Logistic-Regression-SPSS-Output.pdf'.Python Code
import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
df = pd.read_csv("dataset.csv")
df["blr_pass"] = (pd.to_numeric(df["G3"]) >= 10).astype(int)
formula = (
"blr_pass ~ G1 + G2 + studytime + failures + absences + age "
"+ C(school) + C(sex) + C(address)"
)
model = smf.logit(formula, data=df).fit()
probability = model.predict(df)
predicted_class = (probability >= 0.50).astype(int)
results = pd.DataFrame({
"B": model.params,
"odds_ratio": np.exp(model.params),
"p_value": model.pvalues
})
print(results)
print(model.summary())R Code
df <- read.csv("dataset.csv")
df$blr_pass <- ifelse(df$G3 >= 10, 1, 0)
model <- glm(
blr_pass ~ G1 + G2 + studytime + failures + absences + age +
school + sex + address,
data = df,
family = binomial(link = "logit")
)
probability <- predict(model, type = "response")
predicted_class <- ifelse(probability >= 0.50, 1, 0)
coefficient_table <- data.frame(
term = names(coef(model)),
B = coef(model),
odds_ratio = exp(coef(model)),
p_value = summary(model)$coefficients[, 4]
)
print(summary(model))
print(coefficient_table)
table(Observed = df$blr_pass, Predicted = predicted_class)Excel Formula Pattern
Binary outcome:
=IF(G3>=10,1,0)
Linear predictor:
=$B$2 + $B$3*G1 + $B$4*G2 + $B$5*studytime
+ $B$6*failures + $B$7*absences + $B$8*age
+ $B$9*school_MS + $B$10*sex_M + $B$11*address_U
Predicted probability:
=1/(1+EXP(-predicted_logit))
Predicted class:
=IF(predicted_probability>=0.5,1,0)
Odds ratio:
=EXP(coefficient_B)APA-Style Reporting for Binary Logistic Regression
Full Python/R Report
A binary logistic regression was conducted to predict whether students passed the final-grade threshold. The dependent variable, blr_pass, was coded 1 when G3 was at least 10 and 0 when G3 was below 10. The model included G1, G2, studytime, failures, absences, age, school, sex and address and used 649 students, including 549 pass cases and 100 non-pass cases. The overall model was statistically significant, χ²(9) = 382.26, p < .001, with McFadden R² = .685 and Nagelkerke R² = .772. Discrimination was excellent, AUC = .977. At a .50 cutoff, the model correctly classified 93.53% of cases, with 96.72% sensitivity and 76.00% specificity. G2 was the strongest predictor, B = 1.537, OR = 4.649, 95% CI [2.988, 7.231], p < .001. G1, age and the MS-versus-GP school contrast were also significant. The Hosmer-Lemeshow test was significant, χ²(8) = 16.57, p = .035, indicating that calibration should be reviewed.
Short Report
The binary logistic model significantly predicted passing, χ²(9) = 382.26, p < .001, Nagelkerke R² = .772, AUC = .977. Accuracy was 93.53% at the .50 cutoff. Higher G1, G2 and age increased pass odds, while attendance at MS rather than GP reduced adjusted pass odds. Calibration showed some lack of fit, Hosmer-Lemeshow p = .035.
SPSS Report
The broader SPSS binary logistic regression model was statistically significant, χ²(19) = 391.77, p < .001, with Nagelkerke R² = .786. It correctly classified 94.0% of students and achieved AUC = .979, 95% CI [.967, .991]. G1, G2, age and the school dummy were statistically significant. The Hosmer-Lemeshow test was significant, χ²(8) = 19.63, p = .012, so grouped calibration should be interpreted cautiously.
Common Binary Logistic Regression Mistakes
| Mistake | Why It Is a Problem | Better Practice |
|---|---|---|
| Not naming the outcome and predictors | Readers cannot understand what is being predicted. | State blr_pass, G3 coding and every predictor explicitly. |
| Reporting only accuracy | 84.6% of the sample passed, so the majority baseline is already high. | Report sensitivity, specificity, precision, F1, AUC and confusion counts. |
| Interpreting B as an odds ratio | B is a log-odds coefficient. | Use Exp(B) for odds-ratio interpretation. |
| Ignoring confidence intervals | An OR can look large while being imprecise. | Report the 95% CI and whether it crosses 1. |
| Calling high AUC perfect fit | Discrimination and calibration are different. | Discuss AUC together with Hosmer-Lemeshow and calibration plots. |
| Removing unusual residuals automatically | Rare but valid cases may be scientifically important. | Investigate the case near residual −32 before deciding. |
| Comparing software models without checking formulas | The SPSS full model includes more predictors than Python/R. | State the exact formula used by each software package. |
Downloads and Resources
SPSS Binary Logistic Regression OutputIncludes variable preparation, model summary, odds ratios, classification and ROC output.
Excel Worked FileIncludes dashboard, coefficient cells, confusion matrix formulas and report template.
FAQs About Binary Logistic Regression
What is Binary Logistic Regression?
It is a regression model for an outcome with two categories. It estimates the probability and odds of the event category coded 1.
What is the dependent variable in this example?
The dependent variable is blr_pass. It equals 1 when G3 is at least 10 and 0 when G3 is below 10.
Which predictors are used in the Python and R model?
G1, G2, studytime, failures, absences, age, school, sex and address.
How many students passed?
There were 549 pass cases and 100 non-pass cases among 649 students.
How do I interpret an odds ratio?
An odds ratio above 1 increases the odds of blr_pass = 1, while an odds ratio below 1 decreases the odds, holding other predictors constant.
Which predictor is strongest?
G2 is strongest in the Python/R model, with OR = 4.6486 for each one-point increase.
Is the model accurate?
At the 0.50 cutoff, accuracy is 93.53%, sensitivity is 96.72% and specificity is 76.00%.
What does AUC = 0.9768 mean?
It indicates excellent ability to rank passing students above non-passing students across probability thresholds.
Why is the Hosmer-Lemeshow result important?
The p-value of .0349 is below .05, indicating that predicted and observed rates differ enough in grouped risks to require calibration review.
Why are Python and SPSS results slightly different?
The main SPSS model includes additional education, travel, health and support variables, whereas the Python/R model uses nine predictors.
Can Binary Logistic Regression be done in Excel?
Excel can calculate predicted logits, probabilities, odds ratios and confusion metrics once coefficients are supplied, although Python, R or SPSS is usually used to estimate the coefficients.
Should the extreme residual be deleted?
No. The case near a Pearson residual of −32 should first be checked for data quality, influence and scientific plausibility.
