CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
_plot.py886 linesDownload Raw Back to model_selection
1# Authors: The scikit-learn developers
2# SPDX-License-Identifier: BSD-3-Clause
3
4import numpy as np
5
6from ..utils._optional_dependencies import check_matplotlib_support
7from ..utils._plotting import _interval_max_min_ratio, _validate_score_name
8from ._validation import learning_curve, validation_curve
9
10
11class _BaseCurveDisplay:
12    def _plot_curve(
13        self,
14        x_data,
15        *,
16        ax=None,
17        negate_score=False,
18        score_name=None,
19        score_type="test",
20        std_display_style="fill_between",
21        line_kw=None,
22        fill_between_kw=None,
23        errorbar_kw=None,
24    ):
25        check_matplotlib_support(f"{self.__class__.__name__}.plot")
26
27        import matplotlib.pyplot as plt
28
29        if ax is None:
30            _, ax = plt.subplots()
31
32        if negate_score:
33            train_scores, test_scores = -self.train_scores, -self.test_scores
34        else:
35            train_scores, test_scores = self.train_scores, self.test_scores
36
37        if std_display_style not in ("errorbar", "fill_between", None):
38            raise ValueError(
39                f"Unknown std_display_style: {std_display_style}. Should be one of"
40                " 'errorbar', 'fill_between', or None."
41            )
42
43        if score_type not in ("test", "train", "both"):
44            raise ValueError(
45                f"Unknown score_type: {score_type}. Should be one of 'test', "
46                "'train', or 'both'."
47            )
48
49        if score_type == "train":
50            scores = {"Train": train_scores}
51        elif score_type == "test":
52            scores = {"Test": test_scores}
53        else:  # score_type == "both"
54            scores = {"Train": train_scores, "Test": test_scores}
55
56        if std_display_style in ("fill_between", None):
57            # plot the mean score
58            if line_kw is None:
59                line_kw = {}
60
61            self.lines_ = []
62            for line_label, score in scores.items():
63                self.lines_.append(
64                    *ax.plot(
65                        x_data,
66                        score.mean(axis=1),
67                        label=line_label,
68                        **line_kw,
69                    )
70                )
71            self.errorbar_ = None
72            self.fill_between_ = None  # overwritten below by fill_between
73
74        if std_display_style == "errorbar":
75            if errorbar_kw is None:
76                errorbar_kw = {}
77
78            self.errorbar_ = []
79            for line_label, score in scores.items():
80                self.errorbar_.append(
81                    ax.errorbar(
82                        x_data,
83                        score.mean(axis=1),
84                        score.std(axis=1),
85                        label=line_label,
86                        **errorbar_kw,
87                    )
88                )
89            self.lines_, self.fill_between_ = None, None
90        elif std_display_style == "fill_between":
91            if fill_between_kw is None:
92                fill_between_kw = {}
93            default_fill_between_kw = {"alpha": 0.5}
94            fill_between_kw = {**default_fill_between_kw, **fill_between_kw}
95
96            self.fill_between_ = []
97            for line_label, score in scores.items():
98                self.fill_between_.append(
99                    ax.fill_between(
100                        x_data,
101                        score.mean(axis=1) - score.std(axis=1),
102                        score.mean(axis=1) + score.std(axis=1),
103                        **fill_between_kw,
104                    )
105                )
106
107        score_name = self.score_name if score_name is None else score_name
108
109        ax.legend()
110
111        # We found that a ratio, smaller or bigger than 5, between the largest and
112        # smallest gap of the x values is a good indicator to choose between linear
113        # and log scale.
114        if _interval_max_min_ratio(x_data) > 5:
115            xscale = "symlog" if x_data.min() <= 0 else "log"
116        else:
117            xscale = "linear"
118
119        ax.set_xscale(xscale)
120        ax.set_ylabel(f"{score_name}")
121
122        self.ax_ = ax
123        self.figure_ = ax.figure
124
125
126class LearningCurveDisplay(_BaseCurveDisplay):
127    """Learning Curve visualization.
128
129    It is recommended to use
130    :meth:`~sklearn.model_selection.LearningCurveDisplay.from_estimator` to
131    create a :class:`~sklearn.model_selection.LearningCurveDisplay` instance.
132    All parameters are stored as attributes.
133
134    Read more in the :ref:`User Guide <visualizations>` for general information
135    about the visualization API and
136    :ref:`detailed documentation <learning_curve>` regarding the learning
137    curve visualization.
138
139    .. versionadded:: 1.2
140
141    Parameters
142    ----------
143    train_sizes : ndarray of shape (n_unique_ticks,)
144        Numbers of training examples that has been used to generate the
145        learning curve.
146
147    train_scores : ndarray of shape (n_ticks, n_cv_folds)
148        Scores on training sets.
149
150    test_scores : ndarray of shape (n_ticks, n_cv_folds)
151        Scores on test set.
152
153    score_name : str, default=None
154        The name of the score used in `learning_curve`. It will override the name
155        inferred from the `scoring` parameter. If `score` is `None`, we use `"Score"` if
156        `negate_score` is `False` and `"Negative score"` otherwise. If `scoring` is a
157        string or a callable, we infer the name. We replace `_` by spaces and capitalize
158        the first letter. We remove `neg_` and replace it by `"Negative"` if
159        `negate_score` is `False` or just remove it otherwise.
160
161    Attributes
162    ----------
163    ax_ : matplotlib Axes
164        Axes with the learning curve.
165
166    figure_ : matplotlib Figure
167        Figure containing the learning curve.
168
169    errorbar_ : list of matplotlib Artist or None
170        When the `std_display_style` is `"errorbar"`, this is a list of
171        `matplotlib.container.ErrorbarContainer` objects. If another style is
172        used, `errorbar_` is `None`.
173
174    lines_ : list of matplotlib Artist or None
175        When the `std_display_style` is `"fill_between"`, this is a list of
176        `matplotlib.lines.Line2D` objects corresponding to the mean train and
177        test scores. If another style is used, `line_` is `None`.
178
179    fill_between_ : list of matplotlib Artist or None
180        When the `std_display_style` is `"fill_between"`, this is a list of
181        `matplotlib.collections.PolyCollection` objects. If another style is
182        used, `fill_between_` is `None`.
183
184    See Also
185    --------
186    sklearn.model_selection.learning_curve : Compute the learning curve.
187
188    Examples
189    --------
190    >>> import matplotlib.pyplot as plt
191    >>> from sklearn.datasets import load_iris
192    >>> from sklearn.model_selection import LearningCurveDisplay, learning_curve
193    >>> from sklearn.tree import DecisionTreeClassifier
194    >>> X, y = load_iris(return_X_y=True)
195    >>> tree = DecisionTreeClassifier(random_state=0)
196    >>> train_sizes, train_scores, test_scores = learning_curve(
197    ...     tree, X, y)
198    >>> display = LearningCurveDisplay(train_sizes=train_sizes,
199    ...     train_scores=train_scores, test_scores=test_scores, score_name="Score")
200    >>> display.plot()
201    <...>
202    >>> plt.show()
203    """
204
205    def __init__(self, *, train_sizes, train_scores, test_scores, score_name=None):
206        self.train_sizes = train_sizes
207        self.train_scores = train_scores
208        self.test_scores = test_scores
209        self.score_name = score_name
210
211    def plot(
212        self,
213        ax=None,
214        *,
215        negate_score=False,
216        score_name=None,
217        score_type="both",
218        std_display_style="fill_between",
219        line_kw=None,
220        fill_between_kw=None,
221        errorbar_kw=None,
222    ):
223        """Plot visualization.
224
225        Parameters
226        ----------
227        ax : matplotlib Axes, default=None
228            Axes object to plot on. If `None`, a new figure and axes is
229            created.
230
231        negate_score : bool, default=False
232            Whether or not to negate the scores obtained through
233            :func:`~sklearn.model_selection.learning_curve`. This is
234            particularly useful when using the error denoted by `neg_*` in
235            `scikit-learn`.
236
237        score_name : str, default=None
238            The name of the score used to decorate the y-axis of the plot. It will
239            override the name inferred from the `scoring` parameter. If `score` is
240            `None`, we use `"Score"` if `negate_score` is `False` and `"Negative score"`
241            otherwise. If `scoring` is a string or a callable, we infer the name. We
242            replace `_` by spaces and capitalize the first letter. We remove `neg_` and
243            replace it by `"Negative"` if `negate_score` is
244            `False` or just remove it otherwise.
245
246        score_type : {"test", "train", "both"}, default="both"
247            The type of score to plot. Can be one of `"test"`, `"train"`, or
248            `"both"`.
249
250        std_display_style : {"errorbar", "fill_between"} or None, default="fill_between"
251            The style used to display the score standard deviation around the
252            mean score. If None, no standard deviation representation is
253            displayed.
254
255        line_kw : dict, default=None
256            Additional keyword arguments passed to the `plt.plot` used to draw
257            the mean score.
258
259        fill_between_kw : dict, default=None
260            Additional keyword arguments passed to the `plt.fill_between` used
261            to draw the score standard deviation.
262
263        errorbar_kw : dict, default=None
264            Additional keyword arguments passed to the `plt.errorbar` used to
265            draw mean score and standard deviation score.
266
267        Returns
268        -------
269        display : :class:`~sklearn.model_selection.LearningCurveDisplay`
270            Object that stores computed values.
271        """
272        self._plot_curve(
273            self.train_sizes,
274            ax=ax,
275            negate_score=negate_score,
276            score_name=score_name,
277            score_type=score_type,
278            std_display_style=std_display_style,
279            line_kw=line_kw,
280            fill_between_kw=fill_between_kw,
281            errorbar_kw=errorbar_kw,
282        )
283        self.ax_.set_xlabel("Number of samples in the training set")
284        return self
285
286    @classmethod
287    def from_estimator(
288        cls,
289        estimator,
290        X,
291        y,
292        *,
293        groups=None,
294        train_sizes=np.linspace(0.1, 1.0, 5),
295        cv=None,
296        scoring=None,
297        exploit_incremental_learning=False,
298        n_jobs=None,
299        pre_dispatch="all",
300        verbose=0,
301        shuffle=False,
302        random_state=None,
303        error_score=np.nan,
304        fit_params=None,
305        ax=None,
306        negate_score=False,
307        score_name=None,
308        score_type="both",
309        std_display_style="fill_between",
310        line_kw=None,
311        fill_between_kw=None,
312        errorbar_kw=None,
313    ):
314        """Create a learning curve display from an estimator.
315
316        Read more in the :ref:`User Guide <visualizations>` for general
317        information about the visualization API and :ref:`detailed
318        documentation <learning_curve>` regarding the learning curve
319        visualization.
320
321        Parameters
322        ----------
323        estimator : object type that implements the "fit" and "predict" methods
324            An object of that type which is cloned for each validation.
325
326        X : array-like of shape (n_samples, n_features)
327            Training data, where `n_samples` is the number of samples and
328            `n_features` is the number of features.
329
330        y : array-like of shape (n_samples,) or (n_samples, n_outputs) or None
331            Target relative to X for classification or regression;
332            None for unsupervised learning.
333
334        groups : array-like of shape (n_samples,), default=None
335            Group labels for the samples used while splitting the dataset into
336            train/test set. Only used in conjunction with a "Group" :term:`cv`
337            instance (e.g., :class:`GroupKFold`).
338
339        train_sizes : array-like of shape (n_ticks,), \
340                default=np.linspace(0.1, 1.0, 5)
341            Relative or absolute numbers of training examples that will be used
342            to generate the learning curve. If the dtype is float, it is
343            regarded as a fraction of the maximum size of the training set
344            (that is determined by the selected validation method), i.e. it has
345            to be within (0, 1]. Otherwise it is interpreted as absolute sizes
346            of the training sets. Note that for classification the number of
347            samples usually have to be big enough to contain at least one
348            sample from each class.
349
350        cv : int, cross-validation generator or an iterable, default=None
351            Determines the cross-validation splitting strategy.
352            Possible inputs for cv are:
353
354            - None, to use the default 5-fold cross validation,
355            - int, to specify the number of folds in a `(Stratified)KFold`,
356            - :term:`CV splitter`,
357            - An iterable yielding (train, test) splits as arrays of indices.
358
359            For int/None inputs, if the estimator is a classifier and `y` is
360            either binary or multiclass,
361            :class:`~sklearn.model_selection.StratifiedKFold` is used. In all
362            other cases, :class:`~sklearn.model_selection.KFold` is used. These
363            splitters are instantiated with `shuffle=False` so the splits will
364            be the same across calls.
365
366            Refer :ref:`User Guide <cross_validation>` for the various
367            cross-validation strategies that can be used here.
368
369        scoring : str or callable, default=None
370            The scoring method to use when calculating the learning curve. Options:
371
372            - str: see :ref:`scoring_string_names` for options.
373            - callable: a scorer callable object (e.g., function) with signature
374              ``scorer(estimator, X, y)``. See :ref:`scoring_callable` for details.
375            - `None`: the `estimator`'s
376              :ref:`default evaluation criterion <scoring_api_overview>` is used.
377
378        exploit_incremental_learning : bool, default=False
379            If the estimator supports incremental learning, this will be
380            used to speed up fitting for different training set sizes.
381
382        n_jobs : int, default=None
383            Number of jobs to run in parallel. Training the estimator and
384            computing the score are parallelized over the different training
385            and test sets. `None` means 1 unless in a
386            :obj:`joblib.parallel_backend` context. `-1` means using all
387            processors. See :term:`Glossary <n_jobs>` for more details.
388
389        pre_dispatch : int or str, default='all'
390            Number of predispatched jobs for parallel execution (default is
391            all). The option can reduce the allocated memory. The str can
392            be an expression like '2*n_jobs'.
393
394        verbose : int, default=0
395            Controls the verbosity: the higher, the more messages.
396
397        shuffle : bool, default=False
398            Whether to shuffle training data before taking prefixes of it
399            based on`train_sizes`.
400
401        random_state : int, RandomState instance or None, default=None
402            Used when `shuffle` is True. Pass an int for reproducible
403            output across multiple function calls.
404            See :term:`Glossary <random_state>`.
405
406        error_score : 'raise' or numeric, default=np.nan
407            Value to assign to the score if an error occurs in estimator
408            fitting. If set to 'raise', the error is raised. If a numeric value
409            is given, FitFailedWarning is raised.
410
411        fit_params : dict, default=None
412            Parameters to pass to the fit method of the estimator.
413
414        ax : matplotlib Axes, default=None
415            Axes object to plot on. If `None`, a new figure and axes is
416            created.
417
418        negate_score : bool, default=False
419            Whether or not to negate the scores obtained through
420            :func:`~sklearn.model_selection.learning_curve`. This is
421            particularly useful when using the error denoted by `neg_*` in
422            `scikit-learn`.
423
424        score_name : str, default=None
425            The name of the score used to decorate the y-axis of the plot. It will
426            override the name inferred from the `scoring` parameter. If `score` is
427            `None`, we use `"Score"` if `negate_score` is `False` and `"Negative score"`
428            otherwise. If `scoring` is a string or a callable, we infer the name. We
429            replace `_` by spaces and capitalize the first letter. We remove `neg_` and
430            replace it by `"Negative"` if `negate_score` is
431            `False` or just remove it otherwise.
432
433        score_type : {"test", "train", "both"}, default="both"
434            The type of score to plot. Can be one of `"test"`, `"train"`, or
435            `"both"`.
436
437        std_display_style : {"errorbar", "fill_between"} or None, default="fill_between"
438            The style used to display the score standard deviation around the
439            mean score. If `None`, no representation of the standard deviation
440            is displayed.
441
442        line_kw : dict, default=None
443            Additional keyword arguments passed to the `plt.plot` used to draw
444            the mean score.
445
446        fill_between_kw : dict, default=None
447            Additional keyword arguments passed to the `plt.fill_between` used
448            to draw the score standard deviation.
449
450        errorbar_kw : dict, default=None
451            Additional keyword arguments passed to the `plt.errorbar` used to
452            draw mean score and standard deviation score.
453
454        Returns
455        -------
456        display : :class:`~sklearn.model_selection.LearningCurveDisplay`
457            Object that stores computed values.
458
459        Examples
460        --------
461        >>> import matplotlib.pyplot as plt
462        >>> from sklearn.datasets import load_iris
463        >>> from sklearn.model_selection import LearningCurveDisplay
464        >>> from sklearn.tree import DecisionTreeClassifier
465        >>> X, y = load_iris(return_X_y=True)
466        >>> tree = DecisionTreeClassifier(random_state=0)
467        >>> LearningCurveDisplay.from_estimator(tree, X, y)
468        <...>
469        >>> plt.show()
470        """
471        check_matplotlib_support(f"{cls.__name__}.from_estimator")
472
473        score_name = _validate_score_name(score_name, scoring, negate_score)
474
475        train_sizes, train_scores, test_scores = learning_curve(
476            estimator,
477            X,
478            y,
479            groups=groups,
480            train_sizes=train_sizes,
481            cv=cv,
482            scoring=scoring,
483            exploit_incremental_learning=exploit_incremental_learning,
484            n_jobs=n_jobs,
485            pre_dispatch=pre_dispatch,
486            verbose=verbose,
487            shuffle=shuffle,
488            random_state=random_state,
489            error_score=error_score,
490            return_times=False,
491            fit_params=fit_params,
492        )
493
494        viz = cls(
495            train_sizes=train_sizes,
496            train_scores=train_scores,
497            test_scores=test_scores,
498            score_name=score_name,
499        )
500        return viz.plot(
501            ax=ax,
502            negate_score=negate_score,
503            score_type=score_type,
504            std_display_style=std_display_style,
505            line_kw=line_kw,
506            fill_between_kw=fill_between_kw,
507            errorbar_kw=errorbar_kw,
508        )
509
510
511class ValidationCurveDisplay(_BaseCurveDisplay):
512    """Validation Curve visualization.
513
514    It is recommended to use
515    :meth:`~sklearn.model_selection.ValidationCurveDisplay.from_estimator` to
516    create a :class:`~sklearn.model_selection.ValidationCurveDisplay` instance.
517    All parameters are stored as attributes.
518
519    Read more in the :ref:`User Guide <visualizations>` for general information
520    about the visualization API and :ref:`detailed documentation
521    <validation_curve>` regarding the validation curve visualization.
522
523    .. versionadded:: 1.3
524
525    Parameters
526    ----------
527    param_name : str
528        Name of the parameter that has been varied.
529
530    param_range : array-like of shape (n_ticks,)
531        The values of the parameter that have been evaluated.
532
533    train_scores : ndarray of shape (n_ticks, n_cv_folds)
534        Scores on training sets.
535
536    test_scores : ndarray of shape (n_ticks, n_cv_folds)
537        Scores on test set.
538
539    score_name : str, default=None
540        The name of the score used in `validation_curve`. It will override the name
541        inferred from the `scoring` parameter. If `score` is `None`, we use `"Score"` if
542        `negate_score` is `False` and `"Negative score"` otherwise. If `scoring` is a
543        string or a callable, we infer the name. We replace `_` by spaces and capitalize
544        the first letter. We remove `neg_` and replace it by `"Negative"` if
545        `negate_score` is `False` or just remove it otherwise.
546
547    Attributes
548    ----------
549    ax_ : matplotlib Axes
550        Axes with the validation curve.
551
552    figure_ : matplotlib Figure
553        Figure containing the validation curve.
554
555    errorbar_ : list of matplotlib Artist or None
556        When the `std_display_style` is `"errorbar"`, this is a list of
557        `matplotlib.container.ErrorbarContainer` objects. If another style is
558        used, `errorbar_` is `None`.
559
560    lines_ : list of matplotlib Artist or None
561        When the `std_display_style` is `"fill_between"`, this is a list of
562        `matplotlib.lines.Line2D` objects corresponding to the mean train and
563        test scores. If another style is used, `line_` is `None`.
564
565    fill_between_ : list of matplotlib Artist or None
566        When the `std_display_style` is `"fill_between"`, this is a list of
567        `matplotlib.collections.PolyCollection` objects. If another style is
568        used, `fill_between_` is `None`.
569
570    See Also
571    --------
572    sklearn.model_selection.validation_curve : Compute the validation curve.
573
574    Examples
575    --------
576    >>> import numpy as np
577    >>> import matplotlib.pyplot as plt
578    >>> from sklearn.datasets import make_classification
579    >>> from sklearn.model_selection import ValidationCurveDisplay, validation_curve
580    >>> from sklearn.linear_model import LogisticRegression
581    >>> X, y = make_classification(n_samples=1_000, random_state=0)
582    >>> logistic_regression = LogisticRegression()
583    >>> param_name, param_range = "C", np.logspace(-8, 3, 10)
584    >>> train_scores, test_scores = validation_curve(
585    ...     logistic_regression, X, y, param_name=param_name, param_range=param_range
586    ... )
587    >>> display = ValidationCurveDisplay(
588    ...     param_name=param_name, param_range=param_range,
589    ...     train_scores=train_scores, test_scores=test_scores, score_name="Score"
590    ... )
591    >>> display.plot()
592    <...>
593    >>> plt.show()
594    """
595
596    def __init__(
597        self, *, param_name, param_range, train_scores, test_scores, score_name=None
598    ):
599        self.param_name = param_name
600        self.param_range = param_range
601        self.train_scores = train_scores
602        self.test_scores = test_scores
603        self.score_name = score_name
604
605    def plot(
606        self,
607        ax=None,
608        *,
609        negate_score=False,
610        score_name=None,
611        score_type="both",
612        std_display_style="fill_between",
613        line_kw=None,
614        fill_between_kw=None,
615        errorbar_kw=None,
616    ):
617        """Plot visualization.
618
619        Parameters
620        ----------
621        ax : matplotlib Axes, default=None
622            Axes object to plot on. If `None`, a new figure and axes is
623            created.
624
625        negate_score : bool, default=False
626            Whether or not to negate the scores obtained through
627            :func:`~sklearn.model_selection.validation_curve`. This is
628            particularly useful when using the error denoted by `neg_*` in
629            `scikit-learn`.
630
631        score_name : str, default=None
632            The name of the score used to decorate the y-axis of the plot. It will
633            override the name inferred from the `scoring` parameter. If `score` is
634            `None`, we use `"Score"` if `negate_score` is `False` and `"Negative score"`
635            otherwise. If `scoring` is a string or a callable, we infer the name. We
636            replace `_` by spaces and capitalize the first letter. We remove `neg_` and
637            replace it by `"Negative"` if `negate_score` is
638            `False` or just remove it otherwise.
639
640        score_type : {"test", "train", "both"}, default="both"
641            The type of score to plot. Can be one of `"test"`, `"train"`, or
642            `"both"`.
643
644        std_display_style : {"errorbar", "fill_between"} or None, default="fill_between"
645            The style used to display the score standard deviation around the
646            mean score. If None, no standard deviation representation is
647            displayed.
648
649        line_kw : dict, default=None
650            Additional keyword arguments passed to the `plt.plot` used to draw
651            the mean score.
652
653        fill_between_kw : dict, default=None
654            Additional keyword arguments passed to the `plt.fill_between` used
655            to draw the score standard deviation.
656
657        errorbar_kw : dict, default=None
658            Additional keyword arguments passed to the `plt.errorbar` used to
659            draw mean score and standard deviation score.
660
661        Returns
662        -------
663        display : :class:`~sklearn.model_selection.ValidationCurveDisplay`
664            Object that stores computed values.
665        """
666        self._plot_curve(
667            self.param_range,
668            ax=ax,
669            negate_score=negate_score,
670            score_name=score_name,
671            score_type=score_type,
672            std_display_style=std_display_style,
673            line_kw=line_kw,
674            fill_between_kw=fill_between_kw,
675            errorbar_kw=errorbar_kw,
676        )
677        self.ax_.set_xlabel(f"{self.param_name}")
678        return self
679
680    @classmethod
681    def from_estimator(
682        cls,
683        estimator,
684        X,
685        y,
686        *,
687        param_name,
688        param_range,
689        groups=None,
690        cv=None,
691        scoring=None,
692        n_jobs=None,
693        pre_dispatch="all",
694        verbose=0,
695        error_score=np.nan,
696        fit_params=None,
697        ax=None,
698        negate_score=False,
699        score_name=None,
700        score_type="both",
701        std_display_style="fill_between",
702        line_kw=None,
703        fill_between_kw=None,
704        errorbar_kw=None,
705    ):
706        """Create a validation curve display from an estimator.
707
708        Read more in the :ref:`User Guide <visualizations>` for general
709        information about the visualization API and :ref:`detailed
710        documentation <validation_curve>` regarding the validation curve
711        visualization.
712
713        Parameters
714        ----------
715        estimator : object type that implements the "fit" and "predict" methods
716            An object of that type which is cloned for each validation.
717
718        X : array-like of shape (n_samples, n_features)
719            Training data, where `n_samples` is the number of samples and
720            `n_features` is the number of features.
721
722        y : array-like of shape (n_samples,) or (n_samples, n_outputs) or None
723            Target relative to X for classification or regression;
724            None for unsupervised learning.
725
726        param_name : str
727            Name of the parameter that will be varied.
728
729        param_range : array-like of shape (n_values,)
730            The values of the parameter that will be evaluated.
731
732        groups : array-like of shape (n_samples,), default=None
733            Group labels for the samples used while splitting the dataset into
734            train/test set. Only used in conjunction with a "Group" :term:`cv`
735            instance (e.g., :class:`GroupKFold`).
736
737        cv : int, cross-validation generator or an iterable, default=None
738            Determines the cross-validation splitting strategy.
739            Possible inputs for cv are:
740
741            - None, to use the default 5-fold cross validation,
742            - int, to specify the number of folds in a `(Stratified)KFold`,
743            - :term:`CV splitter`,
744            - An iterable yielding (train, test) splits as arrays of indices.
745
746            For int/None inputs, if the estimator is a classifier and `y` is
747            either binary or multiclass,
748            :class:`~sklearn.model_selection.StratifiedKFold` is used. In all
749            other cases, :class:`~sklearn.model_selection.KFold` is used. These
750            splitters are instantiated with `shuffle=False` so the splits will
751            be the same across calls.
752
753            Refer :ref:`User Guide <cross_validation>` for the various
754            cross-validation strategies that can be used here.
755
756        scoring : str or callable, default=None
757            Scoring method to use when computing the validation curve. Options:
758
759            - str: see :ref:`scoring_string_names` for options.
760            - callable: a scorer callable object (e.g., function) with signature
761              ``scorer(estimator, X, y)``. See :ref:`scoring_callable` for details.
762            - `None`: the `estimator`'s
763              :ref:`default evaluation criterion <scoring_api_overview>` is used.
764
765        n_jobs : int, default=None
766            Number of jobs to run in parallel. Training the estimator and
767            computing the score are parallelized over the different training
768            and test sets. `None` means 1 unless in a
769            :obj:`joblib.parallel_backend` context. `-1` means using all
770            processors. See :term:`Glossary <n_jobs>` for more details.
771
772        pre_dispatch : int or str, default='all'
773            Number of predispatched jobs for parallel execution (default is
774            all). The option can reduce the allocated memory. The str can
775            be an expression like '2*n_jobs'.
776
777        verbose : int, default=0
778            Controls the verbosity: the higher, the more messages.
779
780        error_score : 'raise' or numeric, default=np.nan
781            Value to assign to the score if an error occurs in estimator
782            fitting. If set to 'raise', the error is raised. If a numeric value
783            is given, FitFailedWarning is raised.
784
785        fit_params : dict, default=None
786            Parameters to pass to the fit method of the estimator.
787
788        ax : matplotlib Axes, default=None
789            Axes object to plot on. If `None`, a new figure and axes is
790            created.
791
792        negate_score : bool, default=False
793            Whether or not to negate the scores obtained through
794            :func:`~sklearn.model_selection.validation_curve`. This is
795            particularly useful when using the error denoted by `neg_*` in
796            `scikit-learn`.
797
798        score_name : str, default=None
799            The name of the score used to decorate the y-axis of the plot. It will
800            override the name inferred from the `scoring` parameter. If `score` is
801            `None`, we use `"Score"` if `negate_score` is `False` and `"Negative score"`
802            otherwise. If `scoring` is a string or a callable, we infer the name. We
803            replace `_` by spaces and capitalize the first letter. We remove `neg_` and
804            replace it by `"Negative"` if `negate_score` is
805            `False` or just remove it otherwise.
806
807        score_type : {"test", "train", "both"}, default="both"
808            The type of score to plot. Can be one of `"test"`, `"train"`, or
809            `"both"`.
810
811        std_display_style : {"errorbar", "fill_between"} or None, default="fill_between"
812            The style used to display the score standard deviation around the
813            mean score. If `None`, no representation of the standard deviation
814            is displayed.
815
816        line_kw : dict, default=None
817            Additional keyword arguments passed to the `plt.plot` used to draw
818            the mean score.
819
820        fill_between_kw : dict, default=None
821            Additional keyword arguments passed to the `plt.fill_between` used
822            to draw the score standard deviation.
823
824        errorbar_kw : dict, default=None
825            Additional keyword arguments passed to the `plt.errorbar` used to
826            draw mean score and standard deviation score.
827
828        Returns
829        -------
830        display : :class:`~sklearn.model_selection.ValidationCurveDisplay`
831            Object that stores computed values.
832
833        Examples
834        --------
835        >>> import numpy as np
836        >>> import matplotlib.pyplot as plt
837        >>> from sklearn.datasets import make_classification
838        >>> from sklearn.model_selection import ValidationCurveDisplay
839        >>> from sklearn.linear_model import LogisticRegression
840        >>> X, y = make_classification(n_samples=1_000, random_state=0)
841        >>> logistic_regression = LogisticRegression()
842        >>> param_name, param_range = "C", np.logspace(-8, 3, 10)
843        >>> ValidationCurveDisplay.from_estimator(
844        ...     logistic_regression, X, y, param_name=param_name,
845        ...     param_range=param_range,
846        ... )
847        <...>
848        >>> plt.show()
849        """
850        check_matplotlib_support(f"{cls.__name__}.from_estimator")
851
852        score_name = _validate_score_name(score_name, scoring, negate_score)
853
854        train_scores, test_scores = validation_curve(
855            estimator,
856            X,
857            y,
858            param_name=param_name,
859            param_range=param_range,
860            groups=groups,
861            cv=cv,
862            scoring=scoring,
863            n_jobs=n_jobs,
864            pre_dispatch=pre_dispatch,
865            verbose=verbose,
866            error_score=error_score,
867            fit_params=fit_params,
868        )
869
870        viz = cls(
871            param_name=param_name,
872            param_range=np.asarray(param_range),
873            train_scores=train_scores,
874            test_scores=test_scores,
875            score_name=score_name,
876        )
877        return viz.plot(
878            ax=ax,
879            negate_score=negate_score,
880            score_type=score_type,
881            std_display_style=std_display_style,
882            line_kw=line_kw,
883            fill_between_kw=fill_between_kw,
884            errorbar_kw=errorbar_kw,
885        )
886