Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mutual-Fund Lead Scoring & Prioritisation Engine

An end-to-end data analytics project that predicts which clients are most likely to take up an investment product, then ranks and routes those leads to advisors under realistic capacity constraints, turning a marketing list into a prioritised call sheet.

A worked example of propensity modelling for retail-banking direct-marketing campaigns: predict product take-up, rank leads by likelihood to convert, and route limited advisor capacity to maximise conversions per contact.


Headline result

Working only the top 20% of scored leads captures ~66% of all conversions: 3.3× more than random targeting, at 3.8× the value per advisor call.

Cumulative gains

See the full write-up in reports/executive_summary.md.


Why this problem

Advisors can only call a fraction of available leads. Treating every prospect as equally promising wastes the scarcest resource: advisor time. A propensity model that ranks leads lets the team concentrate effort where it converts, driving both acquisition (new subscribers) and retention (re-engaging warm prior-campaign clients).

Dataset

UCI Bank Marketing (bank-additional-full.csv): 41,188 real direct-marketing contacts from a retail bank, with client demographics, campaign/contact history, and macro-economic indicators. The term-deposit subscription target stands in for mutual-fund take-up. Base conversion rate: 11.3%.

Not committed to the repo (see .gitignore). Re-fetch with the command in Reproduce.

Data & privacy

The data is publicly released for research and is de-identified: it contains no names, account numbers, phone numbers, or addresses, only coarse demographic and campaign attributes. The dataset documentation notes that some attributes were withheld from the original source "due to privacy concerns," and the records date from 2008 to 2010. It is used here strictly for educational analysis; any production use of comparable client data would fall under applicable privacy law (such as PIPEDA or GDPR), data governance, and access controls.

Moro, S., Cortez, P., & Rita, P. (2014). A Data-Driven Approach to Predict the Success of Bank Telemarketing. Decision Support Systems, 62, 22-31. https://doi.org/10.1016/j.dss.2014.03.001

Pipeline / architecture

data/raw (CSV)
   │  src/load_to_sqlite.py
   ▼
SQLite  ──►  sql/eda_queries.sql        # SQL layer: business EDA
   │  src/features.py                   # leakage handling + engineered fields
   ▼
src/train.py        ──►  models/        # LogReg baseline + XGBoost challenger
   │                     reports/metrics.json
   ▼
src/prioritize.py   ──►  ranked leads + ROI / strategy comparison
   │
   ▼
src/visuals.py      ──►  reports/figures/  +  dashboard/ (Tableau extracts)
Stage Script Purpose
Ingestion load_to_sqlite.py Load raw data into a queryable SQLite store
EDA sql/eda_queries.sql Surface conversion trends by segment, channel, season
Features features.py Derive fields and remove target leakage
Modelling train.py Train and select the lead-scoring model
Lead prioritisation prioritize.py Rank leads and quantify value vs. baselines
Reporting visuals.py, reports/ Figures, dashboard extracts, executive summary

Modelling notes (the analytically interesting bits)

  • Leakage dropped. duration (call length) is excluded: it is unknown before a call, so using it would inflate metrics and be useless for targeting. Honest held-out ROC-AUC: 0.81.
  • Ranking over accuracy. A "predict no for everyone" model scores ~89% accuracy and is worthless. We optimise PR-AUC and top-decile lift instead.
  • Class imbalance (11% positive) handled via class_weight / scale_pos_weight.
  • Interpretable baseline. Logistic Regression is kept alongside XGBoost; in a regulated bank, an explainable model matters.

Results (held-out test set)

Model ROC-AUC PR-AUC Top-10% precision Top-10% lift
Logistic Regression 0.80 0.46 51% 4.5×
XGBoost (selected) 0.81 0.49 53% 4.7×

Validation & robustness

  • Generalisation is checked, not assumed. src/diagnostics.py reports the train/test gap and 5-fold cross-validation: XGBoost lands at train 0.83 vs test 0.81 (gap ~0.02) with CV 0.796 +/- 0.003, and the logistic baseline shows effectively no gap. All estimates cluster at 0.79 to 0.81, so the held-out headline is not a lucky split.
  • Early stopping + regularisation. XGBoost is fit with early stopping on a validation slice (selecting ~183 trees) plus shallow depth, row/column subsampling, min_child_weight, and L2, keeping the train/test gap near 0.02.
  • Multicollinearity inspected. src/correlation_check.py writes a correlation heatmap and VIF table. The macro-economic features are collinear by construction (VIF > 30), which is expected and harmless for a tree model, so no features are dropped on correlation grounds.

Dashboard

dashboard/ holds Tableau/Power BI-ready extracts (decile gains, strategy comparison, segment / channel / monthly / prior-outcome performance) plus the full scored lead list (data/processed/prioritized_leads.csv) for an interactive lead-prioritisation view.

Reproduce

# 1. environment
python -m venv .venv && .venv/Scripts/python -m pip install -r requirements.txt

# 2. data
curl -L -o data/raw/bank+marketing.zip \
  "https://archive.ics.uci.edu/static/public/222/bank+marketing.zip"
#    unzip the nested bank-additional.zip and place bank-additional-full.csv in data/raw/

# 3. run the pipeline
.venv/Scripts/python src/load_to_sqlite.py
.venv/Scripts/python src/train.py
.venv/Scripts/python src/prioritize.py
.venv/Scripts/python src/visuals.py

# optional: validation + multicollinearity checks
.venv/Scripts/python src/diagnostics.py
.venv/Scripts/python src/correlation_check.py

Tech stack

Python (pandas, scikit-learn, XGBoost, SHAP, matplotlib) · SQL (SQLite) · Tableau/Power BI (dashboard extracts).

Roadmap (full version)

  • AWS deployment: raw data in S3, query via Athena, scoring on Lambda/SageMaker
  • Published interactive Tableau Public dashboard
  • Model monitoring (drift) + fairness review
  • R / SAS parallel implementation of the scoring model

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages