Aakash Singh Dahiya

Customer Analytics / Python · Learning project / Case competition

Customer Churn Analysis — IIFT Case Competition

A Python-based customer churn analysis built for the IIFT Samahva case competition — exploring churn drivers through EDA, feature relationships, and classification modelling on customer behavioural data.

Status
Competition submission
Published
April 2023
Reading time
3 min read
Project type
Python & ML
Complexity
Low
ai-automationpythoncustomer-analytics

Built for IIFT Samahva National Analytics Case Competition (1st Runner-Up)

Context

Identifying churn drivers from customer behavioural and demographic features

Focus

Python — EDA, feature analysis, classification pipeline

Stack

Business Question

Which customer characteristics and behaviours predict churn — and how can an organization identify at-risk customers before they leave? This analysis was developed for the Samahva National Analytics Case Competition at IIFT Delhi, where it contributed to a 1st Runner-Up finish.

Data Sources

A customer dataset with behavioural, demographic and service-usage features — contract type, tenure, monthly charges, payment method, service subscriptions, and a binary churn target.

Approach

A Python analysis covering: data loading and profiling, null handling and type correction, exploratory visualization of churn rates across feature categories, correlation analysis to surface the strongest predictors, and a classification pipeline to model churn probability.

Key Steps

  1. Data profiling — shape, dtypes, null counts, churn rate baseline
  2. EDA — churn by contract type (month-to-month vs annual), tenure band, payment method, and monthly charge distribution using seaborn
  3. Feature relationships — correlation matrix and pairplots to identify multicollinearity and the strongest individual predictors
  4. Modelling — classification pipeline (logistic regression baseline + tree-based comparison), evaluation via confusion matrix and classification report
  5. Insight synthesis — translating model outputs into actionable segment descriptions for the competition presentation

The notebook below walks through the actual pipeline — EDA cells through to the model's classification report.

customer_churn_analysis.ipynbPython 3
In [1]:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
 
df = pd.read_csv('telco_customer_churn.csv')
df.shape
Out[1]:
(7043, 21)
In [2]:
df['Churn'].value_counts(normalize=True).round(4)
Out[2]:
No     0.7346
Yes    0.2654
Name: Churn, dtype: float64
In [3]:
sns.countplot(data=df, x='Contract', hue='Churn')
plt.title('Churn Count by Contract Type')
plt.show()
Out[3]:
Bar chart of churn counts split by contract type
In [4]:
numeric = df[['tenure', 'MonthlyCharges', 'TotalCharges', 'Churn']].copy()
numeric['Churn'] = (df['Churn'] == 'Yes').astype(int)
 
sns.heatmap(numeric.corr(), annot=True, cmap='RdBu_r', center=0)
plt.title('Correlation Matrix Numeric Features')
plt.show()
Out[4]:
Correlation heatmap of tenure, MonthlyCharges, TotalCharges and Churn
In [5]:
sns.kdeplot(data=df, x='MonthlyCharges', hue='Churn', fill=True, common_norm=False)
plt.title('Monthly Charges Distribution by Churn')
plt.show()
Out[5]:
KDE plot of monthly charges split by churn status
In [6]:
X = pd.get_dummies(df.drop(columns=['customerID', 'Churn']), drop_first=True)
y = (df['Churn'] == 'Yes').astype(int)
 
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y
)
 
model = LogisticRegression(max_iter=2000)
model.fit(X_train, y_train)
preds = model.predict(X_test)
 
print(classification_report(y_test, preds, target_names=['No churn', 'Churned']))
Out[6]:
              precision    recall  f1-score   support

    No churn       0.85      0.89      0.87      1294
     Churned       0.65      0.56      0.60       467

    accuracy                           0.81      1761
   macro avg       0.75      0.73      0.74      1761
weighted avg       0.80      0.81      0.80      1761

Key Findings

Month-to-month contract customers showed significantly higher churn rates than annual subscribers — the single strongest categorical predictor. Customers with shorter tenure and higher monthly charges relative to their service bundle were disproportionately represented in the churned group. Payment method also showed a pattern: customers on electronic check payments churned at higher rates than those on automatic bank transfers.

Technologies I Personally Used

Python

pandasnumpyscikit-learnseabornmatplotlib

Analysis

Exploratory Data AnalysisFeature EngineeringClassification

Lessons Learned

  • EDA before modelling is not just good practice — it's where the business insight actually lives; the model confirmed what the distributions already showed
  • For a competition setting, the presentation of findings matters as much as the analysis; translating a confusion matrix into "we can correctly flag 8 in 10 at-risk customers" was more useful to the judges than raw accuracy numbers
  • Segment descriptions (not just predictions) give business teams something to act on

Reflection

What I learned: analytical rigour and business clarity are two different skills — this competition forced me to develop both simultaneously under time pressure.

What I would improve today: survival analysis (time-to-churn) for the tenure variable, and a proper validation framework rather than a single train/test split.

Competition context: Samahva National Analytics Case Competition, IIFT Delhi — SRCC-GBO team finished 1st Runner-Up.

Related work