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

Code before:

    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:
        y_true = xp.astype(xp.asarray(y_true), xp.float64, copy=False)

    average_precision = partial(
        _binary_uninterpolated_average_precision, pos_label=pos_label, xp=xp
    )
    return _average_binary_score(
        average_precision, y_true, y_score, average, sample_weight=sample_weight
    )


@validate_params(
    {
        "y_true": ["array-like"],
        "y_score": ["array-like"],
        "pos_label": [Real, str, "boolean", None],
        "sample_weight": ["array-like", None],
        "drop_intermediate": ["boolean"],
    },
    prefer_skip_nested_validation=True,
)
def det_curve(
    y_true, y_score, pos_label=None, sample_weight=None, drop_intermediate=False
):
    """Compute Detection Error Tradeoff (DET) for different probability thresholds.

    Note: Support beyond :term:`binary` classification tasks, via one-vs-rest or

Review comment (refactor):
This prevents an error from `array_api_strict`:

`TypeError: array_api_strict.int64 and array_api_strict.float64 cannot be type promoted together`

But actually, we should not change our code just to make a helper library happy. I need to think a bit more about this.

Code after:
        # 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 "
                f"`y_score.shape={y_score.shape}`."
            )

    average_precision = partial(
        _binary_uninterpolated_average_precision, pos_label=pos_label, xp=xp
    )
    return _average_binary_score(
        average_precision, y_true, y_score, average, sample_weight=sample_weight
    )


@validate_params(
    {
        "y_true": ["array-like"],
        "y_score": ["array-like"],
        "pos_label": [Real, str, "boolean", None],
        "sample_weight": ["array-like", None],
        "drop_intermediate": ["boolean"],