混合ガウスモデル(GMM)のベイスモデルからサンプリングする

混合モデル(Mixture Model)は、機械学習モデルの中でも汎用性が高く、データサイエンスや機械学習の実用的なモデルでも非常に多く使われています。

混合モデルの中でも、混合ガウスモデル(Gaussian Mixture Model)は、機械学習の分野でも非常に多く登場するモデルで、特にベイズ学習の教科書等でも、変分推論やMCMC、ギブスサンプリングなどのアルゴリズムの紹介等で、非常に多く登場するようなモデルとなっています。

今回はこの混合ガウスモデルについて、生成モデルとしてモデル化し、構築したモデルからデータをサンプリングしてみます。ベイズ推論では、生成モデルとしてモデルを組み立てる場合が多いので、この記事の内容を理解することで、ベイズ手法に対する理解を深めることができるでしょう。

本記事の内容

  • 混合ガウスモデルに概要について理解する
  • 混合ガウスモデルの生成モデルと定式化
  • 生成モデルから混合ガウスモデルを構築し、データをサンプリングする

また混合モデルの別の一例として、下記の記事で混合ポアソン分布からデータをサンプリングしている記事もあるので、こちらも併せてご覧ください。

[

ポアソン混合モデルの生成モデルからサンプリングする

ベイズモデルにおいては、あるモデルを考えるときに、生成モデル(generativ…](https://disassemble-channel.com/mixture-poisson-distribution-sampling/)

混合ガウスモデルの概要

混合ガウスモデルは、データの分布を複数のガウス分布から生成されたとする混合モデルの1つです。

例えば、上図の左側のようなデータ分布が得られたとき、混合ガウスモデルでは、右のようなk個(上図では3つの正規分布)から生成されている、というように捉えるモデルになります。

この可視化をしたコードはこちらに載せておきます。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import cm
from scipy import stats

np.random.seed(1)
sns.set(style="whitegrid", palette="muted", color_codes=True)
sns.set_style("whitegrid", {'grid.linestyle': '--'})
colors = ['m', 'c', 'g', 'r', 'y']

data1 = np.random.multivariate_normal(np.array([1, 3]), np.array([[0.4, 0.2], [0.1, 0.4]]), size=200)
data2 = np.random.multivariate_normal(np.array([-2, -1]), np.array([[0.7, -0.7], [-0.7, 0.9]]), size=200)
data3 = np.random.multivariate_normal(np.array([3, -2]), np.array([[1.2, 0.9], [0.3, 1.4]]), size=200)

data = np.concatenate([data1, data2, data3])

fig, ax = plt.subplots(1, 3, figsize=(20, 6), dpi=60)

ax[0].scatter(data[:, 0], data[:, 1], s=20, alpha=0.5)
ax[0].set_xlim([-6, 6])
ax[0].set_ylim([-6, 6])

ax[1].scatter(data1[:, 0], data1[:, 1], s=20, c=colors[0], alpha=0.5)
ax[1].scatter(data2[:, 0], data2[:, 1], s=20, c=colors[1], alpha=0.5)
ax[1].scatter(data3[:, 0], data3[:, 1], s=20, c=colors[2], alpha=0.5)
ax[1].set_xlim([-6, 6])
ax[1].set_ylim([-6, 6])

rvc1 = stats.multivariate_normal(np.array([1, 3]), np.array([[0.4, 0.2], [0.1, 0.4]]))
rvc2 = stats.multivariate_normal(np.array([-2, -1]), np.array([[0.7, -0.7], [-0.7, 0.9]]))
rvc3 = stats.multivariate_normal(np.array([3, -2]), np.array([[1.2, 0.9], [0.3, 1.4]]))

x = y = np.arange(-5, 5, 0.1)
X, Y = np.meshgrid(x, y)
pos = np.dstack((X, Y))

Z = rvc1.pdf(pos) + rvc2.pdf(pos) + rvc3.pdf(pos)
ax[2].contourf(x, y, Z)

通常のガウス分布のような単純な確率分布では、左側のようなデータの分布を表現することはできませんが、混合ガウスモデルを利用することで、このような分布を表現することができます。

上図の右側にガウス分布の等高線を引いていますが、これを三次元で見ていきましょう。

fig = plt.figure(figsize = (6, 6), dpi=80)
ax = fig.add_subplot(projection='3d')

ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)
ax.set_xlim([-6, 6])
ax.set_ylim([-6, 6])

この記事のこれから混合ガウスモデルの定式化をしていきますが、混合ガウスモデルの確率密度関数はこのようになっています。

これは2次元の混合ガウスモデルの例なので、可視化できていますが、3次元以上のガウス分布でも同様な感じです。混合ガウス分布を用いることで、複数山があるよう多峰性のある分布を表現することができます。

混合ガウスモデルの定式化と生成モデル

ベイズモデルを構築するときは、データが生成される過程を考える生成モデルからモデルを組み立てることが多いです。この辺りは、混合ポワソン分布のときと同様です。