All Data Labs

Machine learning

Credit Card Default Prediction

hard4–5 hours2 datasetsPremium

The whole brief is open to read. This lab's datasets come with Premium.

Company
Capital One
Job positions
Data ScientistML EngineerData Analyst
Topics
ClassificationCredit riskData leakageExpected profitscikit-learn

The scenario

Capital One: Build a model that predicts which credit card applicants will default, decide who to approve, and explain each rejection.

When somebody applies for a Capital One credit card, the company decides whether to approve them, knowing some will stop repaying, which is what defaulting means. A rejected applicant is entitled by law to the main reasons why, which lenders call adverse action reasons, and age cannot be one of them. You're a data scientist on the credit policy team, which wants to approve more applicants without more loss.

Your task

Predict each applicant's chance of defaulting, meaning 90 or more days past due in the first year, set the approval cutoff that makes the most profit, and give reasons for every rejection.

Instructions

  1. 1Load and clean the applications. Check for repeated records and missing values, and explain how you handled each.
  2. 2Decide which columns a decision could actually use. Some are filled in only after an account has been opened, and the decision cannot rest on an applicant's age.
  3. 3Explore how often accounts default, and how that rate moves with the bureau score, balances, recent credit checks and past late payments.
  4. 4Build a baseline from the bureau score alone, then train and compare at least two models on area under the ROC curve, or AUC, validating on later applications than you trained on.
  5. 5Choose an approval cutoff from expected profit. An approved account that keeps paying is worth $420 in its first year, and one that defaults costs 55 percent of the credit line the applicant asked for.
  6. 6For every application you would reject, give the main reasons behind it, ranked, in words the applicant would understand.
  7. 7Score applications_test.csv and save predictions.csv with the columns application_id, default_probability, decision (approve or decline) and decline_reasons, left empty for approvals.

Datasets

All files come in one download.

applications_train.csv

About 15,000 card applications from January to September 2024, each with how the account went in its first year.

15,207 rows · 21 columns · 1.4 MB

ColumnTypeDescription
application_idintegerUnique ID of the application.
applied_ondateDate the application was submitted.
applicant_ageintegerThe applicant's age in years.
annual_income_usdintegerIncome the applicant stated, in US dollars. Zero for some retired applicants, who reported no earned income.
employment_typetextsalaried, self_employed, contract or retired.
employment_yearsintegerYears with the current employer. Empty where the applicant left it blank.
housingtextmortgage, rent, own or other.
statetextUS state the applicant lives in.
zip_median_income_usdintegerMedian household income of the applicant's ZIP code, from census data.
bureau_scoreintegerCredit bureau score from 300 to 850. Empty for applicants with too little credit history to score.
credit_history_monthsintegerMonths since the applicant's oldest credit account was opened.
open_accountsintegerCredit accounts currently open.
total_credit_limit_usdintegerTotal limit across the applicant's existing revolving accounts.
revolving_balance_usdintegerBalance currently carried on those accounts.
inquiries_last_6mintegerCredit checks run on the applicant in the last six months.
delinquencies_last_24mintegerPayments 30 or more days late in the last two years.
months_since_last_delinquencyintegerMonths since the applicant was last late. Empty means they have never been late.
requested_credit_line_usdintegerCredit line the applicant asked for.
assigned_credit_line_usdintegerCredit line the account was given. Set when the account is opened.
first_year_spend_usdintegerSpend on the account over its first year.
ever_90dpd_12minteger1 if the account went 90 or more days past due within twelve months, otherwise 0. This is what you predict.
Preview the first 5 rows
application_idapplied_onapplicant_ageannual_income_usdemployment_typeemployment_yearshousingstatezip_median_income_usdbureau_scorecredit_history_monthsopen_accountstotal_credit_limit_usdrevolving_balance_usdinquiries_last_6mdelinquencies_last_24mmonths_since_last_delinquencyrequested_credit_line_usdassigned_credit_line_usdfirst_year_spend_usdever_90dpd_12m
7000012024-01-014265000self_employed19mortgageFL695006191794241001691240empty12000530057501
7000022024-01-016220808retired0rentVA505006982994119003708447120001050039500
7000032024-01-014173000salaried3ownNY9750059214461190064182062120001170055000
7000042024-01-0147117500salaried15ownIL112500724267528500000empty6000540029500
7000052024-01-014283000salaried2rentTN126000682142337200306103080250020009000

applications_test.csv

About 5,000 applications from October to December 2024, without the outcome.

5,022 rows · 20 columns · 469 KB

ColumnTypeDescription
application_idintegerUnique ID of the application.
applied_ondateDate the application was submitted.
applicant_ageintegerThe applicant's age in years.
annual_income_usdintegerIncome the applicant stated, in US dollars.
employment_typetextsalaried, self_employed, contract or retired.
employment_yearsintegerYears with the current employer. Empty where the applicant left it blank.
housingtextmortgage, rent, own or other.
statetextUS state the applicant lives in.
zip_median_income_usdintegerMedian household income of the applicant's ZIP code, from census data.
bureau_scoreintegerCredit bureau score from 300 to 850. Empty for applicants with too little credit history to score.
credit_history_monthsintegerMonths since the applicant's oldest credit account was opened.
open_accountsintegerCredit accounts currently open.
total_credit_limit_usdintegerTotal limit across the applicant's existing revolving accounts.
revolving_balance_usdintegerBalance currently carried on those accounts.
inquiries_last_6mintegerCredit checks run on the applicant in the last six months.
delinquencies_last_24mintegerPayments 30 or more days late in the last two years.
months_since_last_delinquencyintegerMonths since the applicant was last late. Empty means they have never been late.
requested_credit_line_usdintegerCredit line the applicant asked for.
assigned_credit_line_usdintegerCredit line the account was given. Set when the account is opened.
first_year_spend_usdintegerSpend on the account over its first year.
Preview the first 5 rows
application_idapplied_onapplicant_ageannual_income_usdemployment_typeemployment_yearshousingstatezip_median_income_usdbureau_scorecredit_history_monthsopen_accountstotal_credit_limit_usdrevolving_balance_usdinquiries_last_6mdelinquencies_last_24mmonths_since_last_delinquencyrequested_credit_line_usdassigned_credit_line_usdfirst_year_spend_usd
7151942024-10-013496500contract11rentSC1330005941111208006920204712000122006950
7151952024-10-015343000salaried13mortgage TN 760006802602180001539600empty250028001000
7151962024-10-0148146000salaried21rentAL1785007711736487001281210empty600050002750
7151972024-10-013555500salaried15rentTX705005761773123007692216800028002250
7151982024-10-0149102000salariedemptymortgageNY126000724168522700040empty400041001400

Hints

A column that only exists once an account has been opened cannot help you decide a new application, however well it predicts the outcome. Check each one against the moment the form is submitted.

The reason for a decline comes from that applicant's own contribution to their score, not from which features matter most across everybody.

contribution = coefficients * applicant_scaled
contribution.sort_values(ascending=False).head(3)

Deliverable

A public GitHub repo with your analysis (a notebook or scripts), predictions.csv for the test applications, and a README with the columns you excluded, your model comparison and the cutoff you chose.

When you're done, post your repo in the Solutions tab to share it with other learners.

What grading checks

Use this checklist to review your own work before you post and share it.

  • Submitted GitHub repo is public and reachable.
  • Repo contains at least one notebook or script file.
  • predictions.csv has a probability, a decision and reasons for every test application.
  • default_probability reaches an area under the ROC curve of at least 0.81 on the test applications.
  • Under the cost assumptions in the brief, the approved applications are worth more than approving every applicant.
  • Columns that only exist after an account is opened are excluded with the reason explained, and the applicant's age is excluded from the decision.
  • Models are compared against a bureau score baseline, and decline reasons differ between applicants rather than repeating one list.