Concepts / Predicting Probabilities with Classifiers

Predicting Probabilities with Classifiers

In the source output, the two probabilities in each row add up to 1.

  • Programming

Starting From a Fitted Model

Once a classifier has been fitted, you can ask it for more than a single answer. The method predict_proba returns the model's estimated probabilities for each test sample, so instead of one label per sample you get a full set of numbers describing how likely each class is. In the examples here, a fitted model called gbrt and a test set called X_test are assumed to exist.

Before you read any probability value, read the structure of the result. Probability output is easy to misread when you do not know how it is organized, so the approach in this article is mechanical: run the call, check the shape, then check the values, and only then decide whether the output looks right.

What the Shape Reveals First

predict_proba returns an array whose shape is (n_samples, n_classes). The shape is a pair of numbers: the first counts the samples in the input, and the second counts the classes the model predicts over. The shape tells you the layout of the result but not the values inside it, which is why it is the first thing to check when something looks wrong.

python
Notes on the code
  • gbrt is an already-fitted model and X_test is the test set
  • predict_proba returns one row per test sample
  • shape prints (n_samples, n_classes) for the full test set

What do you think happens?

If you call predict_proba on only the first six test samples, what shape do you expect to print for a two-class model?

  • (2, 6)

  • (6, 2)

  • (6, 6)

  • (1, 6)

Reveal answer
Answer:

(6, 2)

Six samples give six rows, and two classes give two columns. Rows are samples and columns are classes, so the shape is (6, 2).

Reading Rows and Columns

The printed result is a two-dimensional array. Each row is one sample and each column is one class. Reading across a row gives the complete probability picture for that one sample, and reading down a column gives one class's probability across all of the samples in the slice. The grid below shows this layout for six samples and two classes.

Row 0: sample 00.016 | 0.984Column 0: first classRow 1: sample 1Column 1: secondclassRow 2: sample 2Row 3: sample 3Row 4: sample 4Row 5: sample 5
For a given value in the six-by-two output, which row is the sample and which column is the class?
python
Output (expected)
Printed result: a two-dimensional array with six rows and two columns. The first row is 0.016 and 0.984.
Walk through it
  1. 1
    The slice is taken first, so only six samples are passed to the model.
  2. 2
    predict_proba returns a grid with one row per passed sample.
  3. 3
    Printing the array shows the probability values in each row.
Notes on the code
  • X_test[:6] selects the first six samples
  • each printed row is one sample
  • the first row holds the probabilities for the first test sample
Worked example

Reading the first sample's probabilities

The first row of the printed output is 0.016 and 0.984. What does each number mean?

  1. 1
    Identify the row

    The first row is the output for the first test sample, so every number in it describes that one sample.

  2. 2
    Identify the columns

    Column 0 is the first class and column 1 is the second class.

  3. 3
    Read the values

    The model assigns probability 0.016 to the first class and 0.984 to the second class for that sample.

Result

For the first test sample, the second class is far more likely than the first according to the model.

Slicing the Input Changes the Row Count

The expression X_test[:6] is applied to the input before the model is called. Because of this, the number of rows in the output follows the number of rows in the slice, not the size of the full test set. Slicing is a common place for a mismatch to start, because the rows you print may not be the rows you expected.

X_testthe input test set[starts the row selection:6the first six samples]ends the selectionindexed byselectscloses
Which part of X_test[:6] chooses which samples reach predict_proba?

Checking That Each Row Adds to One

In the source output, the two probabilities in each row add up to 1. For a sample in row $i$ with columns for class 0 and class 1, this means $p_{i,0} + p_{i,1} = 1$. The first row confirms this: 0.016 plus 0.984 equals 1. This makes a row a useful check on your own reading. If the two numbers in a row do not add to 1, you may be looking at the wrong row, the wrong column, or a different kind of output than you assumed.

Tracing Where a Mismatch Starts

When a probability result looks wrong, do not begin by questioning the values. Work through the chain from the input to the printed output and check each stage in order. The shape check comes first. If the shape is not what you expect, the problem lies in input selection or in the number of samples, and reading the probability values will not help you find it.

Test set X_testSlice X_test[:6]predict_proba callCheck shapeRead row valuesCheck row sums to 1selectpassreturns arrayshape as expectedread
In what order should you check a probability result that looks wrong?

Mistakes When Reading predict_proba Output

  • Common mistake

    Reading the values before checking the shape

    What it looks like

    Looking at 0.016 and 0.984 and assuming they describe the whole test set

    Why it fails

    Those numbers describe one row. The shape tells you how many rows exist and how many columns to expect.

    Do this instead

    Print the shape first and confirm it matches the number of samples and classes you intended.

  • Common mistake

    Treating columns as samples

    What it looks like

    Assuming that column 0 holds the first six samples

    Why it fails

    Each row is one sample and each column is one class. Columns hold class probabilities, not samples.

    Do this instead

    Read across a row to see one sample's full probability picture, and down a column to see one class across samples.

  • Common mistake

    Forgetting that the slice changes the row count

    What it looks like

    Expecting predict_proba on X_test[:6] to return a row for every test sample

    Why it fails

    The slice is applied before the call, so only the sliced samples are passed to the model and appear as rows.

    Do this instead

    Confirm the slice selects the samples you intended, then check that the number of rows matches it.

  • Common mistake

    Assuming a row's numbers are unrelated

    What it looks like

    Reading the two values in a row as two separate facts with no connection

    Why it fails

    In the source output, the two probabilities in each row add up to 1, so they describe one distribution over the classes.

    Do this instead

    Use the sum of each row as a quick check on whether you are reading the grid correctly.

Practice Reading a Probability Grid

EASY

A colleague runs predict_proba on X_test[:6] for a two-class model and reports that the result has seven rows. Using the chain of checks from this article, where would you look first, and why?

Hints
  • Start with the shape, since it is the first stage in the chain.
  • Think about what the slice selects before the model is called.
  • A row count that does not match the slice points to input selection.

Key Takeaways

  • predict_proba returns an array with shape (n_samples, n_classes), so the shape is the first thing to check when debugging.
  • Each row is one sample and each column is one class; reading across a row gives the full probability picture for that sample.
  • Slicing the input, such as X_test[:6], is applied before the model is called and changes the number of rows, so it is a common source of mismatch.
  • In the source output, each row's probabilities add up to 1, which is a useful check on your reading but not a verdict on model accuracy.
  • When output looks wrong, trace the chain from input selection to shape to values, and only then question the probabilities.

More concepts starting with P