简介
在本实验中,我们将使用高斯混合模型算法来拟合一个遵循带噪声正弦曲线的数据集。我们将使用两种不同类型的高斯混合模型,即期望最大化算法和具有狄利克雷过程先验的贝叶斯高斯混合模型。
虚拟机使用提示
虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。
有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。
如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。
加载所需库
我们将从加载本实验所需的库开始。
import itertools
import numpy as np
from scipy import linalg
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn import mixture
生成数据集
接下来,我们将生成一个遵循带噪声正弦曲线的数据集。
## 参数
n_samples = 100
## 生成遵循正弦曲线的随机样本
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))
使用期望最大化算法拟合高斯混合模型
我们将使用期望最大化算法拟合一个具有 10 个分量的经典高斯混合模型。
## 使用期望最大化算法拟合一个具有 10 个分量的高斯混合模型
gmm = mixture.GaussianMixture(
n_components=10, covariance_type="full", max_iter=100
).fit(X)
绘制期望最大化算法的结果
我们将绘制期望最大化算法的结果。
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])
## 由于狄利克雷过程不会使用它能访问的每个分量,
## 除非有需要,所以我们不应该绘制冗余的分量。
if not np.any(Y == i):
continue
plt.scatter(X[Y == i, 0], X[Y == i, 1], 0.8, color=color)
## 绘制一个椭圆以显示高斯分量
angle = np.arctan(u[1] / u[0])
angle = 180.0 * angle / np.pi ## 转换为度
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(())
plot_results(
X, gmm.predict(X), gmm.means_, gmm.covariances_, 0, "期望最大化"
)
使用狄利克雷过程先验拟合贝叶斯高斯混合模型
现在我们将使用狄利克雷过程先验来拟合一个贝叶斯高斯混合模型。我们将设置一个较低的浓度先验值,以使模型倾向于较少数量的活跃分量。
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,
"具有狄利克雷过程先验的贝叶斯高斯混合模型,"
r"$\gamma_0 = 0.01$.",
)
从具有低浓度先验的贝叶斯高斯混合模型中采样
现在我们将从具有狄利克雷过程先验和低浓度先验值的贝叶斯高斯混合模型中进行采样。
X_s, y_s = dpgmm.sample(n_samples=2000)
plot_samples(
X_s,
y_s,
dpgmm.n_components,
0,
"具有狄利克雷过程先验的高斯混合模型,"
r"$\gamma_0 = 0.01$,采样 2000 个样本。",
)
使用狄利克雷过程先验拟合贝叶斯高斯混合模型
现在我们将使用狄利克雷过程先验来拟合一个贝叶斯高斯混合模型。我们将设置一个较高的浓度先验值,以便让模型有更多自由度来对数据的细粒度结构进行建模。
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,
"具有狄利克雷过程先验的贝叶斯高斯混合模型,"
r"$\gamma_0 = 100$",
)
从具有高浓度先验的贝叶斯高斯混合模型中采样
现在我们将从具有狄利克雷过程先验和高浓度先验值的贝叶斯高斯混合模型中进行采样。
X_s, y_s = dpgmm.sample(n_samples=2000)
plot_samples(
X_s,
y_s,
dpgmm.n_components,
1,
"具有狄利克雷过程先验的高斯混合模型,"
r"$\gamma_0 = 100$,采样 2000 个样本。",
)
总结
在本实验中,我们使用高斯混合模型算法来拟合一个遵循带噪正弦曲线的数据集。我们使用了两种不同类型的高斯混合模型,即期望最大化算法和具有狄利克雷过程先验的贝叶斯高斯混合模型。我们绘制了结果,并从这两个模型中进行采样以比较它们的性能。最佳模型的选择是主观的,这取决于我们是想关注整体情况还是紧密跟踪信号的高密度区域。