Classification Modeling: Customer Churn Prediction with XGBoost

Acquiring a new customer costs 5x to 7x more than retaining an existing one. Customer Churn Prediction is the quintessential classification problem in enterprise data science. In this class, we build an end-to-end churn prediction pipeline using Logistic Regression, Random Forests, and XGBoost.

Algorithm Comparison: Linear vs. Tree Ensembles

Model Interpretability Handling Non-Linearity Feature Scaling Required?
Logistic Regression High (odds ratios from coefficients). Poor (requires manual interaction terms). Yes (mandatory for gradient descent).
Random Forest Medium (feature importance). High (deep bagged trees). No (invariant to monotonic scale).
XGBoost / LightGBM High (via SHAP values). State-of-the-art (gradient boosting). No (handles missing data natively).

End-to-End Customer Churn Model with XGBoost

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, roc_auc_score
from xgboost import XGBClassifier

# Generate synthetic subscription customer records
np.random.seed(42)
n = 2000
df = pd.DataFrame({
    'tenure_months': np.random.randint(1, 60, n),
    'monthly_charges': np.random.uniform(20, 120, n),
    'support_tickets': np.random.poisson(lam=2, size=n),
    'contract_annual': np.random.choice([0, 1], n, p=[0.7, 0.3])
})
# Churn probability increases with high tickets, low tenure, and month-to-month contracts
logits = (df['support_tickets'] * 0.4) - (df['tenure_months'] * 0.05) - (df['contract_annual'] * 1.2)
probs = 1 / (1 + np.exp(-logits))
df['churned'] = (probs > 0.50).astype(int)

X = df.drop(columns=['churned'])
y = df['churned']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, stratify=y, random_state=42)

# Train XGBoost Classifier
xgb_model = XGBClassifier(
    n_estimators=150,
    max_depth=4,
    learning_rate=0.08,
    subsample=0.8,
    colsample_bytree=0.8,
    eval_metric='logloss',
    random_state=42
)
xgb_model.fit(X_train, y_train)

# Predict probabilities
y_prob = xgb_model.predict_proba(X_test)[:, 1]
y_pred = (y_prob >= 0.35).astype(int)  # Business-optimized threshold

print(f"ROC-AUC Score: {roc_auc_score(y_test, y_prob):.4f}")
print("\n--- Classification Report (Threshold = 0.35) ---\n")
print(classification_report(y_test, y_pred, target_names=['Retained', 'Churned']))

Handling Extreme Imbalance with scale_pos_weight

In XGBoost, set parameter scale_pos_weight = (total_negatives / total_positives) to automatically scale gradient updates for the minority class without needing external SMOTE resamplers.

Frequently Asked Questions (FAQ) - Student & Interview Review

Q1. What is the Sigmoid activation function in Logistic Regression?

Logistic Regression passes the linear combination of inputs (z = w^T * x + b) through the Sigmoid (logistic) function: sigma(z) = 1 / (1 + e^(-z)). This compresses any real number into a valid probability strictly between 0.0 and 1.0.

Q2. Why are Gradient Boosted Decision Trees (XGBoost/LightGBM) dominant on tabular data?

Tree ensembles sequentially train new trees that specifically target the residual errors of prior trees. They natively handle non-linear interactions, require zero feature scaling, tolerate missing data, and consistently outperform neural networks on structured tabular datasets.

Q3. What is SMOTE (Synthetic Minority Over-sampling Technique)?

SMOTE addresses severe class imbalance by creating synthetic minority class examples. Rather than duplicating existing rows, it identifies k-nearest neighbors in feature space and synthesizes new points along the line segments connecting them.

Q4. How do you select an optimal probability threshold for churn classification?

The default threshold is 0.50. However, if a retention call costs $10 while losing a customer costs $500, lowering the threshold to 0.25 captures significantly more at-risk customers, maximizing net financial ROI.

Q5. What is Early Stopping in XGBoost?

Early stopping halts boosting rounds if validation metric scores fail to improve for n consecutive iterations (e.g., early_stopping_rounds=15), preventing severe overfitting.

Explore Related Data Science Tutorials & Next Steps

Broaden your statistical analysis, Python data wrangling, and production engineering expertise:

Predictive Modeling Workflow

Handle class imbalance using SMOTE and stratified cross-validation.

Classification Metrics: ROC-AUC & PR-Curves

Select optimal classification thresholds to maximize business ROI.

Customer Segmentation & RFM Analysis

Segment customers before predicting their probability of attrition.

FastAPI Model Serving Microservices

Deploy your churn model to a live REST endpoint for instant CRM scoring.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!