machine learning
python
ValueError
pos_label
classification error

ValueError pos_label1 is not a valid label array'neg', 'pos', dtype'U3'

Master System Design with Codemia

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

Introduction

This scikit-learn error appears when a binary metric expects the positive class label to be 1, but your actual labels are strings such as "neg" and "pos". The metric default and the label representation do not match, so scikit-learn cannot decide which class is supposed to be “positive.”

Why the Error Happens

Many binary metrics in scikit-learn assume pos_label=1 unless you say otherwise. That works for numeric labels like 0 and 1, but not for string labels.

python
1from sklearn.metrics import precision_score
2
3y_true = ["pos", "neg", "pos", "neg"]
4y_pred = ["pos", "pos", "neg", "neg"]
5
6# precision_score(y_true, y_pred)  # can raise the ValueError

The metric is looking for a label value of 1, but the available labels are "neg" and "pos".

Fix It by Setting pos_label

If you want to keep string labels, the simplest solution is to specify the positive class explicitly.

python
1from sklearn.metrics import precision_score, recall_score, f1_score
2
3y_true = ["pos", "neg", "pos", "neg"]
4y_pred = ["pos", "pos", "neg", "neg"]
5
6print(precision_score(y_true, y_pred, pos_label="pos"))
7print(recall_score(y_true, y_pred, pos_label="pos"))
8print(f1_score(y_true, y_pred, pos_label="pos"))

This is often the cleanest answer because it keeps the class labels human-readable and fixes the metric configuration directly.

Or Encode Labels Numerically

If the rest of your pipeline prefers numeric labels, encode them once and keep the mapping consistent.

python
1from sklearn.preprocessing import LabelEncoder
2from sklearn.metrics import precision_score
3
4le = LabelEncoder()
5y_true = ["pos", "neg", "pos", "neg"]
6y_pred = ["pos", "pos", "neg", "neg"]
7
8y_true_num = le.fit_transform(y_true)
9y_pred_num = le.transform(y_pred)
10pos_index = int(le.transform(["pos"])[0])
11
12print(le.classes_)
13print(precision_score(y_true_num, y_pred_num, pos_label=pos_index))

This works, but it also means you now have to preserve the label mapping so later metrics and reports stay consistent.

Binary Versus Multiclass Matters

pos_label only makes sense for binary classification. If your task is multiclass, the correct fix is usually to use an average mode such as macro, micro, or weighted instead of forcing a binary positive label.

python
1from sklearn.metrics import precision_score
2
3y_true = ["cat", "dog", "bird", "dog"]
4y_pred = ["cat", "dog", "dog", "dog"]
5
6print(precision_score(y_true, y_pred, average="macro"))

Do not try to solve a multiclass evaluation problem by tweaking pos_label unless you truly intend a one-vs-rest interpretation.

Validate Labels Before Computing Metrics

A small validation helper can make debugging clearer.

python
1def ensure_positive_label_exists(y_true, y_pred, positive_label):
2    labels = set(y_true) | set(y_pred)
3    if positive_label not in labels:
4        raise ValueError(f"positive label {positive_label!r} not in labels {sorted(labels)}")
5
6
7ensure_positive_label_exists(y_true, y_pred, "pos")

This is especially useful in notebooks or automated reports where metric failures otherwise appear far downstream from the real cause.

Keep Metric Configuration Centralized

If one notebook uses "pos" as the positive class and another silently relies on defaults, your evaluation will become inconsistent. A small wrapper helps keep that policy explicit.

python
1from sklearn.metrics import precision_score, recall_score
2
3
4def binary_report(y_true, y_pred, positive_label):
5    ensure_positive_label_exists(y_true, y_pred, positive_label)
6    return {
7        "precision": precision_score(y_true, y_pred, pos_label=positive_label),
8        "recall": recall_score(y_true, y_pred, pos_label=positive_label),
9    }
10
11
12print(binary_report(["pos", "neg"], ["pos", "pos"], "pos"))

This keeps metric semantics reviewable instead of scattered through different scripts.

Common Pitfalls

A common mistake is relying on default metric settings while using non-numeric class labels.

Another mistake is mixing raw string labels and encoded numeric labels across different parts of the same evaluation pipeline.

Developers also often use pos_label in multiclass settings where an averaging strategy would be the real fix.

Finally, if you encode labels numerically, document the mapping. Otherwise later reports can become ambiguous.

Summary

  • The error means the metric expected positive label 1, but your labels are something else.
  • Set pos_label explicitly when using string labels such as "pos" and "neg".
  • Alternatively, encode labels numerically and keep the mapping consistent.
  • Use average= for multiclass metrics instead of forcing binary semantics.
  • Centralize metric policy so evaluation stays consistent across runs and reports.

Course illustration
Course illustration

All Rights Reserved.