Credit Default Detector
Only about a third of applicants default. F1 is measured for the default class, and predicting everyone as safe scores 0.00.
Higher is better. Scored on 20 held-out rows.
Dataset
- class 0
- class 1
Each dot is one training row: feature 1 against feature 2, coloured by class.
What this lab teaches
Imbalanced classification where F1 on the default class - not accuracy - is the whole score, so the threshold and the rare positives decide the run.
About a third positives
The training split has 40 rows with 14 defaults (35%) and the hidden split has 20 rows with 7. The starter's majority rule finds a positive rate of 0.35, so it predicts safe for everyone: 65% accurate, F1 0.00, which is the recorded baseline. The target is 0.85.
What the four features say
Correlations with the default label run from -0.40 on the first feature to +0.64, +0.45, and +0.58 on the others, so the signal is spread across columns rather than sitting in one. Standardized logistic regression reaches hidden F1 about 0.923 - six of seven defaults caught with no false alarms - and the largest weights land on the two middle features after standardization.
The F1 budget on seven positives
With 7 hidden defaults, 6 TP + 0 FP scores 0.923, 6 TP + 1 FP still scores 0.857, but 5 TP + 1 FP is 0.769 and 5 TP + 0 FP is 0.833 - both miss. In other words, one mistake is allowed and two are fatal. That is why returning sensible probabilities and choosing the threshold deliberately matters more here than any extra optimizer tuning.
Common pitfalls
- Choosing the threshold on accuracy. The majority class dominates accuracy while F1 stays at zero, so the two metrics point in different directions.
- Standardizing with statistics computed on the hidden rows. The transform must come from the training split alone, or the score is not reproducible.
- Treating the 0.5 threshold as sacred. With rare positives the best F1 often sits below 0.5, and the harness accepts any monotone score you return.
Rules of the run
- Define predict(train_X, train_y, test_X) and return exactly one value per test row.
- Pure Python or numpy both run; no external data or network access.
- Return a default probability or 0/1 label; values are thresholded at 0.5.
- F1 is computed for the default class (label 1).
Hint
Standardize the four features and fit logistic regression. Raising the decision threshold trades precision for recall.
Reference solution
Revealing doesn't affect your record — but try the hint first.