
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/release_highlights/plot_release_highlights_0_24_0.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_auto_examples_release_highlights_plot_release_highlights_0_24_0.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_auto_examples_release_highlights_plot_release_highlights_0_24_0.py:


========================================
Release Highlights for scikit-learn 0.24
========================================

.. currentmodule:: sklearn

We are pleased to announce the release of scikit-learn 0.24! Many bug fixes
and improvements were added, as well as some new key features. We detail
below a few of the major features of this release. **For an exhaustive list of
all the changes**, please refer to the :ref:`release notes <release_notes_0_24>`.

To install the latest version (with pip)::

    pip install --upgrade scikit-learn

or with conda::

    conda install -c conda-forge scikit-learn

.. GENERATED FROM PYTHON SOURCE LINES 25-51

Successive Halving estimators for tuning hyper-parameters
---------------------------------------------------------
Successive Halving, a state of the art method, is now available to
explore the space of the parameters and identify their best combination.
:class:`~sklearn.model_selection.HalvingGridSearchCV` and
:class:`~sklearn.model_selection.HalvingRandomSearchCV` can be
used as drop-in replacement for
:class:`~sklearn.model_selection.GridSearchCV` and
:class:`~sklearn.model_selection.RandomizedSearchCV`.
Successive Halving is an iterative selection process illustrated in the
figure below. The first iteration is run with a small amount of resources,
where the resource typically corresponds to the number of training samples,
but can also be an arbitrary integer parameter such as `n_estimators` in a
random forest. Only a subset of the parameter candidates are selected for the
next iteration, which will be run with an increasing amount of allocated
resources. Only a subset of candidates will last until the end of the
iteration process, and the best parameter candidate is the one that has the
highest score on the last iteration.

Read more in the :ref:`User Guide <successive_halving_user_guide>` (note:
the Successive Halving estimators are still :term:`experimental
<experimental>`).

.. figure:: ../model_selection/images/sphx_glr_plot_successive_halving_iterations_001.png
  :target: ../model_selection/plot_successive_halving_iterations.html
  :align: center

.. GENERATED FROM PYTHON SOURCE LINES 51-80

.. code-block:: Python


    import numpy as np
    from scipy.stats import randint

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

    rng = np.random.RandomState(0)

    X, y = make_classification(n_samples=700, random_state=rng)

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

    param_dist = {
        "max_depth": [3, None],
        "max_features": randint(1, 11),
        "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)
    rsh.best_params_





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    {'bootstrap': True, 'criterion': 'gini', 'max_depth': None, 'max_features': 10, 'min_samples_split': 10}



.. GENERATED FROM PYTHON SOURCE LINES 81-100

Native support for categorical features in HistGradientBoosting estimators
--------------------------------------------------------------------------
:class:`~sklearn.ensemble.HistGradientBoostingClassifier` and
:class:`~sklearn.ensemble.HistGradientBoostingRegressor` now have native
support for categorical features: they can consider splits on non-ordered,
categorical data. Read more in the :ref:`User Guide
<categorical_support_gbdt>`.

.. figure:: ../ensemble/images/sphx_glr_plot_gradient_boosting_categorical_001.png
  :target: ../ensemble/plot_gradient_boosting_categorical.html
  :align: center

The plot shows that the new native support for categorical features leads to
fitting times that are comparable to models where the categories are treated
as ordered quantities, i.e. simply ordinal-encoded. Native support is also
more expressive than both one-hot encoding and ordinal encoding. However, to
use the new `categorical_features` parameter, it is still required to
preprocess the data within a pipeline as demonstrated in this :ref:`example
<sphx_glr_auto_examples_ensemble_plot_gradient_boosting_categorical.py>`.

.. GENERATED FROM PYTHON SOURCE LINES 102-110

Improved performances of HistGradientBoosting estimators
--------------------------------------------------------
The memory footprint of :class:`ensemble.HistGradientBoostingRegressor` and
:class:`ensemble.HistGradientBoostingClassifier` has been significantly
improved during calls to `fit`. In addition, histogram initialization is now
done in parallel which results in slight speed improvements.
See more in the `Benchmark page
<https://scikit-learn.org/scikit-learn-benchmarks/>`_.

.. GENERATED FROM PYTHON SOURCE LINES 112-120

New self-training meta-estimator
--------------------------------
A new self-training implementation, based on `Yarowski's algorithm
<https://doi.org/10.3115/981658.981684>`_ can now be used with any
classifier that implements :term:`predict_proba`. The sub-classifier
will behave as a
semi-supervised classifier, allowing it to learn from unlabeled data.
Read more in the :ref:`User guide <self_training>`.

.. GENERATED FROM PYTHON SOURCE LINES 120-135

.. code-block:: Python


    import numpy as np

    from sklearn import datasets
    from sklearn.linear_model import LogisticRegression
    from sklearn.semi_supervised import SelfTrainingClassifier

    rng = np.random.RandomState(42)
    iris = datasets.load_iris()
    random_unlabeled_points = rng.rand(iris.target.shape[0]) < 0.3
    iris.target[random_unlabeled_points] = -1
    clf = LogisticRegression()
    self_training_model = SelfTrainingClassifier(clf)
    self_training_model.fit(iris.data, iris.target)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    $BUILD_DIR/.pybuild/cpython3_3.14/build/sklearn/linear_model/_logistic.py:599: ConvergenceWarning:

    lbfgs failed to converge after 100 iteration(s) (status=1):
    STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT

    Increase the number of iterations to improve the convergence (max_iter=100).
    You might also want to scale the data as shown in:
        https://scikit-learn.org/stable/modules/preprocessing.html
    Please also refer to the documentation for alternative solver options:
        https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression

    $BUILD_DIR/.pybuild/cpython3_3.14/build/sklearn/linear_model/_logistic.py:599: ConvergenceWarning:

    lbfgs failed to converge after 100 iteration(s) (status=1):
    STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT

    Increase the number of iterations to improve the convergence (max_iter=100).
    You might also want to scale the data as shown in:
        https://scikit-learn.org/stable/modules/preprocessing.html
    Please also refer to the documentation for alternative solver options:
        https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression



.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <style>.sk-global {
      /* Definition of color scheme common for light and dark mode */
      --sklearn-color-text: #000;
      --sklearn-color-text-muted: #666;
      --sklearn-color-line: gray;
      /* Definition of color scheme for unfitted estimators */
      --sklearn-color-unfitted-level-0: #fff5e6;
      --sklearn-color-unfitted-level-1: #f6e4d2;
      --sklearn-color-unfitted-level-2: #ffe0b3;
      --sklearn-color-unfitted-level-3: chocolate;
      /* Definition of color scheme for fitted estimators */
      --sklearn-color-fitted-level-0: #f0f8ff;
      --sklearn-color-fitted-level-1: #d4ebff;
      --sklearn-color-fitted-level-2: #b3dbfd;
      --sklearn-color-fitted-level-3: cornflowerblue;
    }

    .sk-global.light {
      /* Specific color for light theme */
      --sklearn-color-text-on-default-background: black;
      --sklearn-color-background: white;
      --sklearn-color-border-box: black;
      --sklearn-color-icon: #696969;
    }

    .sk-global.dark {
      --sklearn-color-text-on-default-background: white;
      --sklearn-color-background: #111;
      --sklearn-color-border-box: white;
      --sklearn-color-icon: #878787;
    }

    .sk-global {
      color: var(--sklearn-color-text);
    }

    .sk-global pre {
      padding: 0;
    }

    .sk-global input.sk-hidden--visually {
      border: 0;
      clip-path: inset(100%);
      height: 1px;
      margin: -1px;
      overflow: hidden;
      padding: 0;
      position: absolute;
      width: 1px;
    }

    .sk-global div.sk-dashed-wrapped {
      border: 1px dashed var(--sklearn-color-line);
      margin: 0 0.4em 0.5em 0.4em;
      box-sizing: border-box;
      padding-bottom: 0.4em;
      background-color: var(--sklearn-color-background);
    }

    .sk-global div.sk-container {
      /* jupyter's `normalize.less` sets `[hidden] { display: none; }`
         but bootstrap.min.css set `[hidden] { display: none !important; }`
         so we also need the `!important` here to be able to override the
         default hidden behavior on the sphinx rendered scikit-learn.org.
         See: https://github.com/scikit-learn/scikit-learn/issues/21755 */
      display: inline-block !important;
      position: relative;
    }

    .sk-global div.sk-text-repr-fallback {
      display: none;
    }

    div.sk-parallel-item,
    div.sk-serial,
    div.sk-item {
      /* draw centered vertical line to link estimators */
      background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));
      background-size: 2px 100%;
      background-repeat: no-repeat;
      background-position: center center;
    }

    /* Parallel-specific style estimator block */

    .sk-global div.sk-parallel-item::after {
      content: "";
      width: 100%;
      border-bottom: 2px solid var(--sklearn-color-text-on-default-background);
      flex-grow: 1;
    }

    .sk-global div.sk-parallel {
      display: flex;
      align-items: stretch;
      justify-content: center;
      background-color: var(--sklearn-color-background);
      position: relative;
    }

    .sk-global div.sk-parallel-item {
      display: flex;
      flex-direction: column;
    }

    .sk-global div.sk-parallel-item:first-child::after {
      align-self: flex-end;
      width: 50%;
    }

    .sk-global div.sk-parallel-item:last-child::after {
      align-self: flex-start;
      width: 50%;
    }

    .sk-global div.sk-parallel-item:only-child::after {
      width: 0;
    }

    /* Serial-specific style estimator block */

    .sk-global div.sk-serial {
      display: flex;
      flex-direction: column;
      align-items: center;
      background-color: var(--sklearn-color-background);
      padding-right: 1em;
      padding-left: 1em;
    }


    /* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is
    clickable and can be expanded/collapsed.
    - Pipeline and ColumnTransformer use this feature and define the default style
    - Estimators will overwrite some part of the style using the `sk-estimator` class
    */

    /* Pipeline and ColumnTransformer style (default) */

    .sk-global div.sk-toggleable {
      /* Default theme specific background. It is overwritten whether we have a
      specific estimator or a Pipeline/ColumnTransformer */
      background-color: var(--sklearn-color-background);
    }

    /* Toggleable label */
    .sk-global label.sk-toggleable__label {
      cursor: pointer;
      display: flex;
      width: 100%;
      margin-bottom: 0;
      padding: 0.5em;
      box-sizing: border-box;
      text-align: center;
      align-items: center;
      justify-content: center;
      gap: 0.5em;
    }

    .sk-global label.sk-toggleable__label .caption {
      font-size: 0.6rem;
      font-weight: lighter;
      color: var(--sklearn-color-text-muted);
    }

    .sk-global label.sk-toggleable__label-arrow:before {
      /* Arrow on the left of the label */
      content: "▸";
      float: left;
      margin-right: 0.25em;
      color: var(--sklearn-color-icon);
    }

    .sk-global label.sk-toggleable__label-arrow:hover:before {
      color: var(--sklearn-color-text);
    }

    /* Toggleable content - dropdown */

    .sk-global div.sk-toggleable__content {
      display: none;
      text-align: left;
      /* unfitted */
      background-color: var(--sklearn-color-unfitted-level-0);
    }

    .sk-global div.sk-toggleable__content.fitted {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-0);
    }

    .sk-global div.sk-toggleable__content pre {
      margin: 0.2em;
      border-radius: 0.25em;
      color: var(--sklearn-color-text);
      /* unfitted */
      background-color: var(--sklearn-color-unfitted-level-0);
    }

    .sk-global div.sk-toggleable__content.fitted pre {
      /* unfitted */
      background-color: var(--sklearn-color-fitted-level-0);
    }

    .sk-global input.sk-toggleable__control:checked~div.sk-toggleable__content {
      /* Expand drop-down */
      display: block;
      width: 100%;
      overflow: visible;
    }

    .sk-global input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {
      content: "▾";
    }

    /* Pipeline/ColumnTransformer-specific style */

    .sk-global div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {
      color: var(--sklearn-color-text);
      background-color: var(--sklearn-color-unfitted-level-2);
    }

    .sk-global div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {
      background-color: var(--sklearn-color-fitted-level-2);
    }

    /* Estimator-specific style */

    /* Colorize estimator box */
    .sk-global div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {
      /* unfitted */
      background-color: var(--sklearn-color-unfitted-level-2);
    }

    .sk-global div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-2);
    }

    .sk-global div.sk-label label.sk-toggleable__label,
    .sk-global div.sk-label label {
      /* The background is the default theme color */
      color: var(--sklearn-color-text-on-default-background);
    }

    /* On hover, darken the color of the background */
    .sk-global div.sk-label:hover label.sk-toggleable__label {
      color: var(--sklearn-color-text);
      background-color: var(--sklearn-color-unfitted-level-2);
    }

    /* Label box, darken color on hover, fitted */
    .sk-global div.sk-label.fitted:hover label.sk-toggleable__label.fitted {
      color: var(--sklearn-color-text);
      background-color: var(--sklearn-color-fitted-level-2);
    }

    /* Estimator label */

    .sk-global div.sk-label label {
      font-family: monospace;
      font-weight: bold;
      line-height: 1.2em;
    }

    .sk-global div.sk-label-container {
      text-align: center;
    }

    /* Estimator-specific */
    .sk-global div.sk-estimator {
      font-family: monospace;
      border: 1px dotted var(--sklearn-color-border-box);
      border-radius: 0.25em;
      box-sizing: border-box;
      margin-bottom: 0.5em;
      /* unfitted */
      background-color: var(--sklearn-color-unfitted-level-0);
    }

    .sk-global div.sk-estimator.fitted {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-0);
    }

    /* on hover */
    .sk-global div.sk-estimator:hover {
      /* unfitted */
      background-color: var(--sklearn-color-unfitted-level-2);
    }

    .sk-global div.sk-estimator.fitted:hover {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-2);
    }

    /* Specification for estimator info (e.g. "i" and "?") */

    /* Common style for "i" and "?" */

    .sk-estimator-doc-link,
    a:link.sk-estimator-doc-link,
    a:visited.sk-estimator-doc-link {
      float: right;
      font-size: smaller;
      line-height: 1em;
      font-family: monospace;
      background-color: var(--sklearn-color-unfitted-level-0);
      border-radius: 1em;
      height: 1em;
      width: 1em;
      text-decoration: none !important;
      margin-left: 0.5em;
      text-align: center;
      /* unfitted */
      border: var(--sklearn-color-unfitted-level-3) 1pt solid;
      color: var(--sklearn-color-unfitted-level-3);
    }

    .sk-estimator-doc-link.fitted,
    a:link.sk-estimator-doc-link.fitted,
    a:visited.sk-estimator-doc-link.fitted {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-0);
      border: var(--sklearn-color-fitted-level-3) 1pt solid;
      color: var(--sklearn-color-fitted-level-3);
    }

    /* On hover */
    div.sk-estimator:hover .sk-estimator-doc-link:hover,
    .sk-estimator-doc-link:hover,
    div.sk-label-container:hover .sk-estimator-doc-link:hover,
    .sk-estimator-doc-link:hover {
      /* unfitted */
      background-color: var(--sklearn-color-unfitted-level-3);
      border: var(--sklearn-color-fitted-level-0) 1pt solid;
      color: var(--sklearn-color-unfitted-level-0);
      text-decoration: none;
    }

    div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,
    .sk-estimator-doc-link.fitted:hover,
    div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,
    .sk-estimator-doc-link.fitted:hover {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-3);
      border: var(--sklearn-color-fitted-level-0) 1pt solid;
      color: var(--sklearn-color-fitted-level-0);
      text-decoration: none;
    }

    /* Span, style for the box shown on hovering the info icon */
    .sk-estimator-doc-link span {
      display: none;
      z-index: 9999;
      position: relative;
      font-weight: normal;
      right: .2ex;
      padding: .5ex;
      margin: .5ex;
      width: min-content;
      min-width: 20ex;
      max-width: 50ex;
      color: var(--sklearn-color-text);
      box-shadow: 2pt 2pt 4pt #999;
      /* unfitted */
      background: var(--sklearn-color-unfitted-level-0);
      border: .5pt solid var(--sklearn-color-unfitted-level-3);
    }

    .sk-estimator-doc-link.fitted span {
      /* fitted */
      background: var(--sklearn-color-fitted-level-0);
      border: var(--sklearn-color-fitted-level-3);
    }

    .sk-estimator-doc-link:hover span {
      display: block;
    }

    /* "?"-specific style due to the `<a>` HTML tag */

    .sk-global a.estimator_doc_link {
      float: right;
      font-size: 1rem;
      line-height: 1em;
      font-family: monospace;
      background-color: var(--sklearn-color-unfitted-level-0);
      border-radius: 1rem;
      height: 1rem;
      width: 1rem;
      text-decoration: none;
      /* unfitted */
      color: var(--sklearn-color-unfitted-level-1);
      border: var(--sklearn-color-unfitted-level-1) 1pt solid;
    }

    .sk-global a.estimator_doc_link.fitted {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-0);
      border: var(--sklearn-color-fitted-level-1) 1pt solid;
      color: var(--sklearn-color-fitted-level-1);
    }

    /* On hover */
    .sk-global a.estimator_doc_link:hover {
      /* unfitted */
      background-color: var(--sklearn-color-unfitted-level-3);
      color: var(--sklearn-color-background);
      text-decoration: none;
    }

    .sk-global a.estimator_doc_link.fitted:hover {
      /* fitted */
      background-color: var(--sklearn-color-fitted-level-3);
    }

    .sk-top-container.sk-global {
      /* pydata-sphinx-theme hides overflow, so scrolling is disabled.
       We need to set it to !important and add tabindex="0" in the HTML
       to allow keyboard-only users to navigate the display. */
      overflow-x: scroll !important;
      max-width: 100%;
    }

    .estimator-table {
        font-family: monospace;
    }

    .estimator-table summary {
        padding: .5rem;
        cursor: pointer;
    }

    .estimator-table summary::marker {
        font-size: 0.7rem;
    }

    .estimator-table details[open] {
        padding-left: 0.1rem;
        padding-right: 0.1rem;
        padding-bottom: 0.3rem;
    }

    .estimator-table .parameters-table {
        margin-left: auto !important;
        margin-right: auto !important;
        margin-top: 0;
    }

    .estimator-table .parameters-table tr:nth-child(odd) {
        background-color: #fff;
    }

    .estimator-table .parameters-table tr:nth-child(even) {
        background-color: #f6f6f6;
    }

    .estimator-table .parameters-table tr:hover td {
        background-color: #e0e0e0;
    }

    .estimator-table table :is(td, th) {
        border: 1px solid rgba(106, 105, 104, 0.232);
    }

    /*
        `table td`is set in notebook with right text-align.
        We need to overwrite it.
    */
    .estimator-table table td.param {
        text-align: left;
        position: relative;
        padding: 0;
    }

    .user-set td {
        color:rgb(255, 94, 0);
        text-align: left !important;
    }

    .user-set td.value {
        color:rgb(255, 94, 0);
        background-color: transparent;
    }

    .default td, .estimator-table th {
        color: black;
        text-align: left !important;
    }

    .user-set td i,
    .default td i {
        color: black;
    }

    td.fitted-att-type {
        white-space: preserve nowrap;
    }

    /*
        Styles for parameter documentation links
        We need styling for visited so jupyter doesn't overwrite it
    */
    a.param-doc-link,
    a.param-doc-link:link,
    a.param-doc-link:visited {
        text-decoration: underline dashed;
        text-underline-offset: .3em;
        color: inherit;
        display: block;
        padding: .5em;
    }

    @supports(anchor-name: --doc-link) {
        a.param-doc-link,
        a.param-doc-link:link,
        a.param-doc-link:visited {
        anchor-name: --doc-link;
        }
    }

    /* "hack" to make the entire area of the cell containing the link clickable */
    a.param-doc-link::before {
        position: absolute;
        content: "";
        inset: 0;
    }

    .param-doc-description {
        display: none;
        position: absolute;
        z-index: 9999;
        left: 0;
        padding: .5ex;
        margin-left: 1.5em;
        color: var(--sklearn-color-text);
        box-shadow: .3em .3em .4em #999;
        width: max-content;
        text-align: left;
        max-height: 10em;
        overflow-y: auto;

        /* unfitted */
        background: var(--sklearn-color-unfitted-level-0);
        border: thin solid var(--sklearn-color-unfitted-level-3);
    }

    @supports(position-area: center right) {
        .param-doc-description {
        position-area: center right;
        position: fixed;
        margin-left: 0;
        }
    }

    /* Fitted state for parameter tooltips */
    .fitted .param-doc-description {
        /* fitted */
        background: var(--sklearn-color-fitted-level-0);
        border: thin solid var(--sklearn-color-fitted-level-3);
    }

    .param-doc-link:hover .param-doc-description {
        display: block;
    }

    .copy-paste-icon {
        background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);
        background-repeat: no-repeat;
        background-size: 14px 14px;
        background-position: 0;
        display: inline-block;
        width: 14px;
        height: 14px;
        cursor: pointer;
    }

    .features {
      font-family: monospace;
      cursor: pointer;
      background-color: var(--sklearn-color-unfitted-level-0);
      border: 1px dotted var(--sklearn-color-border-box);
      border-radius: .20em;
      margin-bottom: 0.5em;
      font-size: inherit; /* Needed for jupyter */
    }

    .features.fitted {
      background-color: var(--sklearn-color-fitted-level-0);
    }

    .features summary {
      cursor: pointer;
      display: flex;
      margin-bottom: 0;
      text-align: center;
      align-items: center;
      justify-content: center;
      gap: 0.5em;
      padding: .25em;
    }

    .features details[open] > summary {
      color: var(--sklearn-color-text);
      background-color: var(--sklearn-color-unfitted-level-2);
      border-radius: .20em 0 0 0;
    }

    .features.fitted details[open] > summary {
      background-color: var(--sklearn-color-fitted-level-2);
      border-radius: .20em 0 0 0;
    }

    .features details > summary .arrow::before {
      content: "▸";
      color: grey;
    }

    .features details[open] > summary .arrow::before {
      content: "▾";
    }

    .features details:hover > summary {
      margin: 0;
      background-color: var(--sklearn-color-unfitted-level-2);
    }

    .features.fitted details:hover > summary {
      margin: 0;
      background-color: var(--sklearn-color-fitted-level-2);
    }

    .features .features-container {
      max-width: 15em;
      max-height: 10em;
      overflow: auto;
      scrollbar-width: thin;
      padding: .25em 0.1rem;
      background-color: var(--sklearn-color-unfitted-level-0);
      border-radius: 0 0 .5em .5em;
    }

    .features.fitted .features-container {
      background-color: var(--sklearn-color-fitted-level-0);
    }

    .features .image-container {
      block-size: 1em;
      inline-size: 1em;
      padding: 0;
      margin: 0%;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .features .copy-paste-icon {
      background-size: 1em 1em;
      width: 1em;
      height: 1em;
      filter: grayscale(100%) opacity(60%);
    }

    .features .features-container table {
      width: 100%;
      margin: 0.01em;
    }

    .features .features-container table tr:nth-child(odd) {
      background-color: #fff;
    }

    .features .features-container table tr:nth-child(even) {
      background-color: #f6f6f6;
    }

    .features .features-container table tr:hover {
      background-color: #e0e0e0;
    }

    .features .features-container table {
      table-layout: inherit;
    }

    .features .features-container table td {
      text-align: left;
      padding: 0 0.5em;
      border: 1px solid rgba(106, 105, 104, 0.232);
      white-space: nowrap;
      color: var(--sklearn-color-text);
    }

    .total_features {
      display: flex;
      justify-content: center;
      margin-top: 0.5em;
    }
    </style><body><div id="sk-container-id-5" tabindex="0" class="sk-top-container sk-global"><div class="sk-text-repr-fallback"><pre>SelfTrainingClassifier(estimator=LogisticRegression())</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class="sk-container" hidden><div class="sk-item sk-dashed-wrapped"><div class="sk-label-container"><div class="sk-label fitted sk-toggleable"><input class="sk-toggleable__control sk-hidden--visually sk-global" id="sk-estimator-id-11" type="checkbox" ><label for="sk-estimator-id-11" class="sk-toggleable__label fitted sk-toggleable__label-arrow"><div><div>SelfTrainingClassifier</div></div><div><a class="sk-estimator-doc-link fitted" rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html">?<span>Documentation for SelfTrainingClassifier</span></a><span class="sk-estimator-doc-link fitted">i<span>Fitted</span></span></div></label><div class="sk-toggleable__content fitted" data-param-prefix="">
            <div class="estimator-table">
                <details>
                    <summary>Parameters</summary>
                    <table class="parameters-table">
                      <tbody>
                    
            <tr class="user-set">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('estimator',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-estimator;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=estimator,-estimator%20object">
                estimator
                <span class="param-doc-description"
                style="position-anchor: --doc-link-estimator;">
                estimator: estimator object<br><br>An estimator object implementing `fit` and `predict_proba`.<br>Invoking the `fit` method will fit a clone of the passed estimator,<br>which will be stored in the `estimator_` attribute.<br><br>.. versionadded:: 1.6<br>    `estimator` was added to replace `base_estimator`.</span>
            </a>
        </td>
                <td class="value">LogisticRegression()</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('threshold',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-threshold;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=threshold,-float%2C%20default%3D0.75">
                threshold
                <span class="param-doc-description"
                style="position-anchor: --doc-link-threshold;">
                threshold: float, default=0.75<br><br>The decision threshold for use with `criterion=&#x27;threshold&#x27;`.<br>Should be in [0, 1). When using the `&#x27;threshold&#x27;` criterion, a<br>:ref:`well calibrated classifier &lt;calibration&gt;` should be used.</span>
            </a>
        </td>
                <td class="value">0.75</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('criterion',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-criterion;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=criterion,-%7B%27threshold%27%2C%20%27k_best%27%7D%2C%20default%3D%27threshold%27">
                criterion
                <span class="param-doc-description"
                style="position-anchor: --doc-link-criterion;">
                criterion: {&#x27;threshold&#x27;, &#x27;k_best&#x27;}, default=&#x27;threshold&#x27;<br><br>The selection criterion used to select which labels to add to the<br>training set. If `&#x27;threshold&#x27;`, pseudo-labels with prediction<br>probabilities above `threshold` are added to the dataset. If `&#x27;k_best&#x27;`,<br>the `k_best` pseudo-labels with highest prediction probabilities are<br>added to the dataset. When using the &#x27;threshold&#x27; criterion, a<br>:ref:`well calibrated classifier &lt;calibration&gt;` should be used.</span>
            </a>
        </td>
                <td class="value">&#x27;threshold&#x27;</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('k_best',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-k_best;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=k_best,-int%2C%20default%3D10">
                k_best
                <span class="param-doc-description"
                style="position-anchor: --doc-link-k_best;">
                k_best: int, default=10<br><br>The amount of samples to add in each iteration. Only used when<br>`criterion=&#x27;k_best&#x27;`.</span>
            </a>
        </td>
                <td class="value">10</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('max_iter',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-max_iter;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=max_iter,-int%20or%20None%2C%20default%3D10">
                max_iter
                <span class="param-doc-description"
                style="position-anchor: --doc-link-max_iter;">
                max_iter: int or None, default=10<br><br>Maximum number of iterations allowed. Should be greater than or equal<br>to 0. If it is `None`, the classifier will continue to predict labels<br>until no new pseudo-labels are added, or all unlabeled samples have<br>been labeled.</span>
            </a>
        </td>
                <td class="value">10</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('verbose',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-verbose;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=verbose,-bool%2C%20default%3DFalse">
                verbose
                <span class="param-doc-description"
                style="position-anchor: --doc-link-verbose;">
                verbose: bool, default=False<br><br>Enable verbose output.</span>
            </a>
        </td>
                <td class="value">False</td>
            </tr>
    
                      </tbody>
                    </table>
                </details>
            </div>
    
            <div class="estimator-table">
                <details>
                    <summary>Fitted attributes</summary>
                    <table class="parameters-table">
                        <tbody>
                            <tr>
                            <th>Name</th>
                            <th>Type</th>
                            <th>Value</th>
                            </tr>
                        
           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-classes_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=classes_,-ndarray%20or%20list%20of%20ndarray%20of%20shape%20%28n_classes%2C%29">
                classes_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-classes_;">
                classes_: ndarray or list of ndarray of shape (n_classes,)<br><br>Class labels for each output. (Taken from the trained<br>`estimator_`).</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[int64](3,)</td>
               <td>[0,1,2]</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-estimator_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=estimator_,-estimator%20object">
                estimator_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-estimator_;">
                estimator_: estimator object<br><br>The fitted estimator.</span>
            </a>
        </td>
               <td class="fitted-att-type">LogisticRegression</td>
               <td>LogisticRegression()</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-labeled_iter_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=labeled_iter_,-ndarray%20of%20shape%20%28n_samples%2C%29">
                labeled_iter_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-labeled_iter_;">
                labeled_iter_: ndarray of shape (n_samples,)<br><br>The iteration in which each sample was labeled. When a sample has<br>iteration 0, the sample was already labeled in the original dataset.<br>When a sample has iteration -1, the sample was not labeled in any<br>iteration.</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[int64](150,)</td>
               <td>[0,0,0,...,0,1,1]</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-n_features_in_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=n_features_in_,-int">
                n_features_in_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-n_features_in_;">
                n_features_in_: int<br><br>Number of features seen during :term:`fit`.<br><br>.. versionadded:: 0.24</span>
            </a>
        </td>
               <td class="fitted-att-type">int</td>
               <td>4</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-n_iter_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=n_iter_,-int">
                n_iter_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-n_iter_;">
                n_iter_: int<br><br>The number of rounds of self-training, that is the number of times the<br>base estimator is fitted on relabeled variants of the training set.</span>
            </a>
        </td>
               <td class="fitted-att-type">int</td>
               <td>2</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-termination_condition_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=termination_condition_,-%7B%27max_iter%27%2C%20%27no_change%27%2C%20%27all_labeled%27%7D">
                termination_condition_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-termination_condition_;">
                termination_condition_: {&#x27;max_iter&#x27;, &#x27;no_change&#x27;, &#x27;all_labeled&#x27;}<br><br>The reason that fitting was stopped.<br><br>- `&#x27;max_iter&#x27;`: `n_iter_` reached `max_iter`.<br>- `&#x27;no_change&#x27;`: no new labels were predicted.<br>- `&#x27;all_labeled&#x27;`: all unlabeled samples were labeled before `max_iter`<br>  was reached.</span>
            </a>
        </td>
               <td class="fitted-att-type">str</td>
               <td>&#x27;no...ge&#x27;</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-transduction_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.semi_supervised.SelfTrainingClassifier.html#:~:text=transduction_,-ndarray%20of%20shape%20%28n_samples%2C%29">
                transduction_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-transduction_;">
                transduction_: ndarray of shape (n_samples,)<br><br>The labels used for the final fit of the classifier, including<br>pseudo-labels added during fit.</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[int64](150,)</td>
               <td>[0,0,0,...,2,2,2]</td>


           </tr>
    
                        </tbody>
                    </table>
                </details>
            </div>
        </div></div></div><div class="sk-parallel"><div class="sk-parallel-item"><div class="sk-item"><div class="sk-label-container"><div class="sk-label fitted sk-toggleable"><input class="sk-toggleable__control sk-hidden--visually sk-global" id="sk-estimator-id-12" type="checkbox" ><label for="sk-estimator-id-12" class="sk-toggleable__label fitted sk-toggleable__label-arrow"><div><div>estimator: LogisticRegression</div></div></label><div class="sk-toggleable__content fitted" data-param-prefix="estimator__"><pre>LogisticRegression()</pre></div></div></div><div class="sk-serial"><div class="sk-item"><div class="sk-estimator fitted sk-toggleable"><input class="sk-toggleable__control sk-hidden--visually sk-global" id="sk-estimator-id-13" type="checkbox" ><label for="sk-estimator-id-13" class="sk-toggleable__label fitted sk-toggleable__label-arrow"><div><div>LogisticRegression</div></div><div><a class="sk-estimator-doc-link fitted" rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html">?<span>Documentation for LogisticRegression</span></a></div></label><div class="sk-toggleable__content fitted" data-param-prefix="estimator__">
            <div class="estimator-table">
                <details>
                    <summary>Parameters</summary>
                    <table class="parameters-table">
                      <tbody>
                    
            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('penalty',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-penalty;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=penalty,-%7B%27l1%27%2C%20%27l2%27%2C%20%27elasticnet%27%2C%20None%7D%2C%20default%3D%27l2%27">
                penalty
                <span class="param-doc-description"
                style="position-anchor: --doc-link-penalty;">
                penalty: {&#x27;l1&#x27;, &#x27;l2&#x27;, &#x27;elasticnet&#x27;, None}, default=&#x27;l2&#x27;<br><br>Specify the norm of the penalty:<br><br>- `None`: no penalty is added;<br>- `&#x27;l2&#x27;`: add an L2 penalty term and it is the default choice;<br>- `&#x27;l1&#x27;`: add an L1 penalty term;<br>- `&#x27;elasticnet&#x27;`: both L1 and L2 penalty terms are added.<br><br>.. warning::<br>   Some penalties may not work with some solvers. See the parameter<br>   `solver` below, to know the compatibility between the penalty and<br>   solver.<br><br>.. versionadded:: 0.19<br>   l1 penalty with SAGA solver (allowing &#x27;multinomial&#x27; + L1)<br><br>.. deprecated:: 1.8<br>   `penalty` was deprecated in version 1.8 and will be removed in 1.10.<br>   Use `l1_ratio` and `C` instead. `l1_ratio=0` for `penalty=&#x27;l2&#x27;`,<br>   `l1_ratio=1` for `penalty=&#x27;l1&#x27;`, `l1_ratio` set to any float between 0 and 1<br>   for `penalty=&#x27;elasticnet&#x27;`, and `C=np.inf` for `penalty=None`.</span>
            </a>
        </td>
                <td class="value">&#x27;deprecated&#x27;</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('C',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-C;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=C,-float%2C%20default%3D1.0">
                C
                <span class="param-doc-description"
                style="position-anchor: --doc-link-C;">
                C: float, default=1.0<br><br>Inverse of regularization strength; must be a positive float.<br>Like in support vector machines, smaller values specify stronger<br>regularization. `C=np.inf` results in unpenalized logistic regression.<br>For a visual example on the effect of tuning the `C` parameter<br>with an L1 penalty, see:<br>:ref:`sphx_glr_auto_examples_linear_model_plot_logistic_path.py`.</span>
            </a>
        </td>
                <td class="value">1.0</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('l1_ratio',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-l1_ratio;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=l1_ratio,-float%2C%20default%3D0.0">
                l1_ratio
                <span class="param-doc-description"
                style="position-anchor: --doc-link-l1_ratio;">
                l1_ratio: float, default=0.0<br><br>The Elastic-Net mixing parameter, with `0 &lt;= l1_ratio &lt;= 1`. Setting<br>`l1_ratio=1` gives a pure L1-penalty, setting `l1_ratio=0` a pure L2-penalty.<br>Any value between 0 and 1 gives an Elastic-Net penalty of the form<br>`l1_ratio * L1 + (1 - l1_ratio) * L2`.<br><br>.. warning::<br>   Certain values of `l1_ratio`, i.e. some penalties, may not work with some<br>   solvers. See the parameter `solver` below, to know the compatibility between<br>   the penalty and solver.<br><br>.. versionchanged:: 1.8<br>    Default value changed from None to 0.0.<br><br>.. deprecated:: 1.8<br>    `None` is deprecated and will be removed in version 1.10. Always use<br>    `l1_ratio` to specify the penalty type.</span>
            </a>
        </td>
                <td class="value">0.0</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('dual',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-dual;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=dual,-bool%2C%20default%3DFalse">
                dual
                <span class="param-doc-description"
                style="position-anchor: --doc-link-dual;">
                dual: bool, default=False<br><br>Dual (constrained) or primal (regularized, see also<br>:ref:`this equation &lt;regularized-logistic-loss&gt;`) formulation. Dual formulation<br>is only implemented for l2 penalty with liblinear solver. Prefer `dual=False`<br>when n_samples &gt; n_features.</span>
            </a>
        </td>
                <td class="value">False</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('tol',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-tol;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=tol,-float%2C%20default%3D1e-4">
                tol
                <span class="param-doc-description"
                style="position-anchor: --doc-link-tol;">
                tol: float, default=1e-4<br><br>Tolerance for stopping criteria.</span>
            </a>
        </td>
                <td class="value">0.0001</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('fit_intercept',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-fit_intercept;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=fit_intercept,-bool%2C%20default%3DTrue">
                fit_intercept
                <span class="param-doc-description"
                style="position-anchor: --doc-link-fit_intercept;">
                fit_intercept: bool, default=True<br><br>Specifies if a constant (a.k.a. bias or intercept) should be<br>added to the decision function.</span>
            </a>
        </td>
                <td class="value">True</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('intercept_scaling',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-intercept_scaling;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=intercept_scaling,-float%2C%20default%3D1">
                intercept_scaling
                <span class="param-doc-description"
                style="position-anchor: --doc-link-intercept_scaling;">
                intercept_scaling: float, default=1<br><br>Useful only when the solver `liblinear` is used<br>and `self.fit_intercept` is set to `True`. In this case, `x` becomes<br>`[x, self.intercept_scaling]`,<br>i.e. a &quot;synthetic&quot; feature with constant value equal to<br>`intercept_scaling` is appended to the instance vector.<br>The intercept becomes<br>``intercept_scaling * synthetic_feature_weight``.<br><br>.. note::<br>    The synthetic feature weight is subject to L1 or L2<br>    regularization as all other features.<br>    To lessen the effect of regularization on synthetic feature weight<br>    (and therefore on the intercept) `intercept_scaling` has to be increased.</span>
            </a>
        </td>
                <td class="value">1</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('class_weight',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-class_weight;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=class_weight,-dict%20or%20%27balanced%27%2C%20default%3DNone">
                class_weight
                <span class="param-doc-description"
                style="position-anchor: --doc-link-class_weight;">
                class_weight: dict or &#x27;balanced&#x27;, default=None<br><br>Weights associated with classes in the form ``{class_label: weight}``.<br>If not given, all classes are supposed to have weight one.<br><br>The &quot;balanced&quot; mode uses the values of y to automatically adjust<br>weights inversely proportional to class frequencies in the input data<br>as ``n_samples / (n_classes * np.bincount(y))``.<br><br>Note that these weights will be multiplied with sample_weight (passed<br>through the fit method) if sample_weight is specified.<br><br>.. versionadded:: 0.17<br>   *class_weight=&#x27;balanced&#x27;*</span>
            </a>
        </td>
                <td class="value">None</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('random_state',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-random_state;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=random_state,-int%2C%20RandomState%20instance%2C%20default%3DNone">
                random_state
                <span class="param-doc-description"
                style="position-anchor: --doc-link-random_state;">
                random_state: int, RandomState instance, default=None<br><br>Used when ``solver`` == &#x27;sag&#x27;, &#x27;saga&#x27; or &#x27;liblinear&#x27; to shuffle the<br>data. See :term:`Glossary &lt;random_state&gt;` for details.</span>
            </a>
        </td>
                <td class="value">None</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('solver',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-solver;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=solver,-%7B%27lbfgs%27%2C%20%27liblinear%27%2C%20%27newton-cg%27%2C%20%27newton-cholesky%27%2C%20%27sag%27%2C%20%27saga%27%7D%2C%20%20%20%20%20%20%20%20%20%20%20%20%20default%3D%27lbfgs%27">
                solver
                <span class="param-doc-description"
                style="position-anchor: --doc-link-solver;">
                solver: {&#x27;lbfgs&#x27;, &#x27;liblinear&#x27;, &#x27;newton-cg&#x27;, &#x27;newton-cholesky&#x27;, &#x27;sag&#x27;, &#x27;saga&#x27;},             default=&#x27;lbfgs&#x27;<br><br>Algorithm to use in the optimization problem. Default is &#x27;lbfgs&#x27;.<br>To choose a solver, you might want to consider the following aspects:<br><br>- &#x27;lbfgs&#x27; is a good default solver because it works reasonably well for a wide<br>  class of problems.<br>- For :term:`multiclass` problems (`n_classes &gt;= 3`), all solvers except<br>  &#x27;liblinear&#x27; minimize the full multinomial loss, &#x27;liblinear&#x27; will raise an<br>  error.<br>- &#x27;newton-cholesky&#x27; is a good choice for<br>  `n_samples` &gt;&gt; `n_features * n_classes`, especially with one-hot encoded<br>  categorical features with rare categories. Be aware that the memory usage<br>  of this solver has a quadratic dependency on `n_features * n_classes`<br>  because it explicitly computes the full Hessian matrix.<br>- For small datasets, &#x27;liblinear&#x27; is a good choice, whereas &#x27;sag&#x27;<br>  and &#x27;saga&#x27; are faster for large ones;<br>- &#x27;liblinear&#x27; can only handle binary classification by default. To apply a<br>  one-versus-rest scheme for the multiclass setting one can wrap it with the<br>  :class:`~sklearn.multiclass.OneVsRestClassifier`.<br><br>.. warning::<br>   The choice of the algorithm depends on the penalty chosen (`l1_ratio=0`<br>   for L2-penalty, `l1_ratio=1` for L1-penalty and `0 &lt; l1_ratio &lt; 1` for<br>   Elastic-Net) and on (multinomial) multiclass support:<br><br>   ================= ======================== ======================<br>   solver            l1_ratio                 multinomial multiclass<br>   ================= ======================== ======================<br>   &#x27;lbfgs&#x27;           l1_ratio=0               yes<br>   &#x27;liblinear&#x27;       l1_ratio=1 or l1_ratio=0 no<br>   &#x27;newton-cg&#x27;       l1_ratio=0               yes<br>   &#x27;newton-cholesky&#x27; l1_ratio=0               yes<br>   &#x27;sag&#x27;             l1_ratio=0               yes<br>   &#x27;saga&#x27;            0&lt;=l1_ratio&lt;=1           yes<br>   ================= ======================== ======================<br><br>.. note::<br>   &#x27;sag&#x27; and &#x27;saga&#x27; fast convergence is only guaranteed on features<br>   with approximately the same scale. You can preprocess the data with<br>   a scaler from :mod:`sklearn.preprocessing`.<br><br>.. seealso::<br>   Refer to the :ref:`User Guide &lt;Logistic_regression&gt;` for more<br>   information regarding :class:`LogisticRegression` and more specifically the<br>   :ref:`Table &lt;logistic_regression_solvers&gt;`<br>   summarizing solver/penalty supports.<br><br>.. versionadded:: 0.17<br>   Stochastic Average Gradient (SAG) descent solver. Multinomial support in<br>   version 0.18.<br>.. versionadded:: 0.19<br>   SAGA solver.<br>.. versionchanged:: 0.22<br>   The default solver changed from &#x27;liblinear&#x27; to &#x27;lbfgs&#x27; in 0.22.<br>.. versionadded:: 1.2<br>   newton-cholesky solver. Multinomial support in version 1.6.</span>
            </a>
        </td>
                <td class="value">&#x27;lbfgs&#x27;</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('max_iter',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-max_iter;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=max_iter,-int%2C%20default%3D100">
                max_iter
                <span class="param-doc-description"
                style="position-anchor: --doc-link-max_iter;">
                max_iter: int, default=100<br><br>Maximum number of iterations taken for the solvers to converge.</span>
            </a>
        </td>
                <td class="value">100</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('verbose',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-verbose;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=verbose,-int%2C%20default%3D0">
                verbose
                <span class="param-doc-description"
                style="position-anchor: --doc-link-verbose;">
                verbose: int, default=0<br><br>For the liblinear and lbfgs solvers set verbose to any positive<br>number for verbosity.</span>
            </a>
        </td>
                <td class="value">0</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('warm_start',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-warm_start;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=warm_start,-bool%2C%20default%3DFalse">
                warm_start
                <span class="param-doc-description"
                style="position-anchor: --doc-link-warm_start;">
                warm_start: bool, default=False<br><br>When set to True, reuse the solution of the previous call to fit as<br>initialization, otherwise, just erase the previous solution.<br>Useless for liblinear solver. See :term:`the Glossary &lt;warm_start&gt;`.<br><br>.. versionadded:: 0.17<br>   *warm_start* to support *lbfgs*, *newton-cg*, *sag*, *saga* solvers.</span>
            </a>
        </td>
                <td class="value">False</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('n_jobs',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-n_jobs;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.linear_model.LogisticRegression.html#:~:text=n_jobs,-int%2C%20default%3DNone">
                n_jobs
                <span class="param-doc-description"
                style="position-anchor: --doc-link-n_jobs;">
                n_jobs: int, default=None<br><br>Does not have any effect.<br><br>.. deprecated:: 1.8<br>   `n_jobs` is deprecated in version 1.8 and will be removed in 1.10.</span>
            </a>
        </td>
                <td class="value">None</td>
            </tr>
    
                      </tbody>
                    </table>
                </details>
            </div>
        </div></div></div></div></div></div></div></div></div></div><script>/*  Authors: The scikit-learn developers
     SPDX-License-Identifier: BSD-3-Clause
    */

    function copyToClipboard(text, element) {
        // Get the parameter prefix from the closest toggleable content
        const toggleableContent = element.closest('.sk-toggleable__content');
        const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';
        const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;

        const originalStyle = element.style;
        const computedStyle = window.getComputedStyle(element);
        const originalWidth = computedStyle.width;
        const originalHTML = element.innerHTML.replace('Copied!', '');

        navigator.clipboard.writeText(fullParamName)
            .then(() => {
                element.style.width = originalWidth;
                element.style.color = 'green';
                element.innerHTML = "Copied!";

                setTimeout(() => {
                    element.innerHTML = originalHTML;
                    element.style = originalStyle;
                }, 2000);
            })
            .catch(err => {
                console.error('Failed to copy:', err);
                element.style.color = 'red';
                element.innerHTML = "Failed!";
                setTimeout(() => {
                    element.innerHTML = originalHTML;
                    element.style = originalStyle;
                }, 2000);
            });
        return false;
    }

    document.querySelectorAll('.copy-paste-icon').forEach(function(element) {
        const toggleableContent = element.closest('.sk-toggleable__content');
        const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';

        const parent = element.parentElement;
        if (!parent || !parent.nextElementSibling) {
            console.warn('Expected copy-paste icon is missing from the DOM structure');
            return;
        }

        const paramName = element.parentElement.nextElementSibling
            .textContent.trim().split(' ')[0];
        const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;

        element.setAttribute('title', fullParamName);
    });

    /**
     * Copy the list of feature names formatted as a Python list.
     *
     * @param {HTMLElement} element - The copy button inside a `.features` block; its siblings
     *   contain a `details` element and a table containing feature named.
     * @returns {boolean} Always returns `false` so callers can prevent the default click behavior.
     */
    function copyFeatureNamesToClipboard(element) {
        var detailsElem = element.closest('.features').querySelector('details');
        var wasOpen = detailsElem.open;
        detailsElem.open = true;
        var content = element.closest('.features').querySelector('tbody')
                      .innerText.trim();
        if (!wasOpen) detailsElem.open = false;
        const rows = content.split('\n').map(row => `    "${row}"`);
        const formattedText = `[\n${rows.join(',\n')},\n]`;
        const originalHTML = element.innerHTML.replace('✔', '');
        const originalStyle = element.style;
        const copyMark = document.createElement('span');
        copyMark.innerHTML = '✔';
        copyMark.style.color = 'blue';
        copyMark.style.fontSize = '1em';

        navigator.clipboard.writeText(formattedText)
            .then(() => {
                element.style.display = 'none';
                element.parentElement.appendChild(copyMark);

                setTimeout(() => {
                    copyMark.remove();
                    element.innerHTML = originalHTML;
                    element.style = originalStyle;
                }, 1000);
            })
            .catch(err => {
                console.error('Failed to copy:', err);
                element.style.color = 'orange';
                element.innerHTML = "Failed!";
                setTimeout(() => {
                    element.innerHTML = originalHTML;
                    element.style = originalStyle;
                }, 1000);
            });
        return false;
    }
    /**
     * Adapted from Skrub
     * https://github.com/skrub-data/skrub/blob/403466d1d5d4dc76a7ef569b3f8228db59a31dc3/skrub/_reporting/_data/templates/report.js#L789
     * @returns "light" or "dark"
     */
    function detectTheme(element) {
        const body = document.querySelector('body');

        // Check VSCode theme
        const themeKindAttr = body.getAttribute('data-vscode-theme-kind');
        const themeNameAttr = body.getAttribute('data-vscode-theme-name');

        if (themeKindAttr && themeNameAttr) {
            const themeKind = themeKindAttr.toLowerCase();
            const themeName = themeNameAttr.toLowerCase();

            if (themeKind.includes("dark") || themeName.includes("dark")) {
                return "dark";
            }
            if (themeKind.includes("light") || themeName.includes("light")) {
                return "light";
            }
        }

        // Check Jupyter theme
        if (body.getAttribute('data-jp-theme-light') === 'false') {
            return 'dark';
        } else if (body.getAttribute('data-jp-theme-light') === 'true') {
            return 'light';
        }

        // Guess based on a parent element's color
        const color = window.getComputedStyle(element.parentNode, null).getPropertyValue('color');
        const match = color.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/i);
        if (match) {
            const [r, g, b] = [
                parseFloat(match[1]),
                parseFloat(match[2]),
                parseFloat(match[3])
            ];

            // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
            const luma = 0.299 * r + 0.587 * g + 0.114 * b;

            if (luma > 180) {
                // If the text is very bright we have a dark theme
                return 'dark';
            }
            if (luma < 75) {
                // If the text is very dark we have a light theme
                return 'light';
            }
            // Otherwise fall back to the next heuristic.
        }

        // Fallback to system preference
        return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    }


    function forceTheme(elementId) {
        const estimatorElement = document.querySelector(`#${elementId}`);
        if (estimatorElement === null) {
            console.error(`Element with id ${elementId} not found.`);
        } else {
            const theme = detectTheme(estimatorElement);
            estimatorElement.classList.add(theme);
        }
    }

    forceTheme('sk-container-id-5');</script></body>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 136-144

New SequentialFeatureSelector transformer
-----------------------------------------
A new iterative transformer to select features is available:
:class:`~sklearn.feature_selection.SequentialFeatureSelector`.
Sequential Feature Selection can add features one at a time (forward
selection) or remove features from the list of the available features
(backward selection), based on a cross-validated score maximization.
See the :ref:`User Guide <sequential_feature_selection>`.

.. GENERATED FROM PYTHON SOURCE LINES 144-159

.. code-block:: Python


    from sklearn.datasets import load_iris
    from sklearn.feature_selection import SequentialFeatureSelector
    from sklearn.neighbors import KNeighborsClassifier

    X, y = load_iris(return_X_y=True, as_frame=True)
    feature_names = X.columns
    knn = KNeighborsClassifier(n_neighbors=3)
    sfs = SequentialFeatureSelector(knn, n_features_to_select=2)
    sfs.fit(X, y)
    print(
        "Features selected by forward sequential selection: "
        f"{feature_names[sfs.get_support()].tolist()}"
    )





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Features selected by forward sequential selection: ['sepal length (cm)', 'petal width (cm)']




.. GENERATED FROM PYTHON SOURCE LINES 160-166

New PolynomialCountSketch kernel approximation function
-------------------------------------------------------
The new :class:`~sklearn.kernel_approximation.PolynomialCountSketch`
approximates a polynomial expansion of a feature space when used with linear
models, but uses much less memory than
:class:`~sklearn.preprocessing.PolynomialFeatures`.

.. GENERATED FROM PYTHON SOURCE LINES 166-185

.. code-block:: Python


    from sklearn.datasets import fetch_covtype
    from sklearn.kernel_approximation import PolynomialCountSketch
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import train_test_split
    from sklearn.pipeline import make_pipeline
    from sklearn.preprocessing import MinMaxScaler

    X, y = fetch_covtype(return_X_y=True)
    pipe = make_pipeline(
        MinMaxScaler(),
        PolynomialCountSketch(degree=2, n_components=300),
        LogisticRegression(max_iter=1000),
    )
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, train_size=5000, test_size=10000, random_state=42
    )
    pipe.fit(X_train, y_train).score(X_test, y_test)



.. rst-class:: sphx-glr-script-out

.. code-block:: pytb

    Traceback (most recent call last):
      File "$BUILD_DIR/examples/release_highlights/plot_release_highlights_0_24_0.py", line 174, in <module>
        X, y = fetch_covtype(return_X_y=True)
               ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
      File "$BUILD_DIR/.pybuild/cpython3_3.14/build/sklearn/utils/_param_validation.py", line 218, in wrapper
        return func(*args, **kwargs)
      File "$BUILD_DIR/.pybuild/cpython3_3.14/build/sklearn/datasets/_covtype.py", line 200, in fetch_covtype
        archive_path = _fetch_remote(
            ARCHIVE, dirname=temp_dir, n_retries=n_retries, delay=delay
        )
      File "$BUILD_DIR/.pybuild/cpython3_3.14/build/sklearn/datasets/_base.py", line 1496, in _fetch_remote
        raise IOError('Debian Policy Section 4.9 prohibits network access during build')
    OSError: Debian Policy Section 4.9 prohibits network access during build




.. GENERATED FROM PYTHON SOURCE LINES 186-187

For comparison, here is the score of a linear baseline for the same data:

.. GENERATED FROM PYTHON SOURCE LINES 187-191

.. code-block:: Python


    linear_baseline = make_pipeline(MinMaxScaler(), LogisticRegression(max_iter=1000))
    linear_baseline.fit(X_train, y_train).score(X_test, y_test)


.. GENERATED FROM PYTHON SOURCE LINES 192-198

Individual Conditional Expectation plots
----------------------------------------
A new kind of partial dependence plot is available: the Individual
Conditional Expectation (ICE) plot. ICE plots visualize the dependence of the
prediction on a feature for each sample separately, with one line per sample.
See the :ref:`User Guide <individual_conditional>`

.. GENERATED FROM PYTHON SOURCE LINES 198-229

.. code-block:: Python


    from sklearn.datasets import fetch_california_housing
    from sklearn.ensemble import RandomForestRegressor

    # from sklearn.inspection import plot_partial_dependence
    from sklearn.inspection import PartialDependenceDisplay

    X, y = fetch_california_housing(return_X_y=True, as_frame=True)
    features = ["MedInc", "AveOccup", "HouseAge", "AveRooms"]
    est = RandomForestRegressor(n_estimators=10)
    est.fit(X, y)

    # plot_partial_dependence has been removed in version 1.2. From 1.2, use
    # PartialDependenceDisplay instead.
    # display = plot_partial_dependence(
    display = PartialDependenceDisplay.from_estimator(
        est,
        X,
        features,
        kind="individual",
        subsample=50,
        n_jobs=3,
        grid_resolution=20,
        random_state=0,
    )
    display.figure_.suptitle(
        "Partial dependence of house value on non-location features\n"
        "for the California housing dataset, with BayesianRidge"
    )
    display.figure_.subplots_adjust(hspace=0.3)


.. GENERATED FROM PYTHON SOURCE LINES 230-236

New Poisson splitting criterion for DecisionTreeRegressor
---------------------------------------------------------
The integration of Poisson regression estimation continues from version 0.23.
:class:`~sklearn.tree.DecisionTreeRegressor` now supports a new `'poisson'`
splitting criterion. Setting `criterion="poisson"` might be a good choice
if your target is a count or a frequency.

.. GENERATED FROM PYTHON SOURCE LINES 236-251

.. code-block:: Python


    import numpy as np

    from sklearn.model_selection import train_test_split
    from sklearn.tree import DecisionTreeRegressor

    n_samples, n_features = 1000, 20
    rng = np.random.RandomState(0)
    X = rng.randn(n_samples, n_features)
    # positive integer target correlated with X[:, 5] with many zeros:
    y = rng.poisson(lam=np.exp(X[:, 5]) / 2)
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=rng)
    regressor = DecisionTreeRegressor(criterion="poisson", random_state=0)
    regressor.fit(X_train, y_train)


.. GENERATED FROM PYTHON SOURCE LINES 252-268

New documentation improvements
------------------------------

New examples and documentation pages have been added, in a continuous effort
to improve the understanding of machine learning practices:

- a new section about :ref:`common pitfalls and recommended
  practices <common_pitfalls>`,
- an example illustrating how to :ref:`statistically compare the performance of
  models <sphx_glr_auto_examples_model_selection_plot_grid_search_stats.py>`
  evaluated using :class:`~sklearn.model_selection.GridSearchCV`,
- an example on how to :ref:`interpret coefficients of linear models
  <sphx_glr_auto_examples_inspection_plot_linear_model_coefficient_interpretation.py>`,
- an :ref:`example
  <sphx_glr_auto_examples_cross_decomposition_plot_pcr_vs_pls.py>`
  comparing Principal Component Regression and Partial Least Squares.


.. rst-class:: sphx-glr-timing

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


.. _sphx_glr_download_auto_examples_release_highlights_plot_release_highlights_0_24_0.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_release_highlights_0_24_0.ipynb <plot_release_highlights_0_24_0.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_release_highlights_0_24_0.py <plot_release_highlights_0_24_0.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_release_highlights_0_24_0.zip <plot_release_highlights_0_24_0.zip>`


.. include:: plot_release_highlights_0_24_0.recommendations


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
