Repository: scikit-learn/scikit-learn
File: sklearn/metrics/_ranking.py (Python)

Code before:
    xp, _ = get_namespace(y_true, y_score, sample_weight)

    if not get_config().get("array_api_dispatch", False):
        y_true = _convert_to_numpy(y_true, xp=xp)
        y_score = _convert_to_numpy(y_score, xp=xp)
        if sample_weight is not None:
            sample_weight = _convert_to_numpy(sample_weight, xp=xp)

    def _binary_uninterpolated_average_precision(
        y_true,
        y_score,
        pos_label=1,
        sample_weight=None,
        xp=xp,
    ):
        precision, recall, _ = precision_recall_curve(
            y_true,
            y_score,
            pos_label=pos_label,
            sample_weight=sample_weight,
        )
        # Return the step function integral
        # The following works because the last entry of precision is
        # guaranteed to be 1, as returned by precision_recall_curve.
        # Due to numerical error, we can get `-0.0` and we therefore clip it.
        return float(max(0.0, -xp.sum(xp.diff(recall) * precision[:-1])))

    y_type = type_of_target(y_true, input_name="y_true")
    present_labels = xp.unique_values(y_true)

    if y_type == "binary":
        if present_labels.shape[0] == 2 and pos_label not in present_labels:
            raise ValueError(
                f"pos_label={pos_label} is not a valid label. It should be "
                f"one of {present_labels}"
            )

    elif y_type == "multilabel-indicator" and pos_label != 1:
        raise ValueError(
            "Parameter pos_label is fixed to 1 for multilabel-indicator y_true. "
            "Do not set pos_label or set pos_label to 1."
        )

    elif y_type == "multiclass":
        if pos_label != 1:
            raise ValueError(
                "Parameter pos_label is fixed to 1 for multiclass y_true. "
                "Do not set pos_label or set pos_label to 1."
            )
        y_true = label_binarize(y_true, classes=present_labels)
        # convert dtype of y_true to floats, to satisfy array_api_strict error:

Review comment (suggestion):
This had been fixed three years ago, see https://github.com/numpy/numpy/issues/6784#issuecomment-1341719384. It makes sense to keep `present_labels` as an array instead of turning it into a list.

I suppose this fix went into numpy 1.24.1 or even earlier.


Code after:
    y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device)

    if sample_weight is not None:
        sample_weight = column_or_1d(sample_weight)

    def _binary_uninterpolated_average_precision(
        y_true,
        y_score,
        pos_label=1,
        sample_weight=None,
        xp=xp,
    ):
        precision, recall, _ = precision_recall_curve(
            y_true,
            y_score,
            pos_label=pos_label,
            sample_weight=sample_weight,
        )
        # Return the step function integral
        # The following works because the last entry of precision is
        # guaranteed to be 1, as returned by precision_recall_curve.
        # Due to numerical error, we can get `-0.0` and we therefore clip it.
        return float(max(0.0, -xp.sum(xp.diff(recall) * precision[:-1])))

    y_type = type_of_target(y_true, input_name="y_true")
    present_labels = xp.unique_values(y_true)

    if y_type == "binary":
        if present_labels.shape[0] == 2 and pos_label not in present_labels:
            raise ValueError(
                f"pos_label={pos_label} is not a valid label. It should be "
                f"one of {present_labels}"
            )

    elif y_type == "multilabel-indicator" and pos_label != 1:
        raise ValueError(
            "Parameter pos_label is fixed to 1 for multilabel-indicator y_true. "
            "Do not set pos_label or set pos_label to 1."
        )

    elif y_type == "multiclass":
        if pos_label != 1:
            raise ValueError(
                "Parameter pos_label is fixed to 1 for multiclass y_true. "
                "Do not set pos_label or set pos_label to 1."
            )
        y_true = label_binarize(y_true, classes=present_labels)
        if not y_score.shape == y_true.shape:
            raise ValueError(
                "`y_score` needs to be of shape `(n_samples, n_classes)`, since "
                "`y_true` contains multiple classes. Got "