Will this customer churn? Will this loan default? Will this patient test positive? You have a yes-or-no outcome and a set of variables that might predict it. Logistic regression gives you probabilities (not just a label, but a number like "73% chance of churn") and shows how each predictor is associated with that probability, holding the other predictors fixed. Upload a CSV and get a classification report.
What Is Logistic Regression?
Logistic regression predicts binary outcomes: yes or no, 0 or 1, churn or stay, default or repay. It works like linear regression's more practical sibling: instead of predicting a number on an infinite scale, it predicts the probability that something falls into one of two categories. The output is always between 0 and 1, which you can read directly as a percentage chance.
The math works through the logistic function (the S-shaped sigmoid curve). Your predictor variables get combined into a linear equation, and the logistic function squashes the result into the 0-to-1 probability range. For example, a model might learn that each additional year of tenure reduces a customer's churn probability by a certain amount, while each support ticket filed increases it. The model weighs all these factors simultaneously and outputs a single probability.
What makes logistic regression especially valuable is its interpretability through odds ratios. Each predictor gets a coefficient that translates directly into how it affects the odds of the outcome. An odds ratio of 2.5 for "missed payment" means a customer who missed a payment has 2.5 times the odds of defaulting compared to one who did not, holding everything else constant. In this made-up case, you can say it in one sentence: "Customers who miss a payment have 2.5 times the odds of default." That does not mean 2.5 times the chance.
Consider a concrete example. A marketing team wants to predict which new users will convert to paid. They have data on usage frequency, feature adoption, company size, and industry. Logistic regression not only predicts each user's conversion probability but gives each input an odds ratio. The worked example below shows how to read one.
When to Use Logistic Regression
Use logistic regression when your outcome variable is binary, two categories, nothing in between. The classic use cases span nearly every industry. In e-commerce: will this customer churn? In finance: will this applicant default on a loan? In marketing: will this user click the ad? In healthcare: does this patient have the condition? In HR: will this employee leave within 12 months? Any question that boils down to "yes or no" is a candidate.
Logistic regression is the right choice when you need to understand why the model makes its predictions, not just what it predicts. If your stakeholders need to know which factors matter and by how much, logistic regression's odds ratios deliver that directly. Some fields ask for models whose predictions can be explained, and a logistic model can be traced back to its inputs. You can trace every prediction back to the input variables and their coefficients.
It also excels when you need probability estimates rather than hard labels. A credit scoring model that says "this applicant has a 12% chance of default" is far more useful than one that just says "approve" or "deny." You can set your own decision threshold based on your risk tolerance: approve everyone below 15% default probability, flag 15-30% for manual review, deny above 30%. The model stays the same; you just move the cutoff.
Logistic regression works best when the relationship between predictors and the log-odds of the outcome is approximately linear, and when the predictors are not too highly correlated with each other. It handles both numeric predictors (age, income, usage count) and categorical predictors (region, plan type, industry) after encoding. It is also fast to fit, even on tens of thousands of rows, which matters when you are iterating on feature selection or re-running monthly.
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. Covers: the logistic model for yes-or-no outcomes.
- James G, Witten D, Hastie T, Tibshirani R. An Introduction to Statistical Learning (2nd ed.). statlearning.com. Covers: linear and logistic regression.
- scikit-learn developers. scikit-learn: linear models. Covers: the logistic regression implementation used in the example.
What Data Do You Need?
You need a CSV with one binary outcome column and at least one predictor column. The outcome column should contain two distinct values. These can be 0/1, yes/no, true/false, churned/retained, or any two labels. The tool auto-detects the positive class, but you can override it with the positive_class parameter if needed.
Predictor columns should be numeric. Common predictors include customer tenure, monthly spend, number of support tickets, usage frequency, account age, or any quantitative measure you suspect influences the outcome. The tool requires at least one predictor (predictor_1) and supports multiple predictors (predictor_2, predictor_3, and so on) for multivariate models. More predictors let you control for confounders, but adding too many relative to your sample size can cause overfitting.
As a rough floor, aim for at least 50 observations, with a reasonable number of both outcomes present. If your data has 1,000 rows but only 5 positive cases, the model will struggle. It needs enough examples of both classes to learn the pattern. A rough guideline is at least 10-20 events per predictor variable. The tool splits your data into training and test sets (controlled by the test_size parameter, typically 20-30%) to evaluate how well the model generalizes to unseen data.
Additional parameters let you tune the analysis: confidence_level sets the width of confidence intervals on coefficients, classification_threshold sets the probability cutoff for assigning classes (default 0.5), and enabled_analyses controls which report sections to generate.
How to Read the Report
The report contains seven sections, each answering a different question about your model's performance and the relationships in your data.
Executive Summary. The top-level overview gives you the key numbers at a glance: overall accuracy, AUC (area under the ROC curve), and the most important predictors. If you only have 30 seconds, read this section. It tells you whether the model is useful and which variables matter most.
ROC Curve and AUC. The ROC (Receiver Operating Characteristic) curve plots true positive rate against false positive rate at every possible classification threshold. A model that predicts perfectly hugs the top-left corner; a model that guesses randomly follows the diagonal. The AUC (Area Under the Curve) summarizes this into a single number between 0 and 1, with 0.5 as the random-ranking baseline. An AUC below 0.5 means the ranking is worse than chance. An AUC of 0.5 means the model is no better than flipping a coin. Labels such as good or excellent depend on the field and the cost of errors. AUC scores ranking across thresholds. It does not show whether the chance estimates match the results, or whether the errors at one cut-off are acceptable.
Confusion Matrix. This 2x2 table shows how the model's predictions compare to actual outcomes on the test set. It breaks predictions into four buckets: true positives (correctly predicted yes), true negatives (correctly predicted no), false positives (predicted yes but actually no), and false negatives (predicted no but actually yes). The costs of these errors are different for every problem. In fraud detection, a false negative (missing real fraud) is far worse than a false positive (flagging a legitimate transaction). In medical screening, the same is true. The confusion matrix lets you see the specific tradeoffs your model makes.
Odds Ratios. This is where logistic regression truly shines. Each predictor's coefficient is exponentiated into an odds ratio with a confidence interval. An odds ratio above 1 means the predictor increases the odds of the positive outcome; below 1 means it decreases the odds. For example, an odds ratio of 1.35 for "monthly_spend" means each one-unit increase in monthly spend multiplies the odds of the outcome by 1.35 (a 35% increase in odds). Odds ratios with confidence intervals that do not cross 1.0 are statistically significant. This section is what you bring to a strategy meeting. It directly answers "what should we focus on?"
Predicted Probability Distribution. This chart shows the distribution of predicted probabilities for the two classes. In a good model, the positive cases cluster toward higher probabilities and the negative cases cluster toward lower probabilities, with clear separation between the two distributions. Overlapping distributions suggest the model is uncertain about a subset of cases. These are the ones that need manual review or additional data.
Model Coefficients. The raw coefficient table shows each predictor's coefficient, standard error, z-statistic, and p-value. This is the technical detail behind the odds ratios. Positive coefficients increase the log-odds of the positive outcome; negative coefficients decrease it. The p-value tells you whether each predictor's contribution is statistically significant. Non-significant predictors (p > 0.05) may be candidates for removal in a more parsimonious model.
Data Preprocessing. This section documents how the data was cleaned and split before modeling: handling of missing values, encoding of categorical variables, and the train/test split. It ensures full transparency and reproducibility.
Worked Example: A Simulated Logistic Model
The data below are made up. The script builds 600 rows with a yes-or-no outcome from the formula in the code, fits a logistic model on 450 rows, and scores it on the other 150. Every number in the output comes from running the script as shown.
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import (
accuracy_score, roc_auc_score,
brier_score_loss, confusion_matrix)
SEED = 42
rng = np.random.default_rng(SEED)
n = 600
feature_count = rng.integers(0, 6, size=n)
support_tickets = rng.poisson(1.2, size=n)
log_odds = (-2.0 + 0.65 * feature_count
+ 0.45 * support_tickets)
probability = 1 / (1 + np.exp(-log_odds))
converted = rng.binomial(1, probability)
X = np.column_stack((feature_count, support_tickets))
X_train, X_test, y_train, y_test = train_test_split(
X, converted, test_size=0.25,
random_state=SEED, stratify=converted)
model = LogisticRegression(
random_state=SEED, solver="lbfgs")
model.fit(X_train, y_train)
pred_prob = model.predict_proba(X_test)[:, 1]
pred_class = (pred_prob >= 0.5).astype(int)
print(f"Simulated data, seed {SEED}")
print(f"Rows: {n}; positive outcomes: "
f"{int(converted.sum())}")
print("Inputs: feature_count (0-5), "
"support_tickets (Poisson mean 1.2)")
print(f"Test rows: {len(y_test)}; threshold: 0.5")
names = ("feature_count", "support_tickets")
for name, coef in zip(names, model.coef_[0]):
print(f"{name}: coefficient={coef:.3f}; "
f"odds ratio={np.exp(coef):.3f}")
acc = accuracy_score(y_test, pred_class)
auc = roc_auc_score(y_test, pred_prob)
brier = brier_score_loss(y_test, pred_prob)
print(f"Test accuracy: {acc:.3f}")
print(f"Test ROC AUC: {auc:.3f}")
print(f"Test Brier score: {brier:.3f}")
print("Confusion matrix "
"[actual rows 0,1; predicted columns 0,1]:")
print(confusion_matrix(
y_test, pred_class, labels=[0, 1]))
Printed output:
Simulated data, seed 42
Rows: 600; positive outcomes: 311
Inputs: feature_count (0-5), support_tickets (Poisson mean 1.2)
Test rows: 150; threshold: 0.5
feature_count: coefficient=0.671; odds ratio=1.956
support_tickets: coefficient=0.495; odds ratio=1.640
Test accuracy: 0.667
Test ROC AUC: 0.731
Test Brier score: 0.213
Confusion matrix [actual rows 0,1; predicted columns 0,1]:
[[47 25]
[25 53]]
Keep support tickets fixed. Each one-step rise in feature_count multiplies the odds of the outcome by 1.956. Keep feature count fixed. Each extra support ticket multiplies the odds by 1.640. Odds compare an event with no event. They are not the same as chance.
On the 150 test rows, the model was right 0.667 of the time. Its ROC AUC was 0.731, which scores how well it ranks yes cases above no cases. The Brier score was 0.213, which scores how close the chance estimates are to the results.
Limit: these rows were made for this example. They do not show what real customers would do.
When to Use Something Else
If your outcome has more than two categories (for example, classifying customers into "low," "medium," and "high" risk tiers), logistic regression in its standard binary form does not apply. You would need multinomial logistic regression or an ordinal model, which this module does not cover. For multi-class problems with complex feature interactions, a random forest is often a better starting point.
If prediction accuracy matters more than interpretability, tree-based ensemble methods will usually outperform logistic regression. XGBoost and random forest can capture nonlinear relationships and complex interactions that logistic regression misses because it assumes a linear relationship between predictors and log-odds. If you do not need to explain why the model predicts what it predicts, these methods will typically give you a higher AUC.
If you have very few data points or your predictors are highly correlated, Naive Bayes is worth considering. It is more robust with small samples and makes strong independence assumptions that, paradoxically, often work well in practice. It is also extremely fast, which matters if you are screening thousands of models or working with streaming data.
If your outcome is numeric rather than categorical. You want to predict how much a customer will spend, not whether they will buy, use linear regression instead. And if you suspect the relationship between predictors and outcome is nonlinear but you still want some interpretability, consider ridge or lasso regression with polynomial features, which add flexibility while keeping the model partially interpretable.
The R Code Behind the Analysis
Every report names its method and includes the R code that produced it, so you can reproduce, audit and cite it. The method code is fixed, not rewritten for each run, so the same data gives the same analysis every time.
The analysis uses glm() with family = binomial for model fitting: a logistic regression implementation in base R. ROC curves and AUC are computed using the pROC package, an R package for receiver operating characteristic analysis. The confusion matrix and classification metrics (accuracy, precision, recall, F1) come from the caret package's confusionMatrix() function. Odds ratios are calculated by exponentiating the model coefficients with exp(coef()), and confidence intervals use confint() based on profile likelihood. Every step is visible in the code tab of your report, so you or a statistician can verify exactly what was done.
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