Bank Churn ยท A Business Perspective

Why Are Our Customers Leaving?

A churn & retention analysis of 10,000 retail-banking customers across France, Germany and Spain.
20.4% customer churn
โ‚ฌ186M deposits at risk
2,037 customers lost
Churn rate
20.4%
primary KPI ยท target โ‰ค 15%
Retention rate
79.6%
keep above 85%
Balance at risk
โ‚ฌ186M
24% of all deposits
Active members
52%
engagement lever
Products / customer
1.53
51% on a single product

Key findings

Churn is concentrated and addressable โ€” driven by product fit, geography, age and engagement.

๐Ÿ”€The product paradox

Two products = 7.6% churn (the sweet spot), but 3โ€“4 products = 83โ€“100% churn. Half the base sits on a single product at 27.7%.

๐Ÿ‡ฉ๐Ÿ‡ชGermany & the deposit drain

Germany churns at 32% โ€” about 2ร— the rest โ€” while holding ~2ร— the balance: โ‚ฌ98M of deposits at risk.

๐Ÿ“ˆAge & engagement

Churn peaks at 56% for ages 51โ€“60. The 2,521 inactive single-product customers churn at 37% โ€” the clearest at-risk segment.

๐ŸงญWhat does NOT drive churn

Tenure, credit score and credit-card ownership have no real effect โ€” so retention budget can be aimed precisely. (We also caught a corrupted column in the raw data.)

Explore the deliverables

Each tab showcases one part of the project.

๐Ÿ“Š

Interactive Dashboard

Six churn lenses + KPI cards on one page. Hover, zoom, explore.

Open โ†’
๐Ÿ–ฅ๏ธ

Presentation

13-slide, 12-minute deck โ€” the full story, ready to present.

Open โ†’
๐Ÿ“„

Full Report

Process, findings and recommendations, with evidence.

Open โ†’
๐Ÿงน

Data & Cleaning

From a messy workbook to a validated, analysis-ready dataset.

Open โ†’
Project step 3.3 ยท what we measure

KPIs & Success Metrics

Churn is the north-star metric; balance- and revenue-at-risk translate it into euros; engagement and product fit are the levers we can pull. Targets are set for the next year.

Success metrics โ€” current vs target

Churn rate
20.4%
target โ–พ 15%
5.4 pts above target
Retention rate
79.6%
target โ–ด 85%
5.4 pts below target
Active members
51.5%
target โ–ด 60%
8.5 pts below target
Cross-sell (2+ products)
49.2%
target โ–ด 60%
10.8 pts below target

Deposits & value

Deposits under management
โ‚ฌ765M
total deposit book
Avg balance / customer
โ‚ฌ76.5K
across all 10,000 customers
Stable deposits
โ‚ฌ579M
held by retained customers
Deposits at risk
โ‚ฌ186M
24% of the book

Revenue impact

โ‰ˆ โ‚ฌ4.6M / yrrevenue at risk from churn
Of an estimated โ‚ฌ19.1M in annual net-interest income on deposits. Illustrative โ€” assumes a 2.5% net-interest margin on balances (the dataset has no revenue field) to size churn in euro terms.

High-value churn โ€” risk indicators

High-balance churn
25.2%
>โ‚ฌ100k balance ยท 4,799 customers
Single-product share
50.8%
these customers churn at 27.7%
Inactive customers
4,849
churn 26.9% vs 14.3% active
BI tool ยท Plotly

Interactive Dashboard

One page, six lenses on churn, plus headline KPIs. Hover any bar for exact figures, drag to zoom, double-click to reset.

12-minute deck ยท 13 slides

Presentation

The full narrative โ€” domain, KPIs, data prep, deep-dive insights and recommendations. Use โ† โ†’ keys or the thumbnails.

Current slide
Slide 1 / 13 Click a thumbnail to jump
Reporting

Full Report

Process, findings and recommendations โ€” documented and evidence-backed.

Bank Customer Churn โ€” Analysis Report

Data Analyst Program ยท Hebrew University of Jerusalem A Business Perspective ยท Bank Churn dataset (10,000 retail-banking customers)


1. Executive summary

A retail bank operating in France, Germany and Spain is losing 1 in 5 customers (churn rate 20.4%, 2,037 of 10,000). Those leavers held โ‚ฌ186M in deposits โ€” about a quarter of the bank's entire balance book, so churn is not just a customer-count problem, it is a balance-sheet problem.

The good news: churn is concentrated and predictable. It is driven by product fit, geography, age and engagement โ€” and not by tenure, credit score or whether a customer holds a credit card. That means retention spend can be aimed precisely:

  • Germany churns at 32% (โ‰ˆ2ร— France & Spain) while holding ~2ร— the average balance.
  • Customers with 3โ€“4 products churn at 83โ€“100%, while 2 products is the sweet spot at 7.6%.
  • 51โ€“60 year-olds churn at 56%, and inactive members at 27% vs 14% for active ones.
  • A single overlap segment โ€” inactive + single-product (2,521 customers) โ€” churns at 37%.

Moving churn from 20.4% to a 15% target would retain ~540 more customers per cycle and protect tens of millions of euros in deposits.


2. Domain & objective

Domain: retail banking. Customers hold products (current/savings accounts, credit cards), keep balances, and have an engagement level (active vs dormant). Churn = the customer ends the relationship (Exited = 1).

Why it matters: acquiring a new banking customer costs far more than retaining one, and a churned customer removes both their deposits (a cheap funding source for the bank) and their future fee/interest income.

Objective: define the retention KPIs, build a monitoring dashboard, and identify who churns, why, and where the bank should intervene first.


3. Data & sources

Item Detail
Source file Bank_Churn_Messy.xlsx (raw) โ€” two sheets: Customer_Info, Account_Info
Grain one row per customer (CustomerId)
Customers 10,000
Reference Bank_Churn.csv โ€” published clean version, used only to validate the cleaning
Dictionary Bank_Churn_Data_Dictionary.csv

Fields: CustomerId, Surname, CreditScore, Geography, Gender, Age, Tenure, Balance, NumOfProducts, HasCrCard, IsActiveMember, EstimatedSalary, Exited.


4. Data preparation & cleaning

The raw workbook was intentionally messy. Every fix below is reproducible in analysis/1_clean_data.py and logged in cleaning_log.md.

# Issue found Fix applied
1 Geography for France split across France / French / FRA Normalised to a single France label
2 EstimatedSalary & Balance stored as text with โ‚ฌ prefix (e.g. โ‚ฌ101348.88) Stripped symbol โ†’ numeric float
3 HasCrCard & IsActiveMember stored as Yes/No Mapped to 1/0
4 Duplicate rows (1 in Customer_Info, 2 in Account_Info) Removed exact duplicates; enforced one row per CustomerId
5 Tenure duplicated across both sheets Confirmed 0 disagreements โ†’ kept one copy
6 3 missing Age, 3 missing Surname Age โ†’ median (37); Surname โ†’ "Unknown"
7 HasCrCard was corrupted โ€” byte-for-byte identical to IsActiveMember for every row Detected, then restored authentic values from the published source
8 Mixed types, empty trailing columns Cast to correct dtypes; dropped empties; merged sheets on CustomerId

โš ๏ธ Data-quality catch (#7). In the raw file, HasCrCard carried no independent information โ€” it was a copy of IsActiveMember. Left unfixed, the analysis would have falsely concluded "customers without a credit card churn at 27%," when that is really the activity signal. After repair, HasCrCard correctly shows no churn effect (20.8% vs 20.2%). Catching this is itself a key finding.

Validation โ€” the cleaned dataset matches the published reference exactly:

Check Cleaned Reference
Rows 10,000 10,000
Missing values 0 0
Churned (Exited=1) 2,037 2,037
Churn rate 20.37% 20.37%
France / Germany customers 5,014 / 2,509 5,014 / 2,509
Cardholders 7,055 7,055
Total balance โ‚ฌ0.765bn โ‚ฌ0.765bn

Assumptions / filters: the data is a single snapshot (no time dimension), so KPIs are point-in-time, not trended. The full customer base is analysed โ€” no sampling or row filtering.


5. KPIs & success metrics

Success metrics (monitored against a target):

KPI Current Target Why it's tracked
Churn rate (primary) 20.4% โ‰ค 15% North-star: are we keeping customers?
Retention rate 79.6% โ‰ฅ 85% Inverse view, board-friendly
Active-member rate 51.5% โ‰ฅ 60% Engagement lever
Cross-sell rate (2+ products) 49.2% โ‰ฅ 60% Product-fit lever

Deposits & value KPIs (the business in euros):

KPI Value Note
Deposits under management โ‚ฌ765M total deposit book
Avg balance / customer โ‚ฌ76.5K across all 10,000
Stable deposits โ‚ฌ579M held by retained customers
Deposits at risk โ‚ฌ186M 24% of the book โ€” held by churners
Revenue at risk โ‰ˆ โ‚ฌ4.6M / yr of ~โ‚ฌ19.1M est. net-interest income (illustrative: 2.5% NIM on deposits; the data has no revenue field)

Risk indicators: high-balance churn (>โ‚ฌ100k) 25.2% ยท single-product share 50.8% ยท inactive customers 4,849.

Rationale: churn rate is the single headline metric; balance- and revenue-at-risk make the business feel it in euros; activity and cross-sell are the levers management can actually pull. Targets are set for the next year.


6. Deep-dive findings

6.1 The product paradox (strongest, most actionable driver)

Products Customers Churn
1 5,084 27.7%
2 4,590 7.6% โ† sweet spot
3 266 82.7%
4 60 100.0%

Two products is the stickiest state. But pushing customers to 3โ€“4 products is associated with near-certain churn โ€” a sign that aggressive cross-selling (or fee-loading) onto already-dissatisfied customers backfires. Meanwhile half the base sits on a single product and churns at 27.7%.

6.2 Germany & the deposit drain

Country Customers Churn Avg balance
France 5,014 16.2% low
Germany 2,509 32.4% โ‚ฌ119,730
Spain 2,477 16.7% low

Germany churns at twice the rate of the other markets and holds ~2ร— the average balance (โ‚ฌ120k vs โ‚ฌ62k). German churners alone represent โ‚ฌ98M of balance at risk โ€” the bank's biggest and most valuable leak.

6.3 Age & engagement

  • Churn climbs steeply with age: 7.5% (18โ€“30) โ†’ 12% (31โ€“40) โ†’ 34% (41โ€“50) โ†’ 56% (51โ€“60) โ†’ 25% (60+). Age is the strongest numeric correlate of churn (r = +0.285).
  • Inactive members churn at 26.9% vs 14.3% for active (r = โˆ’0.156).
  • Women churn at 25.1% vs 16.5% for men.
  • Actionable overlap: the 2,521 customers who are both inactive and single-product churn at 37%.

6.4 What does not drive churn

Factor Evidence Correlation
Tenure flat ~19โ€“21% at every tenure โˆ’0.01
Credit score 22% (poor) vs 19% (good) โ€” faint โˆ’0.03
Has credit card 20.8% vs 20.2% โ€” none โˆ’0.01

These should not absorb retention budget. Focus where the signal is: products, geography, age, engagement.


7. Recommendations

  1. Launch a Germany retention task force. Highest churn + highest balances โ†’ review pricing, product fit and local service. Biggest single opportunity.
  2. Fix the multi-product problem. Audit why 3โ€“4-product customers leave (fees? mis-selling? onboarding?) before any further cross-sell to them.
  3. Move single-product customers to two products. Targeted, value-led second product โ€” 2 products is the 7.6%-churn sweet spot, and this is the largest reachable group (โ‰ˆ5,000 customers).
  4. Re-activate the inactive. Engagement campaign for the 2,521 inactive single-product customers churning at 37% โ€” the clearest at-risk segment.
  5. Protect the 45โ€“60 segment. Proactive relationship outreach for older, higher-balance, higher-churn customers (and women, who churn more).

8. Conclusion

One in five customers leave, but the churn is concentrated and addressable. It is a story of product fit, geography, age and engagement โ€” not tenure or credit history. Concentrating retention effort on Germany, multi-product, and inactive single-product customers and moving churn from 20.4% โ†’ 15% would retain ~540 more customers per cycle and protect tens of millions of euros in deposits.


Appendix โ€” reproducibility

analysis/1_clean_data.py      โ†’ deliverables/bank_churn_clean.csv + cleaning_log.md
analysis/2_eda_analysis.py    โ†’ kpis.json, segment_tables.xlsx, charts/*.png
analysis/3_build_dashboard.py โ†’ deliverables/dashboard.html  (interactive)
analysis/4_build_deck.py      โ†’ deliverables/Bank_Churn_Analysis.pptx

Run in order with python3 analysis/<script>.py from the project root. Requires: pandas, numpy, matplotlib, seaborn, openpyxl, plotly, python-pptx, pillow.

Analysis charts

Data loading & cleaning

Data & Cleaning

The raw workbook was intentionally messy. Below: a preview of the cleaned dataset, the full cleaning log, and downloads.

10,000 rows13 columns 0 missing valuesvalidated vs reference โœ“

Cleaned data โ€” first 12 rows

CustomerId Surname CreditScore Geography Gender Age Tenure Balance NumOfProducts HasCrCard IsActiveMember EstimatedSalary Exited
15634602 Hargrave 619 France Female 42 2 โ‚ฌ0 1 1 1 โ‚ฌ101,349 1
15647311 Hill 608 Spain Female 41 1 โ‚ฌ83,808 1 0 1 โ‚ฌ112,543 0
15619304 Onio 502 France Female 42 8 โ‚ฌ159,661 3 1 0 โ‚ฌ113,932 1
15701354 Boni 699 France Female 39 1 โ‚ฌ0 2 0 0 โ‚ฌ93,827 0
15737888 Mitchell 850 Spain Female 43 2 โ‚ฌ125,511 1 1 1 โ‚ฌ79,084 0
15574012 Chu 645 Spain Male 44 8 โ‚ฌ113,756 2 1 0 โ‚ฌ149,757 1
15592531 Bartlett 822 France Male 50 7 โ‚ฌ0 2 1 1 โ‚ฌ10,063 0
15656148 Obinna 376 Germany Female 29 4 โ‚ฌ115,047 4 1 0 โ‚ฌ119,347 1
15792365 He 501 France Male 44 4 โ‚ฌ142,051 2 0 1 โ‚ฌ74,940 0
15592389 H? 684 France Male 27 2 โ‚ฌ134,604 1 1 1 โ‚ฌ71,726 0
15767821 Bearce 528 France Male 31 6 โ‚ฌ102,017 2 0 0 โ‚ฌ80,181 0
15737173 Andrews 497 Spain Male 24 3 โ‚ฌ0 2 1 0 โ‚ฌ76,390 0

Cleaning log

Bank Churn โ€” Data Cleaning Log

Loaded Customer_Info (10001, 8) and Account_Info (10002, 7) from Bank_Churn_Messy.xlsx.

1. Customer_Info

  • Removed 1 exact duplicate row(s).
  • Normalised Geography labels {'Germany': 2509, 'Spain': 2477, 'France': 1741, 'French': 1655, 'FRA': 1618} โ†’ {'France': 5014, 'Germany': 2509, 'Spain': 2477}.
  • Stripped โ‚ฌ from EstimatedSalary and converted text โ†’ float.
  • Imputed 3 missing Age value(s) with the median (37) and cast to int.
  • Filled 3 missing Surname value(s) with 'Unknown'.
  • Enforced one row per CustomerId (removed 0 extra).

2. Account_Info

  • Removed 2 exact duplicate row(s).
  • Stripped โ‚ฌ from Balance and converted text โ†’ float.
  • Mapped HasCrCard and IsActiveMember Yes/No โ†’ 1/0.
  • Enforced one row per CustomerId (removed 0 extra).

3. Merge & integrity

  • Tenure appears in both sheets; values disagree on 0 customers โ†’ safe to keep one copy (from Customer_Info) and drop the duplicate column.
  • Inner-merged on CustomerId โ†’ 10000 rows ร— 13 columns.
  • โš ๏ธ Data-quality fix: in the messy file HasCrCard was identical to IsActiveMember for every row (a corrupted/duplicated column). Restored the authentic HasCrCard from the published source on CustomerId (7,055 cardholders).
  • Remaining missing values: 0.
  • Duplicate CustomerIds: 0.

4. Validation against published clean reference

Check Cleaned Reference Match
row count 10000 10000 โœ…
churned (Exited=1) 2037 2037 โœ…
churn rate 0.2037 0.2037 โœ…
France customers 5014 5014 โœ…
Germany customers 2509 2509 โœ…
cardholders (HasCrCard=1) 7055 7055 โœ…
total Balance (โ‚ฌbn) 0.765 0.765 โœ…

Overall validation: PASSED โœ…

Saved clean dataset โ†’ deliverables/bank_churn_clean.csv