Repository: scikit-learn/scikit-learn
File: sklearn/inspection/_plot/decision_boundary.py (Python)

Code before:
                estimator,
                X_grid,
                response_method=prediction_method,
                pos_label=class_of_interest,
                return_response_method_used=True,
            )
        except ValueError as exc:
            if "is not a valid label" in str(exc):
                # re-raise a more informative error message since `pos_label` is unknown
                # to our user when interacting with
                # `DecisionBoundaryDisplay.from_estimator`
                raise ValueError(
                    # Note: it is ok to use estimator.classes_ here, as this error will
                    # only be thrown if estimator is a classifier
                    f"class_of_interest={class_of_interest} is not a valid label: It "
                    f"should be one of {estimator.classes_}"
                ) from exc
            raise

        # convert classes predictions into integers
        if response_method_used == "predict" and hasattr(estimator, "classes_"):
            encoder = LabelEncoder()
            encoder.classes_ = estimator.classes_
            response = encoder.transform(response)

        if n_classes is None:
            # try to infer n_classes from the estimator
            if (
                class_of_interest is not None
                or is_regressor(estimator)
                or is_outlier_detector(estimator)
            ):
                n_classes = 2
            elif is_classifier(estimator) and hasattr(estimator, "classes_"):
                n_classes = len(estimator.classes_)
            elif is_clusterer(estimator) and hasattr(estimator, "labels_"):
                n_classes = len(np.unique(estimator.labels_))
            else:
                target_type = type_of_target(response)
                if target_type in ("binary", "continuous"):
                    n_classes = 2
                elif target_type == "multiclass":
                    n_classes = len(np.unique(response))

        if n_classes is None:
            raise ValueError(
                f"'n_classes' cannot be inferred from {estimator.__class__.__name__}. "
                "Please provide the expected number of unique classes or "
                "labels via the 'n_classes' parameter."
            )


Review comment (suggestion):
I had to move inferring `n_classes` up here before the `response` reshaping, so that `type_of_target` works properly.

Code after:
            if "is not a valid label" in str(exc):
                # re-raise a more informative error message since `pos_label` is unknown
                # to our user when interacting with
                # `DecisionBoundaryDisplay.from_estimator`
                raise ValueError(
                    # Note: it is ok to use estimator.classes_ here, as this error will
                    # only be thrown if estimator is a classifier
                    f"class_of_interest={class_of_interest} is not a valid label: It "
                    f"should be one of {estimator.classes_}"
                ) from exc
            raise

        # convert classes predictions into integers
        if response_method_used == "predict" and hasattr(estimator, "classes_"):
            encoder = LabelEncoder()
            encoder.classes_ = estimator.classes_
            response = encoder.transform(response)

        # infer n_classes from the estimator
        if (
            class_of_interest is not None
            or is_regressor(estimator)
            or is_outlier_detector(estimator)
        ):
            n_classes = 2
        elif is_classifier(estimator) and hasattr(estimator, "classes_"):
            n_classes = len(estimator.classes_)
        elif is_clusterer(estimator) and hasattr(estimator, "labels_"):
            n_classes = len(np.unique(estimator.labels_))
        else:
            target_type = type_of_target(response)
            if target_type in ("binary", "continuous"):
                n_classes = 2
            elif target_type == "multiclass":
                n_classes = len(np.unique(response))
            else:
                raise ValueError(
                    "Number of classes or labels cannot be inferred from "
                    f"{estimator.__class__.__name__}. Please make sure your estimator "
                    "follows scikit-learn's estimator API as described here: "
                    "https://scikit-learn.org/stable/developers/develop.html#rolling-your-own-estimator"
                )

        if response.ndim == 1:
            response = response.reshape(*xx0.shape)
        else:
            if is_regressor(estimator):
                raise ValueError("Multi-output regressors are not supported")

            if class_of_interest is not None:
                # For the multiclass case, `_get_response_values` returns the response