
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "auto_examples/mixture/plot_gmm_selection.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_mixture_plot_gmm_selection.py>`
        to download the full example code.

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

.. _sphx_glr_auto_examples_mixture_plot_gmm_selection.py:


================================
Gaussian Mixture Model Selection
================================

This example shows that model selection can be performed with Gaussian Mixture
Models (GMM) using :ref:`information-theory criteria <aic_bic>`. Model selection
concerns both the covariance type and the number of components in the model.

In this case, both the Akaike Information Criterion (AIC) and the Bayes
Information Criterion (BIC) provide the right result, but we only demo the
latter as BIC is better suited to identify the true model among a set of
candidates. Unlike Bayesian procedures, such inferences are prior-free.

.. GENERATED FROM PYTHON SOURCE LINES 16-20

.. code-block:: Python


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








.. GENERATED FROM PYTHON SOURCE LINES 21-28

Data generation
---------------

We generate two components (each one containing `n_samples`) by randomly
sampling the standard normal distribution as returned by `numpy.random.randn`.
One component is kept spherical yet shifted and re-scaled. The other one is
deformed to have a more general covariance matrix.

.. GENERATED FROM PYTHON SOURCE LINES 28-39

.. code-block:: Python


    import numpy as np

    n_samples = 500
    np.random.seed(0)
    C = np.array([[0.0, -0.1], [1.7, 0.4]])
    component_1 = np.dot(np.random.randn(n_samples, 2), C)  # general
    component_2 = 0.7 * np.random.randn(n_samples, 2) + np.array([-4, 1])  # spherical

    X = np.concatenate([component_1, component_2])








.. GENERATED FROM PYTHON SOURCE LINES 40-41

We can visualize the different components:

.. GENERATED FROM PYTHON SOURCE LINES 41-50

.. code-block:: Python


    import matplotlib.pyplot as plt

    plt.scatter(component_1[:, 0], component_1[:, 1], s=0.8)
    plt.scatter(component_2[:, 0], component_2[:, 1], s=0.8)
    plt.title("Gaussian Mixture components")
    plt.axis("equal")
    plt.show()




.. image-sg:: /auto_examples/mixture/images/sphx_glr_plot_gmm_selection_001.png
   :alt: Gaussian Mixture components
   :srcset: /auto_examples/mixture/images/sphx_glr_plot_gmm_selection_001.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 51-70

Model training and selection
----------------------------

We vary the number of components from 1 to 6 and the type of covariance
parameters to use:

- `"full"`: each component has its own general covariance matrix.
- `"tied"`: all components share the same general covariance matrix.
- `"diag"`: each component has its own diagonal covariance matrix.
- `"spherical"`: each component has its own single variance.

We score the different models and keep the best model (the lowest BIC). This
is done by using :class:`~sklearn.model_selection.GridSearchCV` and a
user-defined score function which returns the negative BIC score, as
:class:`~sklearn.model_selection.GridSearchCV` is designed to **maximize** a
score (maximizing the negative BIC is equivalent to minimizing the BIC).

The best set of parameters and estimator are stored in `best_parameters_` and
`best_estimator_`, respectively.

.. GENERATED FROM PYTHON SOURCE LINES 70-90

.. code-block:: Python


    from sklearn.mixture import GaussianMixture
    from sklearn.model_selection import GridSearchCV


    def gmm_bic_score(estimator, X):
        """Callable to pass to GridSearchCV that will use the BIC score."""
        # Make it negative since GridSearchCV expects a score to maximize
        return -estimator.bic(X)


    param_grid = {
        "n_components": range(1, 7),
        "covariance_type": ["spherical", "tied", "diag", "full"],
    }
    grid_search = GridSearchCV(
        GaussianMixture(), param_grid=param_grid, scoring=gmm_bic_score
    )
    grid_search.fit(X)






.. 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-23" tabindex="0" class="sk-top-container sk-global"><div class="sk-text-repr-fallback"><pre>GridSearchCV(estimator=GaussianMixture(),
                 param_grid={&#x27;covariance_type&#x27;: [&#x27;spherical&#x27;, &#x27;tied&#x27;, &#x27;diag&#x27;,
                                                 &#x27;full&#x27;],
                             &#x27;n_components&#x27;: range(1, 7)},
                 scoring=&lt;function gmm_bic_score at 0x7f09534ec930&gt;)</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-71" type="checkbox" ><label for="sk-estimator-id-71" class="sk-toggleable__label fitted sk-toggleable__label-arrow"><div><div>GridSearchCV</div></div><div><a class="sk-estimator-doc-link fitted" rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html">?<span>Documentation for GridSearchCV</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.model_selection.GridSearchCV.html#:~:text=estimator,-estimator%20object">
                estimator
                <span class="param-doc-description"
                style="position-anchor: --doc-link-estimator;">
                estimator: estimator object<br><br>This is assumed to implement the scikit-learn estimator interface.<br>Either estimator needs to provide a ``score`` function,<br>or ``scoring`` must be passed.</span>
            </a>
        </td>
                <td class="value">GaussianMixture()</td>
            </tr>
    

            <tr class="user-set">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('param_grid',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-param_grid;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=param_grid,-dict%20or%20list%20of%20dictionaries">
                param_grid
                <span class="param-doc-description"
                style="position-anchor: --doc-link-param_grid;">
                param_grid: dict or list of dictionaries<br><br>Dictionary with parameters names (`str`) as keys and lists of<br>parameter settings to try as values, or a list of such<br>dictionaries, in which case the grids spanned by each dictionary<br>in the list are explored. This enables searching over any sequence<br>of parameter settings.</span>
            </a>
        </td>
                <td class="value">{&#x27;covariance_type&#x27;: [&#x27;spherical&#x27;, &#x27;tied&#x27;, ...], &#x27;n_components&#x27;: range(1, 7)}</td>
            </tr>
    

            <tr class="user-set">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('scoring',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-scoring;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=scoring,-str%2C%20callable%2C%20list%2C%20tuple%20or%20dict%2C%20default%3DNone">
                scoring
                <span class="param-doc-description"
                style="position-anchor: --doc-link-scoring;">
                scoring: str, callable, list, tuple or dict, default=None<br><br>Strategy to evaluate the performance of the cross-validated model on<br>the test set.<br><br>If `scoring` represents a single score, one can use:<br><br>- a single string (see :ref:`scoring_string_names`);<br>- a callable (see :ref:`scoring_callable`) that returns a single value;<br>- `None`, the `estimator`&#x27;s<br>  :ref:`default evaluation criterion &lt;scoring_api_overview&gt;` is used.<br><br>If `scoring` represents multiple scores, one can use:<br><br>- a list or tuple of unique strings;<br>- a callable returning a dictionary where the keys are the metric<br>  names and the values are the metric scores;<br>- a dictionary with metric names as keys and callables as values.<br><br>See :ref:`multimetric_grid_search` for an example.</span>
            </a>
        </td>
                <td class="value">&lt;function gmm...x7f09534ec930&gt;</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.model_selection.GridSearchCV.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>Number of jobs to run in parallel.<br>``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.<br>``-1`` means using all processors. See :term:`Glossary &lt;n_jobs&gt;`<br>for more details.<br><br>.. versionchanged:: v0.20<br>   `n_jobs` default changed from 1 to None</span>
            </a>
        </td>
                <td class="value">None</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('refit',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-refit;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=refit,-bool%2C%20str%2C%20or%20callable%2C%20default%3DTrue">
                refit
                <span class="param-doc-description"
                style="position-anchor: --doc-link-refit;">
                refit: bool, str, or callable, default=True<br><br>Refit an estimator using the best found parameters on the whole<br>dataset.<br><br>For multiple metric evaluation, this needs to be a `str` denoting the<br>scorer that would be used to find the best parameters for refitting<br>the estimator at the end.<br><br>Where there are considerations other than maximum score in<br>choosing a best estimator, ``refit`` can be set to a function which<br>returns the selected ``best_index_`` given ``cv_results_``. In that<br>case, the ``best_estimator_`` and ``best_params_`` will be set<br>according to the returned ``best_index_`` while the ``best_score_``<br>attribute will not be available.<br><br>The refitted estimator is made available at the ``best_estimator_``<br>attribute and permits using ``predict`` directly on this<br>``GridSearchCV`` instance.<br><br>Also for multiple metric evaluation, the attributes ``best_index_``,<br>``best_score_`` and ``best_params_`` will only be available if<br>``refit`` is set and all of them will be determined w.r.t this specific<br>scorer.<br><br>See ``scoring`` parameter to know more about multiple metric<br>evaluation.<br><br>See :ref:`sphx_glr_auto_examples_model_selection_plot_grid_search_digits.py`<br>to see how to design a custom selection strategy using a callable<br>via `refit`.<br><br>See :ref:`this example<br>&lt;sphx_glr_auto_examples_model_selection_plot_grid_search_refit_callable.py&gt;`<br>for an example of how to use ``refit=callable`` to balance model<br>complexity and cross-validated score.<br><br>.. versionchanged:: 0.20<br>    Support for callable added.</span>
            </a>
        </td>
                <td class="value">True</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('cv',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-cv;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=cv,-int%2C%20cross-validation%20generator%20or%20an%20iterable%2C%20default%3DNone">
                cv
                <span class="param-doc-description"
                style="position-anchor: --doc-link-cv;">
                cv: int, cross-validation generator or an iterable, default=None<br><br>Determines the cross-validation splitting strategy.<br>Possible inputs for cv are:<br><br>- None, to use the default 5-fold cross validation,<br>- integer, to specify the number of folds in a `(Stratified)KFold`,<br>- :term:`CV splitter`,<br>- an iterable yielding (train, test) splits as arrays of indices.<br><br>For integer/None inputs, if the estimator is a classifier and ``y`` is<br>either binary or multiclass, :class:`StratifiedKFold` is used. In all<br>other cases, :class:`KFold` is used. These splitters are instantiated<br>with `shuffle=False` so the splits will be the same across calls.<br><br>Refer :ref:`User Guide &lt;cross_validation&gt;` for the various<br>cross-validation strategies that can be used here.<br><br>.. versionchanged:: 0.22<br>    ``cv`` default value if None changed from 3-fold to 5-fold.</span>
            </a>
        </td>
                <td class="value">None</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.model_selection.GridSearchCV.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>Controls the verbosity of information printed during fitting, with higher<br>values yielding more detailed logging.<br><br>- 0 : no messages are printed;<br>- &gt;=1 : summary of the total number of fits;<br>- &gt;=2 : computation time for each fold and parameter candidate;<br>- &gt;=3 : fold indices and scores;<br>- &gt;=10 : parameter candidate indices and START messages before each fit.</span>
            </a>
        </td>
                <td class="value">0</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('pre_dispatch',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-pre_dispatch;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=pre_dispatch,-int%2C%20or%20str%2C%20default%3D%272%2An_jobs%27">
                pre_dispatch
                <span class="param-doc-description"
                style="position-anchor: --doc-link-pre_dispatch;">
                pre_dispatch: int, or str, default=&#x27;2*n_jobs&#x27;<br><br>Controls the number of jobs that get dispatched during parallel<br>execution. Reducing this number can be useful to avoid an<br>explosion of memory consumption when more jobs get dispatched<br>than CPUs can process. This parameter can be:<br><br>- None, in which case all the jobs are immediately created and spawned. Use<br>  this for lightweight and fast-running jobs, to avoid delays due to on-demand<br>  spawning of the jobs<br>- An int, giving the exact number of total jobs that are spawned<br>- A str, giving an expression as a function of n_jobs, as in &#x27;2*n_jobs&#x27;</span>
            </a>
        </td>
                <td class="value">&#x27;2*n_jobs&#x27;</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('error_score',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-error_score;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=error_score,-%27raise%27%20or%20numeric%2C%20default%3Dnp.nan">
                error_score
                <span class="param-doc-description"
                style="position-anchor: --doc-link-error_score;">
                error_score: &#x27;raise&#x27; or numeric, default=np.nan<br><br>Value to assign to the score if an error occurs in estimator fitting.<br>If set to &#x27;raise&#x27;, the error is raised. If a numeric value is given,<br>FitFailedWarning is raised. This parameter does not affect the refit<br>step, which will always raise the error.</span>
            </a>
        </td>
                <td class="value">nan</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('return_train_score',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-return_train_score;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=return_train_score,-bool%2C%20default%3DFalse">
                return_train_score
                <span class="param-doc-description"
                style="position-anchor: --doc-link-return_train_score;">
                return_train_score: bool, default=False<br><br>If ``False``, the ``cv_results_`` attribute will not include training<br>scores.<br>Computing training scores is used to get insights on how different<br>parameter settings impact the overfitting/underfitting trade-off.<br>However computing the scores on the training set can be computationally<br>expensive and is not strictly required to select the parameters that<br>yield the best generalization performance.<br><br>.. versionadded:: 0.19<br><br>.. versionchanged:: 0.21<br>    Default value was changed from ``True`` to ``False``</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-best_estimator_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=best_estimator_,-estimator">
                best_estimator_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-best_estimator_;">
                best_estimator_: estimator<br><br>Estimator that was chosen by the search, i.e. estimator<br>which gave highest score (or smallest loss if specified)<br>on the left out data. Not available if ``refit=False``.<br><br>See ``refit`` parameter for more information on allowed values.</span>
            </a>
        </td>
               <td class="fitted-att-type">GaussianMixture</td>
               <td>GaussianMixtu..._components=2)</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-best_index_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=best_index_,-int">
                best_index_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-best_index_;">
                best_index_: int<br><br>The index (of the ``cv_results_`` arrays) which corresponds to the best<br>candidate parameter setting.<br><br>The dict at ``search.cv_results_[&#x27;params&#x27;][search.best_index_]`` gives<br>the parameter setting for the best model, that gives the highest<br>mean score (``search.best_score_``).<br><br>For multi-metric evaluation, this is present only if ``refit`` is<br>specified.</span>
            </a>
        </td>
               <td class="fitted-att-type">int64</td>
               <td>np.int64(19)</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-best_params_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=best_params_,-dict">
                best_params_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-best_params_;">
                best_params_: dict<br><br>Parameter setting that gave the best results on the hold out data.<br><br>For multi-metric evaluation, this is present only if ``refit`` is<br>specified.</span>
            </a>
        </td>
               <td class="fitted-att-type">dict</td>
               <td>{&#x27;co...pe&#x27;: &#x27;full&#x27;, &#x27;n_...ts&#x27;: 2}</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-best_score_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=best_score_,-float">
                best_score_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-best_score_;">
                best_score_: float<br><br>Mean cross-validated score of the best_estimator<br><br>For multi-metric evaluation, this is present only if ``refit`` is<br>specified.<br><br>This attribute is not available if ``refit`` is a function.</span>
            </a>
        </td>
               <td class="fitted-att-type">float64</td>
               <td>-1047</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-cv_results_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=cv_results_,-dict%20of%20numpy%20%28masked%29%20ndarrays">
                cv_results_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-cv_results_;">
                cv_results_: dict of numpy (masked) ndarrays<br><br>A dict with keys as column headers and values as columns, that can be<br>imported into a pandas ``DataFrame``.<br><br>For instance the below given table<br><br>+------------+-----------+------------+-----------------+---+---------+<br>|param_kernel|param_gamma|param_degree|split0_test_score|...|rank_t...|<br>+============+===========+============+=================+===+=========+<br>|  &#x27;poly&#x27;    |     --    |      2     |       0.80      |...|    2    |<br>+------------+-----------+------------+-----------------+---+---------+<br>|  &#x27;poly&#x27;    |     --    |      3     |       0.70      |...|    4    |<br>+------------+-----------+------------+-----------------+---+---------+<br>|  &#x27;rbf&#x27;     |     0.1   |     --     |       0.80      |...|    3    |<br>+------------+-----------+------------+-----------------+---+---------+<br>|  &#x27;rbf&#x27;     |     0.2   |     --     |       0.93      |...|    1    |<br>+------------+-----------+------------+-----------------+---+---------+<br><br>will be represented by a ``cv_results_`` dict of::<br><br>    {<br>    &#x27;param_kernel&#x27;: masked_array(data = [&#x27;poly&#x27;, &#x27;poly&#x27;, &#x27;rbf&#x27;, &#x27;rbf&#x27;],<br>                                 mask = [False False False False]...)<br>    &#x27;param_gamma&#x27;: masked_array(data = [-- -- 0.1 0.2],<br>                                mask = [ True  True False False]...),<br>    &#x27;param_degree&#x27;: masked_array(data = [2.0 3.0 -- --],<br>                                 mask = [False False  True  True]...),<br>    &#x27;split0_test_score&#x27;  : [0.80, 0.70, 0.80, 0.93],<br>    &#x27;split1_test_score&#x27;  : [0.82, 0.50, 0.70, 0.78],<br>    &#x27;mean_test_score&#x27;    : [0.81, 0.60, 0.75, 0.85],<br>    &#x27;std_test_score&#x27;     : [0.01, 0.10, 0.05, 0.08],<br>    &#x27;rank_test_score&#x27;    : [2, 4, 3, 1],<br>    &#x27;split0_train_score&#x27; : [0.80, 0.92, 0.70, 0.93],<br>    &#x27;split1_train_score&#x27; : [0.82, 0.55, 0.70, 0.87],<br>    &#x27;mean_train_score&#x27;   : [0.81, 0.74, 0.70, 0.90],<br>    &#x27;std_train_score&#x27;    : [0.01, 0.19, 0.00, 0.03],<br>    &#x27;mean_fit_time&#x27;      : [0.73, 0.63, 0.43, 0.49],<br>    &#x27;std_fit_time&#x27;       : [0.01, 0.02, 0.01, 0.01],<br>    &#x27;mean_score_time&#x27;    : [0.01, 0.06, 0.04, 0.04],<br>    &#x27;std_score_time&#x27;     : [0.00, 0.00, 0.00, 0.01],<br>    &#x27;params&#x27;             : [{&#x27;kernel&#x27;: &#x27;poly&#x27;, &#x27;degree&#x27;: 2}, ...],<br>    }<br><br>For an example of visualization and interpretation of GridSearch results,<br>see :ref:`sphx_glr_auto_examples_model_selection_plot_grid_search_stats.py`.<br><br>NOTE<br><br>The key ``&#x27;params&#x27;`` is used to store a list of parameter<br>settings dicts for all the parameter candidates.<br><br>The ``mean_fit_time``, ``std_fit_time``, ``mean_score_time`` and<br>``std_score_time`` are all in seconds.<br><br>For multi-metric evaluation, the scores for all the scorers are<br>available in the ``cv_results_`` dict at the keys ending with that<br>scorer&#x27;s name (``&#x27;_&lt;scorer_name&gt;&#x27;``) instead of ``&#x27;_score&#x27;`` shown<br>above. (&#x27;split0_test_precision&#x27;, &#x27;mean_train_precision&#x27; etc.)</span>
            </a>
        </td>
               <td class="fitted-att-type">dict</td>
               <td>{&#x27;me...me&#x27;: array([0.0018..., 0.01637645]), &#x27;me...me&#x27;: array([0.0002..., 0.00038905]), &#x27;me...re&#x27;: array([-1728....179.97789043]), &#x27;pa...pe&#x27;: masked_array(... dtype=object), ...}</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-multimetric_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=multimetric_,-bool">
                multimetric_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-multimetric_;">
                multimetric_: bool<br><br>Whether or not the scorers compute several metrics.</span>
            </a>
        </td>
               <td class="fitted-att-type">bool</td>
               <td>False</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.model_selection.GridSearchCV.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`. Only defined if<br>`best_estimator_` is defined (see the documentation for the `refit`<br>parameter for more details) and that `best_estimator_` exposes<br>`n_features_in_` when fit.<br><br>.. versionadded:: 0.24</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-n_splits_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=n_splits_,-int">
                n_splits_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-n_splits_;">
                n_splits_: int<br><br>The number of cross-validation splits (folds/iterations).</span>
            </a>
        </td>
               <td class="fitted-att-type">int</td>
               <td>5</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-refit_time_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=refit_time_,-float">
                refit_time_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-refit_time_;">
                refit_time_: float<br><br>Seconds used for refitting the best model on the whole dataset.<br><br>This is present only if ``refit`` is not False.<br><br>.. versionadded:: 0.20</span>
            </a>
        </td>
               <td class="fitted-att-type">float</td>
               <td>0.004874</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-scorer_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.model_selection.GridSearchCV.html#:~:text=scorer_,-function%20or%20a%20dict">
                scorer_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-scorer_;">
                scorer_: function or a dict<br><br>Scorer function used on the held out data to choose the best<br>parameters for the model.<br><br>For multi-metric evaluation, this attribute holds the validated<br>``scoring`` dict which maps the scorer key to the scorer callable.</span>
            </a>
        </td>
               <td class="fitted-att-type">function</td>
               <td>&lt;function gmm...x7f09534ec930&gt;</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-72" type="checkbox" ><label for="sk-estimator-id-72" class="sk-toggleable__label fitted sk-toggleable__label-arrow"><div><div>best_estimator_: GaussianMixture</div></div></label><div class="sk-toggleable__content fitted" data-param-prefix="best_estimator___"><pre>GaussianMixture(n_components=2)</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-73" type="checkbox" ><label for="sk-estimator-id-73" class="sk-toggleable__label fitted sk-toggleable__label-arrow"><div><div>GaussianMixture</div></div><div><a class="sk-estimator-doc-link fitted" rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html">?<span>Documentation for GaussianMixture</span></a></div></label><div class="sk-toggleable__content fitted" data-param-prefix="best_estimator___">
            <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('n_components',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-n_components;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=n_components,-int%2C%20default%3D1">
                n_components
                <span class="param-doc-description"
                style="position-anchor: --doc-link-n_components;">
                n_components: int, default=1<br><br>The number of mixture components.</span>
            </a>
        </td>
                <td class="value">2</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('covariance_type',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-covariance_type;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=covariance_type,-%7B%27full%27%2C%20%27tied%27%2C%20%27diag%27%2C%20%27spherical%27%7D%2C%20default%3D%27full%27">
                covariance_type
                <span class="param-doc-description"
                style="position-anchor: --doc-link-covariance_type;">
                covariance_type: {&#x27;full&#x27;, &#x27;tied&#x27;, &#x27;diag&#x27;, &#x27;spherical&#x27;}, default=&#x27;full&#x27;<br><br>String describing the type of covariance parameters to use.<br>Must be one of:<br><br>- &#x27;full&#x27;: each component has its own general covariance matrix.<br>- &#x27;tied&#x27;: all components share the same general covariance matrix.<br>- &#x27;diag&#x27;: each component has its own diagonal covariance matrix.<br>- &#x27;spherical&#x27;: each component has its own single variance.<br><br>For an example of using `covariance_type`, refer to<br>:ref:`sphx_glr_auto_examples_mixture_plot_gmm_selection.py`.</span>
            </a>
        </td>
                <td class="value">&#x27;full&#x27;</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.mixture.GaussianMixture.html#:~:text=tol,-float%2C%20default%3D1e-3">
                tol
                <span class="param-doc-description"
                style="position-anchor: --doc-link-tol;">
                tol: float, default=1e-3<br><br>The convergence threshold. EM iterations will stop when the<br>lower bound average gain is below this threshold.</span>
            </a>
        </td>
                <td class="value">0.001</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('reg_covar',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-reg_covar;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=reg_covar,-float%2C%20default%3D1e-6">
                reg_covar
                <span class="param-doc-description"
                style="position-anchor: --doc-link-reg_covar;">
                reg_covar: float, default=1e-6<br><br>Non-negative regularization added to the diagonal of covariance.<br>Allows to assure that the covariance matrices are all positive.</span>
            </a>
        </td>
                <td class="value">1e-06</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.mixture.GaussianMixture.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>The number of EM iterations to perform.</span>
            </a>
        </td>
                <td class="value">100</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('n_init',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-n_init;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=n_init,-int%2C%20default%3D1">
                n_init
                <span class="param-doc-description"
                style="position-anchor: --doc-link-n_init;">
                n_init: int, default=1<br><br>The number of initializations to perform. The best results are kept.</span>
            </a>
        </td>
                <td class="value">1</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('init_params',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-init_params;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=init_params,-%7B%27kmeans%27%2C%20%27k-means%2B%2B%27%2C%20%27random%27%2C%20%27random_from_data%27%7D%2C%20%20%20%20%20default%3D%27kmeans%27">
                init_params
                <span class="param-doc-description"
                style="position-anchor: --doc-link-init_params;">
                init_params: {&#x27;kmeans&#x27;, &#x27;k-means++&#x27;, &#x27;random&#x27;, &#x27;random_from_data&#x27;},     default=&#x27;kmeans&#x27;<br><br>The method used to initialize the weights, the means and the<br>precisions.<br>String must be one of:<br><br>- &#x27;kmeans&#x27; : responsibilities are initialized using kmeans.<br>- &#x27;k-means++&#x27; : use the k-means++ method to initialize.<br>- &#x27;random&#x27; : responsibilities are initialized randomly.<br>- &#x27;random_from_data&#x27; : initial means are randomly selected data points.<br><br>.. versionchanged:: v1.1<br>    `init_params` now accepts &#x27;random_from_data&#x27; and &#x27;k-means++&#x27; as<br>    initialization methods.</span>
            </a>
        </td>
                <td class="value">&#x27;kmeans&#x27;</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('weights_init',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-weights_init;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=weights_init,-array-like%20of%20shape%20%28n_components%2C%20%29%2C%20default%3DNone">
                weights_init
                <span class="param-doc-description"
                style="position-anchor: --doc-link-weights_init;">
                weights_init: array-like of shape (n_components, ), default=None<br><br>The user-provided initial weights.<br>If it is None, weights are initialized using the `init_params` method.</span>
            </a>
        </td>
                <td class="value">None</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('means_init',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-means_init;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=means_init,-array-like%20of%20shape%20%28n_components%2C%20n_features%29%2C%20default%3DNone">
                means_init
                <span class="param-doc-description"
                style="position-anchor: --doc-link-means_init;">
                means_init: array-like of shape (n_components, n_features), default=None<br><br>The user-provided initial means,<br>If it is None, means are initialized using the `init_params` method.</span>
            </a>
        </td>
                <td class="value">None</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('precisions_init',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-precisions_init;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=precisions_init,-array-like%2C%20default%3DNone">
                precisions_init
                <span class="param-doc-description"
                style="position-anchor: --doc-link-precisions_init;">
                precisions_init: array-like, default=None<br><br>The user-provided initial precisions (inverse of the covariance<br>matrices).<br>If it is None, precisions are initialized using the &#x27;init_params&#x27;<br>method.<br>The shape depends on &#x27;covariance_type&#x27;::<br><br>    (n_components,)                        if &#x27;spherical&#x27;,<br>    (n_features, n_features)               if &#x27;tied&#x27;,<br>    (n_components, n_features)             if &#x27;diag&#x27;,<br>    (n_components, n_features, n_features) if &#x27;full&#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.mixture.GaussianMixture.html#:~:text=random_state,-int%2C%20RandomState%20instance%20or%20None%2C%20default%3DNone">
                random_state
                <span class="param-doc-description"
                style="position-anchor: --doc-link-random_state;">
                random_state: int, RandomState instance or None, default=None<br><br>Controls the random seed given to the method chosen to initialize the<br>parameters (see `init_params`).<br>In addition, it controls the generation of random samples from the<br>fitted distribution (see the method `sample`).<br>Pass an int for reproducible output across multiple function calls.<br>See :term:`Glossary &lt;random_state&gt;`.</span>
            </a>
        </td>
                <td class="value">None</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.mixture.GaussianMixture.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>If &#x27;warm_start&#x27; is True, the solution of the last fitting is used as<br>initialization for the next call of fit(). This can speed up<br>convergence when fit is called several times on similar problems.<br>In that case, &#x27;n_init&#x27; is ignored and only a single initialization<br>occurs upon the first call.<br>See :term:`the Glossary &lt;warm_start&gt;`.</span>
            </a>
        </td>
                <td class="value">False</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.mixture.GaussianMixture.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>Enable verbose output. If 1 then it prints the current<br>initialization and each iteration step. If greater than 1 then<br>it prints also the log probability and the time needed<br>for each step.</span>
            </a>
        </td>
                <td class="value">0</td>
            </tr>
    

            <tr class="default">
                <td><i class="copy-paste-icon"
                     onclick="copyToClipboard('verbose_interval',
                              this.parentElement.nextElementSibling)"
                ></i></td>
                <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-verbose_interval;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=verbose_interval,-int%2C%20default%3D10">
                verbose_interval
                <span class="param-doc-description"
                style="position-anchor: --doc-link-verbose_interval;">
                verbose_interval: int, default=10<br><br>Number of iteration done before the next print.</span>
            </a>
        </td>
                <td class="value">10</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-converged_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=converged_,-bool">
                converged_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-converged_;">
                converged_: bool<br><br>True when convergence of the best fit of EM was reached, False otherwise.</span>
            </a>
        </td>
               <td class="fitted-att-type">bool</td>
               <td>True</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-covariances_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=covariances_,-array-like">
                covariances_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-covariances_;">
                covariances_: array-like<br><br>The covariance of each mixture component.<br>The shape depends on `covariance_type`::<br><br>    (n_components,)                        if &#x27;spherical&#x27;,<br>    (n_features, n_features)               if &#x27;tied&#x27;,<br>    (n_components, n_features)             if &#x27;diag&#x27;,<br>    (n_components, n_features, n_features) if &#x27;full&#x27;<br><br>For an example of using covariances, refer to<br>:ref:`sphx_glr_auto_examples_mixture_plot_gmm_covariances.py`.</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[float64](2, 2, 2)</td>
               <td>[[[ 2.89, 0.68],
      [ 0.68, 0.17]],

     [[ 0.47,-0.01],
      [-0.01, 0.46]]]</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-lower_bound_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=lower_bound_,-float">
                lower_bound_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-lower_bound_;">
                lower_bound_: float<br><br>Lower bound value on the log-likelihood (of the training data with<br>respect to the model) of the best fit of EM.</span>
            </a>
        </td>
               <td class="fitted-att-type">float64</td>
               <td>-2.233</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-lower_bounds_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=lower_bounds_,-array-like%20of%20shape%20%28n_iter_%2C%29">
                lower_bounds_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-lower_bounds_;">
                lower_bounds_: array-like of shape (`n_iter_`,)<br><br>The list of lower bound values on the log-likelihood from each<br>iteration of the best fit of EM.</span>
            </a>
        </td>
               <td class="fitted-att-type">list</td>
               <td>[np.float64(-2...0495624935283), np.float64(-2.258444849277139), np.float64(-2.237564594477556), np.float64(-2...8322149565912), ...]</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-means_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=means_,-array-like%20of%20shape%20%28n_components%2C%20n_features%29">
                means_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-means_;">
                means_: array-like of shape (n_components, n_features)<br><br>The mean of each mixture component.</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[float64](2, 2)</td>
               <td>[[-0.04,-0.  ],
     [-3.99, 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.mixture.GaussianMixture.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>2</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.mixture.GaussianMixture.html#:~:text=n_iter_,-int">
                n_iter_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-n_iter_;">
                n_iter_: int<br><br>Number of step used by the best fit of EM to reach the convergence.</span>
            </a>
        </td>
               <td class="fitted-att-type">int</td>
               <td>5</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-precisions_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=precisions_,-array-like">
                precisions_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-precisions_;">
                precisions_: array-like<br><br>The precision matrices for each component in the mixture. A precision<br>matrix is the inverse of a covariance matrix. A covariance matrix is<br>symmetric positive definite so the mixture of Gaussian can be<br>equivalently parameterized by the precision matrices. Storing the<br>precision matrices instead of the covariance matrices makes it more<br>efficient to compute the log-likelihood of new samples at test time.<br>The shape depends on `covariance_type`::<br><br>    (n_components,)                        if &#x27;spherical&#x27;,<br>    (n_features, n_features)               if &#x27;tied&#x27;,<br>    (n_components, n_features)             if &#x27;diag&#x27;,<br>    (n_components, n_features, n_features) if &#x27;full&#x27;</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[float64](2, 2, 2)</td>
               <td>[[[  6.18,-24.84],
      [-24.84,105.76]],

     [[  2.15,  0.04],
      [  0.04,  2.19]]]</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-precisions_cholesky_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=precisions_cholesky_,-array-like">
                precisions_cholesky_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-precisions_cholesky_;">
                precisions_cholesky_: array-like<br><br>The Cholesky decomposition of the precision matrices of each mixture<br>component. A precision matrix is the inverse of a covariance matrix.<br>A covariance matrix is symmetric positive definite so the mixture of<br>Gaussian can be equivalently parameterized by the precision matrices.<br>Storing the precision matrices instead of the covariance matrices makes<br>it more efficient to compute the log-likelihood of new samples at test<br>time. The shape depends on `covariance_type`::<br><br>    (n_components,)                        if &#x27;spherical&#x27;,<br>    (n_features, n_features)               if &#x27;tied&#x27;,<br>    (n_components, n_features)             if &#x27;diag&#x27;,<br>    (n_components, n_features, n_features) if &#x27;full&#x27;</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[float64](2, 2, 2)</td>
               <td>[[[ 0.59,-2.42],
      [ 0.  ,10.28]],

     [[ 1.46, 0.02],
      [ 0.  , 1.48]]]</td>


           </tr>
    

           <tr class="default">
               <td class="param">
            <a class="param-doc-link"
                style="anchor-name: --doc-link-weights_;"
                rel="noreferrer" target="_blank" href="https://scikit-learn.org/1.9/modules/generated/sklearn.mixture.GaussianMixture.html#:~:text=weights_,-array-like%20of%20shape%20%28n_components%2C%29">
                weights_
                <span class="param-doc-description"
                style="position-anchor: --doc-link-weights_;">
                weights_: array-like of shape (n_components,)<br><br>The weights of each mixture components.</span>
            </a>
        </td>
               <td class="fitted-att-type">ndarray[float64](2,)</td>
               <td>[0.5,0.5]</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-23');</script></body>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 91-97

Plot the BIC scores
-------------------

To ease the plotting we can create a `pandas.DataFrame` from the results of
the cross-validation done by the grid search. We re-inverse the sign of the
BIC score to show the effect of minimizing it.

.. GENERATED FROM PYTHON SOURCE LINES 97-113

.. code-block:: Python


    import pandas as pd

    df = pd.DataFrame(grid_search.cv_results_)[
        ["param_n_components", "param_covariance_type", "mean_test_score"]
    ]
    df["mean_test_score"] = -df["mean_test_score"]
    df = df.rename(
        columns={
            "param_n_components": "Number of components",
            "param_covariance_type": "Type of covariance",
            "mean_test_score": "BIC score",
        }
    )
    df.sort_values(by="BIC score").head()






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th>Number of components</th>
          <th>Type of covariance</th>
          <th>BIC score</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>19</th>
          <td>2</td>
          <td>full</td>
          <td>1046.829429</td>
        </tr>
        <tr>
          <th>20</th>
          <td>3</td>
          <td>full</td>
          <td>1084.038689</td>
        </tr>
        <tr>
          <th>21</th>
          <td>4</td>
          <td>full</td>
          <td>1114.517272</td>
        </tr>
        <tr>
          <th>22</th>
          <td>5</td>
          <td>full</td>
          <td>1148.512281</td>
        </tr>
        <tr>
          <th>23</th>
          <td>6</td>
          <td>full</td>
          <td>1179.977890</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 114-125

.. code-block:: Python

    import seaborn as sns

    sns.catplot(
        data=df,
        kind="bar",
        x="Number of components",
        y="BIC score",
        hue="Type of covariance",
    )
    plt.show()




.. image-sg:: /auto_examples/mixture/images/sphx_glr_plot_gmm_selection_002.png
   :alt: plot gmm selection
   :srcset: /auto_examples/mixture/images/sphx_glr_plot_gmm_selection_002.png
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 126-142

In the present case, the model with 2 components and full covariance (which
corresponds to the true generative model) has the lowest BIC score and is
therefore selected by the grid search.

Plot the best model
-------------------

We plot an ellipse to show each Gaussian component of the selected model. For
such purpose, one needs to find the eigenvalues of the covariance matrices as
returned by the `covariances_` attribute. The shape of such matrices depends
on the `covariance_type`:

- `"full"`: (`n_components`, `n_features`, `n_features`)
- `"tied"`: (`n_features`, `n_features`)
- `"diag"`: (`n_components`, `n_features`)
- `"spherical"`: (`n_components`,)

.. GENERATED FROM PYTHON SOURCE LINES 142-177

.. code-block:: Python


    from matplotlib.patches import Ellipse
    from scipy import linalg

    color_iter = sns.color_palette("tab10", 2)[::-1]
    Y_ = grid_search.predict(X)

    fig, ax = plt.subplots()

    for i, (mean, cov, color) in enumerate(
        zip(
            grid_search.best_estimator_.means_,
            grid_search.best_estimator_.covariances_,
            color_iter,
        )
    ):
        v, w = linalg.eigh(cov)
        if not np.any(Y_ == i):
            continue
        plt.scatter(X[Y_ == i, 0], X[Y_ == i, 1], 0.8, color=color)

        angle = np.arctan2(w[0][1], w[0][0])
        angle = 180.0 * angle / np.pi  # convert to degrees
        v = 2.0 * np.sqrt(2.0) * np.sqrt(v)
        ellipse = Ellipse(mean, v[0], v[1], angle=180.0 + angle, color=color)
        ellipse.set_clip_box(fig.bbox)
        ellipse.set_alpha(0.5)
        ax.add_artist(ellipse)

    plt.title(
        f"Selected GMM: {grid_search.best_params_['covariance_type']} model, "
        f"{grid_search.best_params_['n_components']} components"
    )
    plt.axis("equal")
    plt.show()



.. image-sg:: /auto_examples/mixture/images/sphx_glr_plot_gmm_selection_003.png
   :alt: Selected GMM: full model, 2 components
   :srcset: /auto_examples/mixture/images/sphx_glr_plot_gmm_selection_003.png
   :class: sphx-glr-single-img






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

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


.. _sphx_glr_download_auto_examples_mixture_plot_gmm_selection.py:

.. only:: html

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

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

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

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

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

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

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


.. include:: plot_gmm_selection.recommendations


.. only:: html

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

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