Примечание
Перейти в конец, чтобы скачать полный код примера или запустить его в браузере через JupyterLite или Binder.
Кривая синуса и модель смеси Гаусса
В этом примере демонстрируется поведение моделей смеси Гаусса, обученных на данных, которые не были получены из смеси гауссовских случайных величин. Набор данных состоит из 100 точек, приблизительно равномерно расположенных вдоль зашумленной кривой синуса. Поэтому истинное значение числа гауссовских компонент неизвестно.
Первая модель — классическая модель смеси Гаусса с 10 компонентами, обученная с помощью алгоритма максимизации ожидания.
Вторая модель — байесовская модель смеси Гаусса с априорным распределением в виде процесса Дирихле, обученная методом вариационного вывода. Низкое значение параметра концентрации априорного распределения побуждает модель выбирать меньшее число активных компонент. Эта модель «решает» сосредоточить свою моделирующую способность на общей структуре набора данных: группах точек с чередующимися направлениями, моделируемых недиагональными ковариационными матрицами. Эти чередующиеся направления приблизительно передают чередующийся характер исходного сигнала синуса.
Третья модель также является байесовской моделью смеси Гаусса с априорным распределением в виде процесса Дирихле, но на этот раз значение параметра концентрации априорного распределения выше, что дает модели больше свободы для моделирования детальной структуры данных. В результате получается смесь с большим числом активных компонент, похожая на первую модель, в которой мы произвольно задали число компонент равным 10.
Выбор лучшей модели зависит от субъективной оценки: хотим ли мы предпочесть модели, которые отражают только общую картину, чтобы обобщить и объяснить большую часть структуры данных, игнорируя детали, или же предпочитаем модели, которые точно следуют областям высокой плотности сигнала?
На двух последних панелях показано, как можно генерировать выборки из двух последних моделей. Распределения полученных выборок не совсем совпадают с исходным распределением данных. Это различие обусловлено главным образом ошибкой аппроксимации, возникающей из-за использования модели, предполагающей, что данные были сгенерированы конечным числом гауссовских компонент, а не непрерывной зашумленной кривой синуса.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause
import itertools
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from scipy import linalg
from sklearn import mixture
color_iter = itertools.cycle(["navy", "c", "cornflowerblue", "gold", "darkorange"])
def plot_results(X, Y, means, covariances, index, title):
splot = plt.subplot(5, 1, 1 + index)
for i, (mean, covar, color) in enumerate(zip(means, covariances, color_iter)):
v, w = linalg.eigh(covar)
v = 2.0 * np.sqrt(2.0) * np.sqrt(v)
u = w[0] / linalg.norm(w[0])
# as the DP will not use every component it has access to
# unless it needs it, we shouldn't plot the redundant
# components.
if not np.any(Y == i):
continue
plt.scatter(X[Y == i, 0], X[Y == i, 1], 0.8, color=color)
# Plot an ellipse to show the Gaussian component
angle = np.arctan(u[1] / u[0])
angle = 180.0 * angle / np.pi # convert to degrees
ell = mpl.patches.Ellipse(mean, v[0], v[1], angle=180.0 + angle, color=color)
ell.set_clip_box(splot.bbox)
ell.set_alpha(0.5)
splot.add_artist(ell)
plt.xlim(-6.0, 4.0 * np.pi - 6.0)
plt.ylim(-5.0, 5.0)
plt.title(title)
plt.xticks(())
plt.yticks(())
def plot_samples(X, Y, n_components, index, title):
plt.subplot(5, 1, 4 + index)
for i, color in zip(range(n_components), color_iter):
# as the DP will not use every component it has access to
# unless it needs it, we shouldn't plot the redundant
# components.
if not np.any(Y == i):
continue
plt.scatter(X[Y == i, 0], X[Y == i, 1], 0.8, color=color)
plt.xlim(-6.0, 4.0 * np.pi - 6.0)
plt.ylim(-5.0, 5.0)
plt.title(title)
plt.xticks(())
plt.yticks(())
# Parameters
n_samples = 100
# Generate random sample following a sine curve
np.random.seed(0)
X = np.zeros((n_samples, 2))
step = 4.0 * np.pi / n_samples
for i in range(X.shape[0]):
x = i * step - 6.0
X[i, 0] = x + np.random.normal(0, 0.1)
X[i, 1] = 3.0 * (np.sin(x) + np.random.normal(0, 0.2))
plt.figure(figsize=(10, 10))
plt.subplots_adjust(
bottom=0.04, top=0.95, hspace=0.2, wspace=0.05, left=0.03, right=0.97
)
# Fit a Gaussian mixture with EM using ten components
gmm = mixture.GaussianMixture(
n_components=10, covariance_type="full", max_iter=100
).fit(X)
plot_results(
X, gmm.predict(X), gmm.means_, gmm.covariances_, 0, "Expectation-maximization"
)
dpgmm = mixture.BayesianGaussianMixture(
n_components=10,
covariance_type="full",
weight_concentration_prior=1e-2,
weight_concentration_prior_type="dirichlet_process",
mean_precision_prior=1e-2,
covariance_prior=1e0 * np.eye(2),
init_params="random",
max_iter=100,
random_state=2,
).fit(X)
plot_results(
X,
dpgmm.predict(X),
dpgmm.means_,
dpgmm.covariances_,
1,
"Bayesian Gaussian mixture models with a Dirichlet process prior "
r"for $\gamma_0=0.01$.",
)
X_s, y_s = dpgmm.sample(n_samples=2000)
plot_samples(
X_s,
y_s,
dpgmm.n_components,
0,
"Gaussian mixture with a Dirichlet process prior "
r"for $\gamma_0=0.01$ sampled with $2000$ samples.",
)
dpgmm = mixture.BayesianGaussianMixture(
n_components=10,
covariance_type="full",
weight_concentration_prior=1e2,
weight_concentration_prior_type="dirichlet_process",
mean_precision_prior=1e-2,
covariance_prior=1e0 * np.eye(2),
init_params="kmeans",
max_iter=100,
random_state=2,
).fit(X)
plot_results(
X,
dpgmm.predict(X),
dpgmm.means_,
dpgmm.covariances_,
2,
"Bayesian Gaussian mixture models with a Dirichlet process prior "
r"for $\gamma_0=100$",
)
X_s, y_s = dpgmm.sample(n_samples=2000)
plot_samples(
X_s,
y_s,
dpgmm.n_components,
1,
"Gaussian mixture with a Dirichlet process prior "
r"for $\gamma_0=100$ sampled with $2000$ samples.",
)
plt.show()
Общее время выполнения скрипта: (0 минут 0.510 секунд)
Связанные примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/mixture/plot_gmm_sin.html