Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.
Выбор модели гауссовой смеси
В этом примере показано, что выбор модели можно выполнять с помощью моделей гауссовых смесей (GMM), используя критерии теории информации. Выбор модели касается как типа ковариации, так и количества компонентов в модели.
В данном случае и информационный критерий Акаике (AIC), и байесовский информационный критерий (BIC) дают правильный результат, но мы демонстрируем только последний, поскольку BIC лучше подходит для определения истинной модели среди набора кандидатов. В отличие от байесовских процедур, такие выводы не зависят от априорных предположений.
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Генерация данных
Мы генерируем два компонента (каждый из которых содержит n_samples), случайным образом выбирая значения из стандартного нормального распределения, возвращаемого numpy.random.randn. Один компонент сохраняет сферическую форму, но сдвигается и масштабируется. Другой деформируется, чтобы получить более общую ковариационную матрицу.
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])
Мы можем визуализировать различные компоненты:
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()

Обучение и выбор модели
Мы изменяем количество компонентов от 1 до 6 и тип используемых параметров ковариации:
-
"full": каждый компонент имеет собственную общую ковариационную матрицу. -
"tied": все компоненты используют одну и ту же общую ковариационную матрицу. -
"diag": каждый компонент имеет собственную диагональную ковариационную матрицу. -
"spherical": каждый компонент имеет собственную единственную дисперсию.
Мы оцениваем различные модели и оставляем лучшую (с наименьшим BIC). Для этого используются GridSearchCV и пользовательская функция оценки, возвращающая отрицательное значение BIC, поскольку GridSearchCV предназначен для максимизации оценки (максимизация отрицательного BIC эквивалентна минимизации BIC).
Лучший набор параметров и оцениватель сохраняются соответственно в best_parameters_ и best_estimator_.
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)
Построение графика оценок BIC
Чтобы упростить построение графика, можно создать pandas.DataFrame на основе результатов перекрёстной проверки, выполненной поиском по сетке. Мы меняем знак оценки BIC на противоположный, чтобы показать эффект её минимизации.
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()
import seaborn as sns
sns.catplot(
data=df,
kind="bar",
x="Number of components",
y="BIC score",
hue="Type of covariance",
)
plt.show()

В данном случае модель с 2 компонентами и полной ковариацией (соответствующая истинной генеративной модели) имеет наименьшую оценку BIC, поэтому поиск по сетке выбирает именно её.
Построение графика лучшей модели
Для отображения каждого гауссовского компонента выбранной модели построим эллипс. Для этого необходимо найти собственные значения матриц ковариации, возвращаемых атрибутом covariances_. Форма этих матриц зависит от covariance_type:
-
"full": (n_components,n_features,n_features) -
"tied": (n_features,n_features) -
"diag": (n_components,n_features) -
"spherical": (n_components,)
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()

Общее время выполнения скрипта: (0 минут 1.569 секунды)
Связанные примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/mixture/plot_gmm_selection.html