Concepts / Imbalanced Binary Classification

Imbalanced Binary Classification

On an imbalanced task, the overall average in a classification report is dominated by the larger class. The row for the minority class is where a failure is most likely to be hidden, so that row deserves direct attention.

  • Programming

Why an Average Can Hide a Failing Class

Many learners treat the output of a classifier as if the final label were fixed by the model itself. You call predict, a label comes back, and it feels as though the model has settled the question. This section challenges that belief. The label you receive is the result of applying a cutoff to a score, and that cutoff is a choice that can be moved. Moving it changes which samples count as positive, which changes precision and recall, and sometimes changes the result you were hoping for.

The setting for this article is an imbalanced binary task. The negative class is much larger than the positive class, and the split sizes make that visible. The training portion has 400 negative points and 50 positive points. The test portion has 104 negative samples and 9 positive samples. Because the classes are so uneven, a classifier can spend most of its effort on the large class, and the numbers in a classification report reflect that skew.

SplitClass 0 (negative)Class 1 (positive)
Training portion40050
Test portion1049

Class sizes in the imbalanced binary setting

Key point

On an imbalanced task, the overall average in a classification report is dominated by the larger class. The row for the minority class is where a failure is most likely to be hidden, so that row deserves direct attention.

Tracing One Score Through the Cutoff

A classifier that exposes decision_function produces a degree of certainty for each sample, not just a yes or no. Each sample receives a score. Turning that score into a label requires a cutoff. For binary classification the default cutoff is 0 for decision_function. A sample whose score sits above the cutoff is labeled as the positive class, and a sample below it is labeled as the negative class.

Follow the illustrative scores below through the default cutoff. Each point is compared with the cutoff, and the side it lands on decides its label. The scores here are invented to show the mechanism; they are not taken from the source's model.

score -1.2labeled class 0score -0.4labeled class 0cutoff 0default fordecision_functionscore 0.3labeled class 1score 1.1labeled class 1
Where does each score fall relative to the cutoff at 0, and which side of the cut determines whether the point is labeled positive or negative?

The same rule applies to every sample. A score above the cutoff produces the positive label, and a score below it produces the negative label. Nothing about the model's fitted parameters is consulted at this step. Only the score and the cutoff are compared.

What a Decision Threshold Is

Definition

A decision threshold is the cutoff applied to decision_function output (default 0) or predict_proba output (default 0.5) to assign class labels, and it can be changed without retraining the model.

Probability outputs are often easier to reason about. Their values lie on a fixed scale from 0 to 1, and they are meant to represent the model's probability for the positive class. With the default threshold of 0.5, a point is classified as positive when the model is more than 50 percent confident. Raising the threshold means the model must be more confident before it makes a positive decision. It also means the model can be less confident before making a negative one.

Key point

Retraining is not required to change the threshold. The same fitted model, with the same scores, can produce different labels simply because the cutoff moved. That is why the threshold is a decision you make about the application rather than a property the model has learned.

Lowering the Cutoff and Watching Labels Change

Before looking at any numbers, commit to a prediction. Suppose the positive class matters a great deal, and you want the model to find as many positive samples as possible, even if it occasionally flags a negative sample by mistake. You lower the decision_function cutoff from 0 to a value near -0.8, so more points count as positive. Think about what should happen to recall for the positive class, and what should happen to precision.

What do you think happens?

When the positive-class cutoff moves from 0 to -0.8, what happens to recall and precision for class 1?

  • Recall rises and precision falls

  • Recall falls and precision rises

  • Both recall and precision rise

  • Neither changes, because the model was not retrained

Reveal answer
Answer:

Recall for class 1 rises, and precision for class 1 tends to fall.

Lowering the threshold for the positive class tends to raise its recall and lower its precision, because more samples are labeled positive, including more false positives. Retraining is not needed for this to happen.

Now trace what happens to individual points. The illustrative sample below has a score of -0.5. Under the default cutoff of 0, it sits below the line and is labeled class 0. Under the lowered cutoff of -0.8, it sits above the line and is labeled class 1. Its score did not change, and the model was not retrained. Only the cutoff moved.

score -0.5 pointclass 0 at cutoff 0score -0.5 pointclass 1 at cutoff -0.8score -1.2 pointclass 0 at cutoff 0score -1.2 pointclass 0 at cutoff -0.8score 0.3 pointclass 1 at cutoff 0score 0.3 pointclass 1 at cutoff -0.8
When the threshold moves from 0 to -0.8, which point changes label, and what does that do to the counts for each class?

Every point that lies between the two cutoffs changes label, and every point outside that band keeps its label. Points that move from class 0 to class 1 can be correct or incorrect, depending on their true labels. Correct moves raise the true positive count. Incorrect moves raise the false positive count. Recall for class 1 grows when the first kind of move dominates, and precision for class 1 drops when the second kind is common.

Worked example

Recomputing precision and recall at two cutoffs

The test portion contains 9 positive samples. Suppose that at the default cutoff the model labels 5 samples as positive, and 3 of those are truly positive. At the lowered cutoff the model labels 13 samples as positive, and 6 of those are truly positive. These counts are illustrative and are not from the source's model. Compute precision and recall for class 1 at both cutoffs.

  1. 1
    Identify the counts at the default cutoff

    TP is 3, because 3 of the 5 positive labels are correct. FP is 2, because 5 minus 3 leaves 2 wrong positive labels. FN is 6, because 9 truly positive samples minus 3 found leaves 6 missed.

  2. 2
    Compute the default-cutoff values

    Precision is 3 divided by 5, which is 0.60. Recall is 3 divided by 9, which is about 0.33.

  3. 3
    Identify the counts at the lowered cutoff

    TP is 6, so 6 of the 13 positive labels are correct. FP is 7, because 13 minus 6 leaves 7 wrong positive labels. FN is 3, because 9 minus 6 leaves 3 missed.

  4. 4
    Compute the lowered-cutoff values

    Precision is 6 divided by 13, which is about 0.46. Recall is 6 divided by 9, which is about 0.67.

  5. 5
    Compare the direction of change

    Recall for class 1 rose from about 0.33 to about 0.67, and precision fell from 0.60 to about 0.46. This matches the direction predicted for lowering the positive-class cutoff.

Result

Lowering the cutoff raised recall for class 1 and lowered its precision, with the change coming from more samples labeled positive.

Best practice

When a reported value does not match your expectation, recompute it from the counts. If the arithmetic agrees, the surprise lies in the threshold or the data rather than in the metric. If the arithmetic does not agree, the divergence lies in how the metric was computed.

Recovering TP, FP, and FN from a Report

A classification report hides its counts behind a few decimals, but the counts are what you need when you want to understand a failure. TP counts true positives, FP counts false positives, and FN counts false negatives. Precision asks how many of the samples labeled positive really are positive. Recall asks how many of the truly positive samples were found.

Rule

Both formulas share the true positive count in the numerator, which is why precision and recall move together in some situations and pull apart in others once the threshold changes. The denominator of precision collects everything labeled positive. The denominator of recall collects everything that is truly positive. To recover the counts from a report, work backward. If you know the precision and the number of predicted positives, TP is their product. FN then follows from the number of truly positive samples minus TP.

TPshared numeratorTPshared numeratorTP + FPall labeled positiveTP + FNall truly positive
How do the true positive, false positive, and false negative counts combine into the precision and recall values shown in the report?

Read the per-class rows of the report rather than only its averages. The row for class 1 is where a divergence from what you wanted usually appears. Its recall may be small while its precision is mixed, and the overall average can still look respectable because class 0 dominates it. Class 0 often shows the mirror image: when class 1 recall climbs, class 0 precision tends to rise and class 0 recall tends to fall.

Mistakes When Tuning the Threshold

  • Common mistake

    Assuming the label is fixed by the model

    What it looks like

    Calling predict and treating the returned label as the model's final answer, with no consideration of the cutoff behind it.

    Why it fails

    The label is the result of comparing a score with a cutoff. The cutoff can be moved without retraining.

    Do this instead

    Identify the score and the cutoff that produced each label, and treat the cutoff as a decision about the application.

  • Common mistake

    Reading only the averages

    What it looks like

    Seeing a strong overall average in a report and concluding that the minority class is handled well.

    Why it fails

    The averages are dominated by the larger class, so a weak minority row can hide inside a strong average.

    Do this instead

    Check the row for the class you care about, and compare per-class rows when diagnosing a change.

  • Common mistake

    Tuning the threshold on the test set

    What it looks like

    Trying many cutoffs, scoring each one on the test portion, and keeping the best.

    Why it fails

    The source says that setting a decision threshold on the test set tends to produce overly optimistic results, in the same way that tuning any other parameter on the test set does.

    Do this instead

    Choose the threshold on a validation set or with cross-validation, and keep the test portion for the final evaluation.

  • Common mistake

    Expecting a universal cutoff value

    What it looks like

    Copying a threshold from another project and assuming it will work on a different model.

    Why it fails

    The source gives no rule of thumb for a specific threshold. Because decision_function outputs can take arbitrary ranges, the right cutoff depends on the model and the data.

    Do this instead

    Expect to search for the cutoff, guided by which errors your application can tolerate.

  • Common mistake

    Forgetting that probability outputs need honest calibration before a cutoff on them means much

Choosing the Threshold Without Leaking the Test Set

Once you see that the threshold changes the outcome, it is tempting to try many values and keep the one that looks best. The question is where you do that search. The threshold should be chosen on a validation set or with cross-validation. The test portion is held back so that the final model is evaluated on data it has not been used to shape. Searching over the test portion lets its information leak into the decision, and the resulting numbers look better than the model will perform on new data.

Training portionfit the modelValidation or CVfoldssearch over cutoffsChosen thresholdfixed before testingTest portionheld back for one finalevaluationscoresbest cutoffapply once
Which data partition is used to pick the threshold, and which is held back to evaluate the final model without leaking information?

Practice: Predict the Direction of Each Change

MEDIUM

A classifier with a positive-class cutoff of 0 reports recall 0.33 and precision 0.60 for class 1 on a test portion with 9 positive samples. You raise the cutoff so that fewer samples are labeled positive. Predict whether class 1 recall goes up or down, and whether class 1 precision goes up or down. Then recompute both values from TP, FP, and FN after you assume that the change removes one false positive and one true positive from the original counts.

Hints
  • Raising the cutoff labels fewer samples as positive, which is the reverse of lowering it.
  • Start from the default counts: TP is 3, FP is 2, and FN is 6.
  • Removing one true positive increases FN by one, and removing one false positive shrinks the labeled-positive pool.

Key Takeaways

  • A decision threshold is the cutoff applied to decision_function output (default 0) or predict_proba output (default 0.5) that turns scores into class labels, and it can be changed without retraining.
  • Lowering the positive-class cutoff tends to raise recall for class 1 and lower its precision, because more samples are labeled positive, including more false positives.
  • Precision is TP divided by TP plus FP, and recall is TP divided by TP plus FN, so the three counts can be recovered from a report and recomputed when a value looks surprising.
  • On imbalanced tasks, read the per-class rows, since the averages are dominated by the larger class.
  • Choose the threshold on a validation set or with cross-validation, and never by repeatedly tuning on the test set.

Related concepts

More concepts starting with I