Aluode/PerceptionLabPortable
0
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 