predict_proba function
probability order
machine learning
classification models
scikit-learn

Why does predict_proba function print the probabilities in reverse order?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

predict_proba is not reversing anything. In scikit-learn, the probability columns are returned in the exact order stored in the model's classes_ attribute, so the output only looks backward when your mental label order does not match the estimator's label order.

This matters most in binary classification, where people often assume the second column is the positive class or the first column is the negative class. Those assumptions are unsafe unless you inspect classes_.

How predict_proba Chooses Column Order

Every classifier that exposes predict_proba keeps a class list after fitting. The returned probability array is aligned to that list.

python
1from sklearn.linear_model import LogisticRegression
2import numpy as np
3
4X = np.array([[0], [1], [2], [3]])
5y = np.array([1, 1, 0, 0])
6
7model = LogisticRegression().fit(X, y)
8
9print("classes_:", model.classes_)
10print("predict_proba:", model.predict_proba([[0.5]]))

If model.classes_ prints [0 1], then the first probability is for class 0 and the second is for class 1. That is true even if you personally think of class 1 as the more important outcome.

Why It Feels Reversed

The confusion usually comes from one of three assumptions:

  • you expect the positive class to come first
  • you expect labels to be returned in the order you first saw them in the training data
  • you switched from numeric labels to string labels and forgot that sorting changed

String labels are especially easy to misread:

python
1X = np.array([[0], [1], [2], [3]])
2y = np.array(["spam", "spam", "ham", "ham"])
3
4model = LogisticRegression().fit(X, y)
5print(model.classes_)
6print(model.predict_proba([[0.5]]))

If the classes print as ['ham' 'spam'], then the first probability column belongs to ham, not spam.

The Safe Way to Read Probabilities

Do not hard-code probability columns unless you also hard-code the label mapping. Pair the probabilities with classes_ directly.

python
1sample = [[0.5]]
2proba = model.predict_proba(sample)[0]
3
4for label, p in zip(model.classes_, proba):
5    print(label, p)

That is the most robust way to inspect output in notebooks, logs, and dashboards.

If you need one specific class, look up its index explicitly:

python
1target_label = "spam"
2target_index = list(model.classes_).index(target_label)
3score = model.predict_proba([[0.5]])[0][target_index]
4
5print(score)

This pattern avoids subtle bugs when a model is retrained with different labels or when class names change.

Binary Classification and the Positive Class

Metrics such as ROC AUC, PR AUC, and threshold-based business rules usually need the probability of one chosen positive class. In that case, you must map that class to the correct column yourself.

python
1positive_label = 1
2positive_index = list(model.classes_).index(positive_label)
3positive_scores = model.predict_proba(X)[:, positive_index]
4
5print(positive_scores)

That is safer than assuming column 1 is always the positive class. In many teams, this mistake silently corrupts evaluation code because the script still runs and produces plausible-looking numbers.

Multiclass Models Follow the Same Rule

The exact same logic applies in multiclass classification. If the model has five classes, the probability matrix has five columns, ordered by classes_.

python
1from sklearn.ensemble import RandomForestClassifier
2
3X = np.array([[0], [1], [2], [3], [4], [5]])
4y = np.array([2, 0, 1, 2, 1, 0])
5
6model = RandomForestClassifier(random_state=0).fit(X, y)
7print(model.classes_)
8print(model.predict_proba([[2.5]]))

Once you stop thinking of the columns as "left" or "right" and start thinking of them as "aligned to classes_", the behavior becomes consistent.

Common Pitfalls

The biggest mistake is assuming the first or second column always corresponds to the class you care about. That assumption breaks as soon as labels or training setup change.

Another common problem is reading probabilities without logging classes_. If the label mapping is not visible, debugging becomes harder than it should be.

People also mix up training sample order and class order. predict_proba does not preserve the order in which labels first appeared in the dataset. It preserves the model's class mapping.

Finally, metric code often grabs the wrong column and still produces valid-looking output. That is dangerous because the bug is semantic, not syntactic.

Summary

  • 'predict_proba columns follow model.classes_.'
  • The function is not reversing the probabilities.
  • Binary and multiclass models both use the same label-order rule.
  • Use zip(model.classes_, proba) to inspect results safely.
  • Look up the target label index explicitly before computing metrics.
  • Never assume a fixed probability column without checking the class mapping.

Course illustration
Course illustration

All Rights Reserved.