Class Imbalance
When one answer is rare, accuracy stops meaning anything and most fixes quietly make the model worse. Rebalance a fraud dataset and watch what each repair actually costs.
Worth reading first: Measuring a Model
Chapter seven opened with a model that did nothing and scored 99.7%. This is what to do about it. The answer most tutorials give — rebalance the data — turns out to be an expensive way of doing something you can do for free, and this chapter is mostly about why.
The rare thing is the whole point
Four thousand card transactions. Seventy-five are fraudulent, which is one in fifty-three. Train a perfectly ordinary logistic regression on them, take the usual probability cut-off of 0.5, and it flags nothing at all. Not one transaction. It scores 98.1% accuracy.
The model is not broken and it has not failed to learn. It has learned correctly that under the loss it was handed, guessing “legitimate” every time is the best available strategy. Every fraud costs it a little; every false alarm would cost it a little; there are fifty-three times as many chances to be wrong on the second. The arithmetic is unarguable and the result is useless.
This is what imbalance does. The rare class is always the one you care about — the fraud, the tumour, the failing part — and it is always the one the default loss function is happiest to sacrifice.
1400 held-back transactions, 27 of them fraudulent. Flagging nothing at all scores 98% accuracy, so accuracy is the one number that cannot help you here.
Fit the model on the raw data and take the usual 0.5 cut-off. The maths works perfectly and the result is a model that has noticed the cheapest available strategy.
What it costs: Nothing, which is the problem.
Accuracy
98%Beaten by flagging nothing, in most of these rows.
Recall
0%Of the 27 real frauds, how many were caught.
Precision
—Undefined: it flagged nothing, so nothing can be right.
Now leave the first model exactly as it was trained and move only the cut-off. Every point the three rebalancing strategies reached is somewhere on this curve.
- recall
- precision
flag anything above 0.076 — 56 transactions to review, 8 of the 27 frauds caught
Precision here
14%Share of flagged transactions that were really fraud.
Recall here
30%Share of real frauds this cut-off catches.
F1 here
0.19Rebalancing managed 0.08 for the cost of retraining.
Three ways to rebalance, and what each costs
The standard advice is to fix the data. There are three ways, and you should try all three in the panel above before reading on.
Undersampling keeps every fraud and throws away legitimate transactions until the classes are level. It works, and it means learning the legitimate half of the problem from a few dozen rows out of two and a half thousand. You paid for that data.
Oversampling keeps everything and copies each fraud until the counts match. Nothing is discarded, and nothing is added either — the model sees the same forty-eight frauds fifty times each and becomes confident about their particular quirks rather than about fraud.
Class weighting leaves the rows alone and charges a mistake on a fraud fifty-three times what it charges a mistake on a legitimate transaction. Nothing is duplicated or deleted, which is why it is usually the right one of the three to reach for.
Now the finding that should bother you. All three produce the same result: 59% recall, 4% precision, about 413 transactions flagged. Not similar — the same, to the row. Three different interventions, one outcome.
Moving the threshold instead
If all three are really moving the cut-off, then move the cut-off. Take the original model, trained on the untouched imbalanced data, and flag anything above a probability of 0.025 rather than 0.5.
That reproduces the rebalanced result almost exactly: 59% recall, 4% precision, 372 flagged. Same answer, no retraining, no discarded data, no duplicated rows.
And once the cut-off is a dial rather than an accident, you can put it where the problem actually wants it. At 0.076 the model catches 30% of frauds at 14% precision, flagging 56 transactions instead of 413. By F1 that is 0.19 against the 0.07 all three rebalancing strategies managed — nearly three times better, from changing one number after training.
Which threshold is right is not a question the data can answer. A review team that can process sixty cases a day sets it one way; an automatic block on a customer's card sets it far more cautiously, because the cost of a false positive is a stranded customer. Pick the operating point from the cost of each mistake, then report where you picked it and why.
What to report when the classes are lopsided
Accuracy is the first thing to drop. At 98.1% for a model that flags nothing, it is not merely uninformative here — it actively rewards the failure. Any imbalanced problem where somebody quotes accuracy is a problem where nobody has looked closely.
Report precision and recall as a pair, at a stated threshold, and say how many cases that threshold sends to a human. F1 combines the two into one number, which is convenient for comparing models and hides the trade-off you actually need to argue about, so quote it alongside its parts rather than instead of them.
The uncomfortable summary: for a rare class, most of what you can do is choose which kind of mistake to make. Fifty-three to one is a hard problem, the model here tops out around 14% precision at 30% recall, and no amount of resampling changes the information in the data. Recognising that early is worth more than a better sampler.
Key takeaways
- With one fraud in fifty-three, a correctly trained model flagged nothing at all and scored 98.1% accuracy. It had learned the right answer to the wrong question.
- Undersampling discards data you paid for; oversampling duplicates rows without adding information; class weighting leaves the data alone and is usually the best of the three.
- All three produced identical results here — 59% recall at 4% precision — because for a linear model they all do the same thing: shift where the model starts saying yes.
- Moving the decision threshold on the untouched model reproduced that exact result with no retraining.
- Choosing the threshold deliberately reached F1 0.19 against 0.07 for every rebalancing strategy.
- A cut-off of 0.5 is a library default, correct only when the classes are balanced and both mistakes cost the same.
- Pick the operating point from what each mistake costs, then report precision and recall at that threshold — never accuracy alone.
- Resample the training set if you like. Never resample the test set.