Skip to content
Aditya Aryan, home

01 / live dashboard / 43,193 contacts / in your browser

Who actually says yes.

A Portuguese bank phoned people to sell a fixed-term savings account and logged 45,211 calls. Of the 43,193 with complete records, only 11.6% said yes. Filter by job, marital status, education, month or balance, and watch that number move.

Python · scikit-learn · SQLite · originally Dash and Plotly

Loading the dashboard…

Can a model tell who’ll say yes?

I trained three models on most of the calls and tested them on the rest, which they had never seen. The best was gradient boosting: hand it one person who said yes and one who said no, and it picks the right one about 92 times in 100.

Two things I checked before trusting that. 88% of people said no, so a model that always guesses no is right 88% of the time, which is why I didn’t score it on plain accuracy. And its strongest clue is how long the call lasted, which you only know once the call is over. Take that away and it still picks the right one about 76 times in 100.

The scores for all three models
Classifier performance on the held-out test split.
ModelAccuracyPrecisionRecallF1ROC AUC
Logistic regressionScaled features, 1000 iterations.0.90270.64680.35760.46060.9099
Decision treeUnpruned, on unscaled features.0.87130.45010.48510.46690.7036
Gradient boostingScikit-learn defaults, scaled features.0.90640.65070.41930.51000.9164

Trained on 80% of the cleaned rows and scored on the other 20%, split so both halves carry the same yes rate. Without call length, gradient boosting scores 0.7645 ROC AUC.

What gradient boosting leaned on

  1. duration50.3%
  2. poutcome_success19.7%
  3. pdays6.6%
  4. housing_yes4.9%
  5. age4.8%
  6. month_mar4.5%
  7. month_oct1.6%
  8. month_sep1.3%
  9. balance1.0%
  10. month_may0.8%

Are those differences real, or luck?

Real. Job, education, having a home loan, and how the last campaign went each change how often people say yes, by far more than chance would explain. So the gaps in the charts above aren’t noise.

The 5 tests behind that
Hypothesis tests run against the cleaned dataset.
QuestionTestStatisticpn
Balance by previous outcomeMean balance of contacts whose last campaign succeeded against those where it failed.Welch t-test4.291.91e-56,133
Job against subscriptionWhether subscription rate is independent of job.Chi-squared772.491.69e-15943,193
Education against subscriptionWhether subscription rate is independent of education.Chi-squared233.402.08e-5143,193
Housing loan against subscriptionWhether subscription rate is independent of housing loan.Chi-squared825.281.72e-18143,193
Previous outcome against subscriptionWhether subscription rate is independent of previous outcome.Chi-squared4027.72< 1e-30043,193

How the data was cleaned.

The charts don’t read the raw file. 2,018 of the 45,211 calls were dropped because the person’s job or education wasn’t recorded, which leaves 43,193.

Every step, with what it cost
  1. 01loaded bank-full.csv45,211 rows
  2. 02dropped campaign and day45,211 rows
  3. 03removed unknown job44,923 rows · −288
  4. 04removed unknown education43,193 rows · −1,730
  5. 05reassigned unknown contact in proportion43,193 rows · 12,286 moved
  6. 06poutcome unknown folded into other43,193 rows

Source: UCI Bank Marketing (bank-full.csv). UCI Machine Learning Repository. Moro, S., Cortez, P. and Rita, P. (2014). A data-driven approach to predict the success of bank telemarketing. Decision Support Systems.

Back to selected work