はじめに
この実験では、情報理論基準を使用してガウス混合モデル (GMM) を用いたモデル選択方法を学びます。モデル選択には、共分散の種類とモデル内のコンポーネント数の両方が関係します。最適なモデルを選択するために、赤池情報量基準 (AIC) とベイズ情報量基準 (BIC) を使用します。標準正規分布をランダムサンプリングすることで 2 つのコンポーネントを生成します。一方のコンポーネントは球形を保ちながらシフトさせ、再スケーリングします。もう一方は、より一般的な共分散行列を持つように変形させます。
VM のヒント
VM の起動が完了したら、左上隅をクリックして ノートブック タブに切り替え、Jupyter Notebook を使って練習しましょう。
Jupyter Notebook の読み込みには数秒かかる場合があります。Jupyter Notebook の制限により、操作の検証は自動化できません。
学習中に問題がある場合は、Labby にお問い合わせください。セッション終了後にフィードバックを提供してください。すぐに問題を解決いたします。
データ生成
numpy.random.randn によって返される標準正規分布をランダムサンプリングすることで、2 つのコンポーネント(それぞれ n_samples 個含む)を生成します。一方のコンポーネントは球形を保ちながらシフトさせ、再スケーリングします。もう一方は、より一般的な共分散行列を持つように変形させます。
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])
可視化
Matplotlib を使って、異なるコンポーネントを可視化することができます。
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 スコアを返します。最適なパラメータセットと推定器は、それぞれ 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 スコアの符号を逆に戻して、それを最小化する効果を示します。seaborn を使って BIC スコアをプロットします。
import pandas as pd
import seaborn as sns
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()
sns.catplot(
data=df,
kind="bar",
x="Number of components",
y="BIC score",
hue="Type of covariance",
)
plt.show()
最適なモデルをプロットする
選択されたモデルの各ガウス成分を示すために楕円をプロットします。そのためには、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()
まとめ
この実験では、情報理論基準を使ってガウス混合モデル (GMM) を用いたモデル選択を行う方法を学びました。最適なモデルを選択するために、赤池情報量基準 (AIC) とベイズ情報量基準 (BIC) を使用しました。標準正規分布をランダムサンプリングすることで 2 つのコンポーネントを生成しました。一方のコンポーネントは球形を保ちながらシフトさせ、再スケーリングしました。もう一方はより一般的な共分散行列を持つように変形させました。異なるコンポーネントを可視化し、最適なモデルを学習して選択し、BIC スコアをプロットし、最適なモデルをプロットしました。