Spec-Zone.ru › scikit-learn

Note

Go to the end to download the full example code or to run this example in your browser via JupyterLite or Binder.

Successive Halving Iterations

This example illustrates how a successive halving search (HalvingGridSearchCV and HalvingRandomSearchCV) iteratively chooses the best parameter combination out of multiple candidates.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.stats import randint

from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier
from sklearn.experimental import enable_halving_search_cv  # noqa: F401
from sklearn.model_selection import HalvingRandomSearchCV

We first define the parameter space and train a HalvingRandomSearchCV instance.

rng = np.random.RandomState(0)

X, y = datasets.make_classification(n_samples=400, n_features=12, random_state=rng)

clf = RandomForestClassifier(n_estimators=20, random_state=rng)

param_dist = {
    "max_depth": [3, None],
    "max_features": randint(1, 6),
    "min_samples_split": randint(2, 11),
    "bootstrap": [True, False],
    "criterion": ["gini", "entropy"],
}

rsh = HalvingRandomSearchCV(
    estimator=clf, param_distributions=param_dist, factor=2, random_state=rng
)
rsh.fit(X, y)
HalvingRandomSearchCV(estimator=RandomForestClassifier(n_estimators=20,
                                                       random_state=RandomState(MT19937) at 0x784166B66A40),
                      factor=2,
                      param_distributions={'bootstrap': [True, False],
                                           'criterion': ['gini', 'entropy'],
                                           'max_depth': [3, None],
                                           'max_features': <scipy.stats._distn_infrastructure.rv_discrete_frozen object at 0x784129d35e50>,
                                           'min_samples_split': <scipy.stats._distn_infrastructure.rv_discrete_frozen object at 0x78416c563490>},
                      random_state=RandomState(MT19937) at 0x784166B66A40)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Parameters
estimator estimator: estimator object

This is assumed to implement the scikit-learn estimator interface.
Either estimator needs to provide a ``score`` function,
or ``scoring`` must be passed.
RandomForestC...x784166B66A40)
param_distributions param_distributions: dict or list of dicts

Dictionary with parameters names (`str`) as keys and distributions
or lists of parameters to try. Distributions must provide a ``rvs``
method for sampling (such as those from scipy.stats.distributions).
If a list is given, it is sampled uniformly.
If a list of dicts is given, first a dict is sampled uniformly, and
then a parameter is sampled using that dict as above.
{'bootstrap': [True, False], 'criterion': ['gini', 'entropy'], 'max_depth': [3, None], 'max_features': <scipy.stats....x784129d35e50>, ...}
factor factor: int or float, default=3

The 'halving' parameter, which determines the proportion of candidates
that are selected for each subsequent iteration. For example,
``factor=3`` means that only one third of the candidates are selected.
2
random_state random_state: int, RandomState instance or None, default=None

Pseudo random number generator state used for subsampling the dataset
when `resources != 'n_samples'`. Also used for random uniform
sampling from lists of possible values instead of scipy.stats
distributions.
Pass an int for reproducible output across multiple function calls.
See :term:`Glossary <random_state>`.
RandomState(M...0x784166B66A40
n_candidates n_candidates: "exhaust" or int, default="exhaust"

The number of candidate parameters to sample, at the first
iteration. Using 'exhaust' will sample enough candidates so that the
last iteration uses as many resources as possible, based on
`min_resources`, `max_resources` and `factor`. In this case,
`min_resources` cannot be 'exhaust'.
'exhaust'
resource resource: ``'n_samples'`` or str, default='n_samples'

Defines the resource that increases with each iteration. By default,
the resource is the number of samples. It can also be set to any
parameter of the base estimator that accepts positive integer
values, e.g. 'n_iterations' or 'n_estimators' for a gradient
boosting estimator. In this case ``max_resources`` cannot be 'auto'
and must be set explicitly.
'n_samples'
max_resources max_resources: int, default='auto'

The maximum number of resources that any candidate is allowed to use
for a given iteration. By default, this is set ``n_samples`` when
``resource='n_samples'`` (default), else an error is raised.
'auto'
min_resources min_resources: {'exhaust', 'smallest'} or int, default='smallest'

The minimum amount of resource that any candidate is allowed to use
for a given iteration. Equivalently, this defines the amount of
resources `r0` that are allocated for each candidate at the first
iteration.

- 'smallest' is a heuristic that sets `r0` to a small value:

- ``n_splits * 2`` when ``resource='n_samples'`` for a regression problem
- ``n_classes * n_splits * 2`` when ``resource='n_samples'`` for a
classification problem
- ``1`` when ``resource != 'n_samples'``

- 'exhaust' will set `r0` such that the **last** iteration uses as
much resources as possible. Namely, the last iteration will use the
highest value smaller than ``max_resources`` that is a multiple of
both ``min_resources`` and ``factor``. In general, using 'exhaust'
leads to a more accurate estimator, but is slightly more time
consuming. 'exhaust' isn't available when `n_candidates='exhaust'`.

Note that the amount of resources used at each iteration is always a
multiple of ``min_resources``.
'smallest'
aggressive_elimination aggressive_elimination: bool, default=False

This is only relevant in cases where there isn't enough resources to
reduce the remaining candidates to at most `factor` after the last
iteration. If ``True``, then the search process will 'replay' the
first iteration for as long as needed until the number of candidates
is small enough. This is ``False`` by default, which means that the
last iteration may evaluate more than ``factor`` candidates. See
:ref:`aggressive_elimination` for more details.
False
cv cv: int, cross-validation generator or an iterable, default=5

Determines the cross-validation splitting strategy.
Possible inputs for cv are:

- integer, to specify the number of folds in a `(Stratified)KFold`,
- :term:`CV splitter`,
- an iterable yielding (train, test) splits as arrays of indices.

For integer/None inputs, if the estimator is a classifier and ``y`` is
either binary or multiclass, :class:`StratifiedKFold` is used. In all
other cases, :class:`KFold` is used. These splitters are instantiated
with `shuffle=False` so the splits will be the same across calls.

Refer :ref:`User Guide <cross_validation>` for the various
cross-validation strategies that can be used here.

.. note::
Due to implementation details, the folds produced by `cv` must be
the same across multiple calls to `cv.split()`. For
built-in `scikit-learn` iterators, this can be achieved by
deactivating shuffling (`shuffle=False`), or by setting the
`cv`'s `random_state` parameter to an integer.
5
scoring scoring: str or callable, default=None

Scoring method to use to evaluate the predictions on the test set.

- str: see :ref:`scoring_string_names` for options.
- callable: a scorer callable object (e.g., function) with signature
``scorer(estimator, X, y)``. See :ref:`scoring_callable` for details.
- `None`: the `estimator`'s
:ref:`default evaluation criterion <scoring_api_overview>` is used.
None
refit refit: bool or callable, default=True

Refit an estimator using the best found parameters on the whole
dataset.

Where there are considerations other than maximum score in
choosing a best estimator, ``refit`` can be set to a function which
returns the selected ``best_index_`` given ``cv_results_``. In that
case, the ``best_estimator_`` and ``best_params_`` will be set
according to the returned ``best_index_`` while the ``best_score_``
attribute will not be available.

The refitted estimator is made available at the ``best_estimator_``
attribute and permits using ``predict`` directly on this
``HalvingRandomSearchCV`` instance.

See :ref:`this example
<sphx_glr_auto_examples_model_selection_plot_grid_search_refit_callable.py>`
for an example of how to use ``refit=callable`` to balance model
complexity and cross-validated score.
True
error_score error_score: 'raise' or numeric

Value to assign to the score if an error occurs in estimator fitting.
If set to 'raise', the error is raised. If a numeric value is given,
FitFailedWarning is raised. This parameter does not affect the refit
step, which will always raise the error. Default is ``np.nan``.
nan
return_train_score return_train_score: bool, default=False

If ``False``, the ``cv_results_`` attribute will not include training
scores.
Computing training scores is used to get insights on how different
parameter settings impact the overfitting/underfitting trade-off.
However computing the scores on the training set can be computationally
expensive and is not strictly required to select the parameters that
yield the best generalization performance.
True
n_jobs n_jobs: int or None, default=None

Number of jobs to run in parallel.
``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
``-1`` means using all processors. See :term:`Glossary <n_jobs>`
for more details.
None
verbose verbose: int

Controls the verbosity: the higher, the more messages.
0
Fitted attributes
Name Type Value
best_estimator_ best_estimator_: estimator or dict

Estimator that was chosen by the search, i.e. estimator
which gave highest score (or smallest loss if specified)
on the left out data. Not available if ``refit=False``.
RandomForestClassifier RandomForestC...x784117609540)
best_index_ best_index_: int

The index (of the ``cv_results_`` arrays) which corresponds to the best
candidate parameter setting.

The dict at ``search.cv_results_['params'][search.best_index_]`` gives
the parameter setting for the best model, that gives the highest
mean score (``search.best_score_``).
int64 np.int64(39)
best_params_ best_params_: dict

Parameter setting that gave the best results on the hold out data.
dict {'bo...ap': False, 'cr...on': 'entropy', 'ma...th': None, 'ma...es': 4, ...}
best_score_ best_score_: float

Mean cross-validated score of the best_estimator.
float64 0.8875
classes_ classes_: ndarray of shape (n_classes,)

The classes labels. This is present only if ``refit`` is specified and
the underlying estimator is a classifier.
ndarray[int64](2,) [0,1]
cv_results_ cv_results_: dict of numpy (masked) ndarrays

A dict with keys as column headers and values as columns, that can be
imported into a pandas ``DataFrame``. It contains lots of information
for analysing the results of a search.
Please refer to the :ref:`User guide<successive_halving_cv_results>`
for details.
For an example of analysing ``cv_results_``,
see :ref:`sphx_glr_auto_examples_model_selection_plot_grid_search_stats.py`.
dict {'iter': array([0, 0, ..., 3, 3, 4, 4]), 'me...me': array([0.03, ..., 0.03, 0.04]), 'me...me': array([0. , ..., 0. , 0. ]), 'me...re': array([0.65, ..., 0.88, 0.89]), ...}
max_resources_ max_resources_: int

The maximum number of resources that any candidate is allowed to use
for a given iteration. Note that since the number of resources used at
each iteration must be a multiple of ``min_resources_``, the actual
number of resources used at the last iteration may be smaller than
``max_resources_``.
int 400
min_resources_ min_resources_: int

The amount of resources that are allocated for each candidate at the
first iteration.
int 20
multimetric_ multimetric_: bool

Whether or not the scorers compute several metrics.
bool False
n_candidates_ n_candidates_: list of int

The number of candidate parameters that were evaluated at each
iteration.
list [20, 10, 5, 3, ...]
n_features_in_ n_features_in_: int

Number of features seen during :term:`fit`. Only defined if
`best_estimator_` is defined (see the documentation for the `refit`
parameter for more details) and that `best_estimator_` exposes
`n_features_in_` when fit.

.. versionadded:: 0.24
int 12
n_iterations_ n_iterations_: int

The actual number of iterations that were run. This is equal to
``n_required_iterations_`` if ``aggressive_elimination`` is ``True``.
Else, this is equal to ``min(n_possible_iterations_,
n_required_iterations_)``.
int 5
n_possible_iterations_ n_possible_iterations_: int

The number of iterations that are possible starting with
``min_resources_`` resources and without exceeding
``max_resources_``.
int 5
n_remaining_candidates_ n_remaining_candidates_: int

The number of candidate parameters that are left after the last
iteration. It corresponds to `ceil(n_candidates[-1] / factor)`
int 1
n_required_iterations_ n_required_iterations_: int

The number of iterations that are required to end up with less than
``factor`` candidates at the last iteration, starting with
``min_resources_`` resources. This will be smaller than
``n_possible_iterations_`` when there isn't enough resources.
int 5
n_resources_ n_resources_: list of int

The amount of resources used at each iteration.
list [20, 40, 80, 160, ...]
n_splits_ n_splits_: int

The number of cross-validation splits (folds/iterations).
int 5
refit_time_ refit_time_: float

Seconds used for refitting the best model on the whole dataset.

This is present only if ``refit`` is not False.
float 0.04359
scorer_ scorer_: function or a dict

Scorer function used on the held out data to choose the best
parameters for the model.
_PassthroughScorer RandomForestClassifier.score
RandomForestClassifier(bootstrap=False, criterion='entropy', max_features=4,
                       min_samples_split=5, n_estimators=20,
                       random_state=RandomState(MT19937) at 0x784117609540)
Parameters
n_estimators n_estimators: int, default=100

The number of trees in the forest.

.. versionchanged:: 0.22
The default value of ``n_estimators`` changed from 10 to 100
in 0.22.
20
criterion criterion: {"gini", "entropy", "log_loss"}, default="gini"

The function to measure the quality of a split. Supported criteria are
"gini" for the Gini impurity and "log_loss" and "entropy" both for the
Shannon information gain, see :ref:`tree_mathematical_formulation`.
Note: This parameter is tree-specific.
'entropy'
min_samples_split min_samples_split: int or float, default=2

The minimum number of samples required to split an internal node:

- If int, then consider `min_samples_split` as the minimum number.
- If float, then `min_samples_split` is a fraction and
`ceil(min_samples_split * n_samples)` are the minimum
number of samples for each split.

.. versionchanged:: 0.18
Added float values for fractions.
5
max_features max_features: {"sqrt", "log2", None}, int or float, default="sqrt"

The number of features to consider when looking for the best split:

- If int, then consider `max_features` features at each split.
- If float, then `max_features` is a fraction and
`max(1, int(max_features * n_features_in_))` features are considered at each
split.
- If "sqrt", then `max_features=sqrt(n_features)`.
- If "log2", then `max_features=log2(n_features)`.
- If None, then `max_features=n_features`.

.. versionchanged:: 1.1
The default of `max_features` changed from `"auto"` to `"sqrt"`.

Note: the search for a split does not stop until at least one
valid partition of the node samples is found, even if it requires to
effectively inspect more than ``max_features`` features.
4
bootstrap bootstrap: bool, default=True

Whether bootstrap samples are used when building trees. If False, the
whole dataset is used to build each tree.
False
random_state random_state: int, RandomState instance or None, default=None

Controls both the randomness of the bootstrapping of the samples used
when building trees (if ``bootstrap=True``) and the sampling of the
features to consider when looking for the best split at each node
(if ``max_features < n_features``).
See :term:`Glossary <random_state>` for details.
RandomState(M...0x784117609540
max_depth max_depth: int, default=None

The maximum depth of the tree. If None, then nodes are expanded until
all leaves are pure or until all leaves contain less than
min_samples_split samples.
None
min_samples_leaf min_samples_leaf: int or float, default=1

The minimum number of samples required to be at a leaf node.
A split point at any depth will only be considered if it leaves at
least ``min_samples_leaf`` training samples in each of the left and
right branches. This may have the effect of smoothing the model,
especially in regression.

- If int, then consider `min_samples_leaf` as the minimum number.
- If float, then `min_samples_leaf` is a fraction and
`ceil(min_samples_leaf * n_samples)` are the minimum
number of samples for each node.

.. versionchanged:: 0.18
Added float values for fractions.
1
min_weight_fraction_leaf min_weight_fraction_leaf: float, default=0.0

The minimum weighted fraction of the sum total of weights (of all
the input samples) required to be at a leaf node. Samples have
equal weight when sample_weight is not provided.
0.0
max_leaf_nodes max_leaf_nodes: int, default=None

Grow trees with ``max_leaf_nodes`` in best-first fashion.
Best nodes are defined as relative reduction in impurity.
If None then unlimited number of leaf nodes.
None
min_impurity_decrease min_impurity_decrease: float, default=0.0

A node will be split if this split induces a decrease of the impurity
greater than or equal to this value.

The weighted impurity decrease equation is the following::

N_t / N * (impurity - N_t_R / N_t * right_impurity
- N_t_L / N_t * left_impurity)

where ``N`` is the total number of samples, ``N_t`` is the number of
samples at the current node, ``N_t_L`` is the number of samples in the
left child, and ``N_t_R`` is the number of samples in the right child.

``N``, ``N_t``, ``N_t_R`` and ``N_t_L`` all refer to the weighted sum,
if ``sample_weight`` is passed.

.. versionadded:: 0.19
0.0
oob_score oob_score: bool or callable, default=False

Whether to use out-of-bag samples to estimate the generalization score.
By default, :func:`~sklearn.metrics.accuracy_score` is used.
Provide a callable with signature `metric(y_true, y_pred)` to use a
custom metric. Only available if `bootstrap=True`.

For an illustration of out-of-bag (OOB) error estimation, see the example
:ref:`sphx_glr_auto_examples_ensemble_plot_ensemble_oob.py`.
False
n_jobs n_jobs: int, default=None

The number of jobs to run in parallel. :meth:`fit`, :meth:`predict`,
:meth:`decision_path` and :meth:`apply` are all parallelized over the
trees. ``None`` means 1 unless in a :obj:`joblib.parallel_backend`
context. ``-1`` means using all processors. See :term:`Glossary
<n_jobs>` for more details.
None
verbose verbose: int, default=0

Controls the verbosity when fitting and predicting.
0
warm_start warm_start: bool, default=False

When set to ``True``, reuse the solution of the previous call to fit
and add more estimators to the ensemble, otherwise, just fit a whole
new forest. See :term:`Glossary <warm_start>` and
:ref:`tree_ensemble_warm_start` for details.
False
class_weight class_weight: {"balanced", "balanced_subsample"}, dict or list of dicts, default=None

Weights associated with classes in the form ``{class_label: weight}``.
If not given, all classes are supposed to have weight one. For
multi-output problems, a list of dicts can be provided in the same
order as the columns of y.

Note that for multioutput (including multilabel) weights should be
defined for each class of every column in its own dict. For example,
for four-class multilabel classification weights should be
[{0: 1, 1: 1}, {0: 1, 1: 5}, {0: 1, 1: 1}, {0: 1, 1: 1}] instead of
[{1:1}, {2:5}, {3:1}, {4:1}].

The "balanced" mode uses the values of y to automatically adjust
weights inversely proportional to class frequencies in the input data
as ``n_samples / (n_classes * np.bincount(y))``

The "balanced_subsample" mode is the same as "balanced" except that
weights are computed based on the bootstrap sample for every tree
grown.

For multi-output, the weights of each column of y will be multiplied.

Note that these weights will be multiplied with sample_weight (passed
through the fit method) if sample_weight is specified.
None
ccp_alpha ccp_alpha: non-negative float, default=0.0

Complexity parameter used for Minimal Cost-Complexity Pruning. The
subtree with the largest cost complexity that is smaller than
``ccp_alpha`` will be chosen. By default, no pruning is performed. See
:ref:`minimal_cost_complexity_pruning` for details. See
:ref:`sphx_glr_auto_examples_tree_plot_cost_complexity_pruning.py`
for an example of such pruning.

.. versionadded:: 0.22
0.0
max_samples max_samples: int or float, default=None

If bootstrap is True, the number of samples to draw from X
to train each base estimator.

- If None (default), then draw `X.shape[0]` samples irrespective of
`sample_weight`.
- If int, then draw `max_samples` samples.
- If float, then draw `max_samples * X.shape[0]` unweighted samples
or `max_samples * sample_weight.sum()` weighted samples.

.. versionadded:: 0.22

.. versionchanged:: 1.9
Float `max_samples` is relative to `sample_weight.sum()` instead of
`X.shape[0]` for weighted samples.
None
monotonic_cst monotonic_cst: array-like of int of shape (n_features), default=None

Indicates the monotonicity constraint to enforce on each feature.
- 1: monotonic increase
- 0: no constraint
- -1: monotonic decrease

If monotonic_cst is None, no constraints are applied.

Monotonicity constraints are not supported for:
- multiclass classifications (i.e. when `n_classes > 2`),
- multioutput classifications (i.e. when `n_outputs_ > 1`).

The constraints hold over the probability of the positive class.

Read more in the :ref:`User Guide <monotonic_cst_gbdt>`.

.. versionadded:: 1.4
None
Fitted attributes
Name Type Value
classes_ classes_: ndarray of shape (n_classes,) or a list of such arrays

The classes labels (single output problem), or a list of arrays of
class labels (multi-output problem).
ndarray[int64](2,) [0,1]
estimator_ estimator_: :class:`~sklearn.tree.DecisionTreeClassifier`

The child estimator template used to create the collection of fitted
sub-estimators.

.. versionadded:: 1.2
`base_estimator_` was renamed to `estimator_`.
DecisionTreeClassifier DecisionTreeClassifier()
estimators_ estimators_: list of DecisionTreeClassifier

The collection of fitted sub-estimators.
list [DecisionTreeC...ate=214286498), DecisionTreeC...ate=631739714), DecisionTreeC...te=1554730159), DecisionTreeC...tate=25323325), ...]
estimators_samples_ estimators_samples_: list of arrays

The subset of drawn samples (i.e., the in-bag samples) for each base
estimator. Each subset is defined by an array of the indices selected.

.. versionadded:: 1.4
list [array([ 0, ..., dtype=int32), array([ 0, ..., dtype=int32), array([ 0, ..., dtype=int32), array([ 0, ..., dtype=int32), ...]
feature_importances_ feature_importances_: ndarray of shape (n_features,)

The impurity-based feature importances.
The higher, the more important the feature.
The importance of a feature is computed as the (normalized)
total reduction of the criterion brought by that feature. It is also
known as the Gini importance.

Warning: impurity-based feature importances can be misleading for
high cardinality features (many unique values). See
:func:`sklearn.inspection.permutation_importance` as an alternative.
ndarray[float64](12,) [0.15,0.22,0.02,...,0.02,0.02,0.02]
n_classes_ n_classes_: int or list

The number of classes (single output problem), or a list containing the
number of classes for each output (multi-output problem).
int 2
n_features_in_ n_features_in_: int

Number of features seen during :term:`fit`.

.. versionadded:: 0.24
int 12
n_outputs_ n_outputs_: int

The number of outputs when ``fit`` is performed.
int 1


We can now use the cv_results_ attribute of the search estimator to inspect and plot the evolution of the search.

results = pd.DataFrame(rsh.cv_results_)
results["params_str"] = results.params.apply(str)
results.drop_duplicates(subset=("params_str", "iter"), inplace=True)
mean_scores = results.pivot(
    index="iter", columns="params_str", values="mean_test_score"
)
ax = mean_scores.plot(legend=False, alpha=0.6)

labels = [
    f"iter={i}\nn_samples={rsh.n_resources_[i]}\nn_candidates={rsh.n_candidates_[i]}"
    for i in range(rsh.n_iterations_)
]

ax.set_xticks(range(rsh.n_iterations_))
ax.set_xticklabels(labels, rotation=45, multialignment="left")
ax.set_title("Scores of candidates over iterations")
ax.set_ylabel("mean test score", fontsize=15)
ax.set_xlabel("iterations", fontsize=15)
plt.tight_layout()
plt.show()
Scores of candidates over iterations

Number of candidates and amount of resource at each iteration

At the first iteration, a small amount of resources is used. The resource here is the number of samples that the estimators are trained on. All candidates are evaluated.

At the second iteration, only the best half of the candidates is evaluated. The number of allocated resources is doubled: candidates are evaluated on twice as many samples.

This process is repeated until the last iteration, where only 2 candidates are left. The best candidate is the candidate that has the best score at the last iteration.

Total running time of the script: (0 minutes 7.454 seconds)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_successive_halving_iterations.ipynb

Download Python source code: plot_successive_halving_iterations.py

Download zipped: plot_successive_halving_iterations.zip

Related examples

Comparing randomized search and grid search for hyperparameter estimation

Comparison between grid search and successive halving

Release Highlights for scikit-learn 0.24

Analysis of the convergence of penalized logistic regression models

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/model_selection/plot_successive_halving_iterations.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API