Decision Values in Linear Classifiers
The row values are the ones from the source.
Why Scores Beat Single Labels
A classifier that only reports a single label for each sample tells you the answer but hides how close the decision was. Many scikit-learn classifiers can do more. Instead of saying only which class a sample belongs to, they can report how strongly they favor each possible class. The main tool for this is the method predict_proba. This article walks through what its output looks like, how to turn that output back into a single predicted label, and why the column positions in that output must be translated into class names with care.
What do you think happens?
How many numbers are in the row that predict_proba returns for that one sample, and what do those numbers add up to?
Reveal answer
Three numbers, summing to 1
The output has one column per class, so a three-class model gives three numbers per sample. For each sample, the probabilities across the classes add up to 1, so each row can be read as a distribution over the classes.
Reading One Row of Probabilities
The output of predict_proba is an array with shape (n_samples, n_classes). Each row belongs to one sample, and each column belongs to one class. A row therefore lists, for a single sample, a probability for every class the model knows about. Because the model is choosing among several classes, the numbers in a row are meant to be read together, not one at a time.
In this formula, p_{ik} is the probability that sample i belongs to class column k, and K is the number of classes. The formula says that the probabilities in each row sum to 1. This is the central property of the output: each row is a distribution over the classes, so a larger value in one column means the model leans more toward that class, and the remaining columns share the rest of the probability.
Checking the first row of the output
The first row of predict_proba for a three-class model contains the values 0.107, 0.784, and 0.109. Which class does this sample lean toward, and do the values behave as the source describes?
- 1Identify the columns
The row has three entries, so there is one column per class. Column 0 holds 0.107, column 1 holds 0.784, and column 2 holds 0.109.
- 2Add the row
0.107 + 0.784 + 0.109 = 1.000, which matches the property that each row sums to 1.
- 3Find the strongest column
The largest value is 0.784 in column 1, the middle column. The sample is most strongly associated with that class.
- 4Note the remaining probability
The other two classes still receive 0.107 and 0.109. The model is not certain, and those smaller values are part of the answer too.
The sample leans most strongly toward the class in column 1, with the other two classes still receiving some probability. The row is read as a single distribution, not three separate facts.
Recovering the Predicted Class with Argmax
A row of probabilities is useful, but often you want one label per sample. You get that label by finding the column with the largest value in each row. This is an argmax operation across columns. The index of the largest entry is the position of the predicted class. The argmax returns a column index, not a class name, so the index still has to be translated before you have a label.
Here the hat over k marks the predicted column for sample i. The expression says: among all columns k, pick the one whose probability p_{ik} is largest. The predicted column index is then used to look up a class name in classes_.
The label dog in the diagram comes from a made-up set of class names, cat, dog, and fish, used only to illustrate the lookup. The row values are the ones from the source. The procedure is what matters: find the largest column, take its index, and translate that index through classes_.
['dog']- argmax(axis=1) takes the largest value in each row, returning column positions
- classes[
pred_index] uses those positions to index the class labels, mirroring how classes_ is used
In the source's run, the argmax results agree exactly with the output of predict. That agreement is what you should expect, because predict chooses the class with the highest probability. If your argmax and predict ever disagree on a trained model, that is a signal to check which class labels you are mapping to, rather than assuming the probability logic is wrong.
Mapping Column Positions to Labels
A column index is only meaningful if you know which class each column stands for. A classifier stores the class labels it learned during fitting in an attribute called classes_. The position of each label in classes_ corresponds to the position of the matching column in the output. So classes_[0] names the class in column 0, classes_[1] names the class in column 1, and so on.
The mapping can look obvious when the labels are plain integers that start at 0 and run consecutively, because the position and the label seem to be the same number. That is exactly why the step is easy to skip. The source points out that classes_ must be used to map positions to names, especially for string labels or for integer labels that are not consecutive. Once the labels are strings like cat, dog, and fish, a position of 1 tells you nothing until you look it up.
Suppose a learner expects column 1 to mean dog, because that is how the labels were listed in a previous script. The model was refit, and classes_ is now fish, cat, dog. The argmax still returns column 1, and the code reports cat. Nothing in the probabilities changed. The bug is in the assumed mapping. The fix is to read classes_ from the fitted model and translate positions through it, instead of hard-coding a list.
- model.classes_ is read from the fitted model, so the mapping always matches the trained column order
Mistakes When Reading Class Columns
Common mistake Treating the argmax index as the class label
What it looks likeReporting 1 as the predicted class because argmax returned 1.
Why it failsThe argmax gives a column position. The source states that this column index is a position, not a label.
Do this insteadTranslate the index through classes_, for example classes_[1], before reporting a class.
Common mistake Assuming the columns follow a remembered label order
What it looks likeUsing cat for column 0 from an older script, even though the refit model stores fish first.
Why it failsThe column order is set by classes_ on the fitted model, so a remembered order can silently disagree with it.
Do this insteadRead model.classes_ after fitting and use it for every mapping.
Common mistake Assuming the same mapping is safe for integer labels
What it looks likeLabels of 2, 5, and 9 are used directly as if they were column numbers 0, 1, and 2.
Why it failsThe source notes that integer labels need care when they are not consecutive from 0, because the label value and the column position no longer match.
Do this insteadAlways map through classes_ rather than assuming the label equals the column index.
Common mistake Checking that each probability row sums to 1 only once and never again, instead of trusting it on new outputs
decision_function Compared with predict_proba
Many classifiers also provide a second method, decision_function, which returns decision values instead of probabilities. The two methods are closely related in shape. In the multiclass case, both predict_proba and decision_function return an array with shape (n_samples, n_classes), one row per sample and one column per class. The argmax-and-classes_ procedure recovers the predicted class from decision_function in the same way it does from predict_proba, so both need the same care when turning column positions into names.
| Method | Multiclass shape | Binary shape | What the columns hold |
|---|---|---|---|
| predict_proba | (n_samples, n_classes) | (n_samples, 2) | One probability column per class, rows sum to 1 |
| decision_function | (n_samples, n_classes) | (n_samples,) with one column for the positive class | One decision value column per class in the multiclass case; in the binary case, a single column for classes_[1] |
Shapes and column meanings for the two methods
The binary case is the one exception. For decision_function, a binary classifier returns only one column of values, which corresponds to the positive class, classes_[1]. The source describes this as a historical convenience. It means that the multiclass recipe of taking an argmax across columns does not apply to that single column in the same way. Instead, you read the one column against the positive class and interpret it as the source describes for that case.
Checking Your Reading of an Output
A model trained on three classes returns, for one sample, the probability row 0.2, 0.5, and 0.3 from predict_proba, with classes_ equal to the labels red, green, and blue in that order. Find the predicted class for this sample, then explain what the other two columns still tell you.
Hints
- Start by identifying which column holds the largest value in the row.
- The argmax gives a column position, so translate that position through classes_.
- Check whether the row adds up to 1 before trusting the values.
Suppose the same model is refit and classes_ becomes blue, red, green, while the probability row for the same sample is unchanged. Which label does the argmax now lead you to, and why did the answer change even though the numbers did not?
Hints
- Compare the position of the largest value before and after the refit.
- Look up the new position in the new classes_ array.
Summary of the Reading Procedure
- 1Confirm the shape: rows are samples and columns are classes.
- 2Read a row as a distribution, since its values sum to 1.
- 3Take the argmax across columns to get the winning column position.
- 4Translate that position into a label with classes_, not by assumption.
- 5For
decision_function, apply the same procedure in the multiclass case, and remember that the binary case returns one column for classes_[1].
At a glance
predict_probareturns an array of shape (n_samples,n_classes): one row per sample, one column per class, with each row summing to 1.- The argmax across each row gives the winning column position, which matches predict when predict picks the highest-probability class.
- A column position is not a label. classes_ stores the labels in column order and must be used to translate positions into class names, especially for string labels or non-consecutive integers.
decision_functionhas the same multiclass shape aspredict_proba, but in the binary case it returns a single column for the positive class, classes_[1].