2018年05月11日

Bayesian Gaussian mixture model(BGMM)を使ってクラスタリング数を求める

エモトです.みなさま某IWはご覧になりましたでしょうか.私は原作を知らなかったのでこんな展開になるのかよ!と驚きました.しかし幸いなことに,直前に某アニメの王位争奪戦を見直していたので,心のダメージは最小に抑えられました.アタルありがとう.フェイスフラッシュで無事解決したように,来年公開の4を待ちましょう.

前回,混合ガウスモデル(Gaussian mixture model, GMM)を使用して,クラスタリングを行いました.クラスタリングで問題になるのは,やはり最適なクラスタリング数は何かです.

前回はBIC(ベイズ情報量規準)から最適なクラスタリング数を求めました.ここで,潜在的ディリクレ配分法(Latent Dirichlet Allocation, LDA)に階層ディリクレ過程(Hierechical Dirichlet Process, HDP)があるように,GMMにもクラスタリング数を自動推定する Bayesian Gaussian mixture model(BGMM)があります.今回は,そのBGMMを簡単に説明します.

なお,同様な手法として Dirichlet Process Gaussian Mixture Model (DPGMM) があるのですが,今回使用するライブラリ scikit-learn では deprecated になっていました(これらの経緯は勉強不足です,すみません).

今回は簡単な例を示した後に,複雑なデータを与えたときの結果を紹介します.なお,前半のコード例は こちら で公開しています.

BayesianGaussianMixtureの使い方

まず,検証用のデータを生成します.今回は2クラスに分類されそうなデータを作成しました.
from numpy.random import rand
vec_list = []
for base in [[10, 10], [0, 0]]:
  for _ in range(100):
    temp = [base[0] + rand(), base[1] + rand()]
    vec_list.append(temp)
1F1BC2E6D3FAEFA026E5FE9BEF6FC562.png


BGMMの学習を行います.前述通り,scikit-learn を使用しています.ここでは,BGMMの推定クラスターの最大候補数 n_components を10に,学習回数 max_iter を1000にしています.この例では学習回数はデフォルトの100のままでも大丈夫ですが,実際に複雑なデータでは100より大きい数値に設定しておくと良いと思います.
import numpy as np
nvec = np.array(vec_list)

from sklearn.mixture import BayesianGaussianMixture
gmm = BayesianGaussianMixture(n_components=10, verbose=1, max_iter=1000)
gmm.fit(nvec)
分類結果を見ると,今回はクラスター番号2と5のクラスターに分かれました.クラスターごとに色付けた散布図をみると,綺麗に2クラスに分かれたことがわかります.
clusters = gmm.predict(nvec)
print("clusters:", clusters)

'''
clusters: [5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
'''
5A5F4268F47E0D856FBF4F181D9BEBF0.png


また,分類結果のクラスター番号を集合(set)に変換すると,クラスター数がわかりやすくなると思います.
clusters_set = set(clusters)
print("clusters_set:", clusters_set)
print("len(clusters_set):", len(clusters_set))
'''
clusters_set: {2, 5}
len(clusters_set): 2
'''
次に,BGMMで学習した各クラスター番号の重みを確認します.クラスタリング番号2と5に重みが集中して,他がほとんど0になっています.この重みからも2クラスターになったのが判断できます.
weights = gmm.weights_
components = gmm.n_components
x_clusters = np.arange(components)
plt.bar(x_clusters, weights, tick_label=x_clusters)
plt.show
1197D336BADA29F45CCB19C8EF080875.png


より複雑なデータはどうなるか?

上記の例ではきれいに分かれましたが.実際のデータ(より複雑なデータ)ではそう簡単にはいきません.下図は,あるデータに対してBGMMを行ったときの各カテゴリーごとの重みの計算結果です.
94C04508A40C2F2A81EA26BF037F7DAE.png


グラフを比べてわかるように,後者の図からクラスター数をポンっと決めるのは難しいです.しかしながら,いくつか0に近い重みのクラスターがあるので,それら考慮して取捨選択していけば,ある程度の目星はつきそうです.クラスター数の候補を絞って,GMMを行い,結果を比較すれば,最適なクラスター数を絞り込めそうです.


posted by Seesaa京都スタッフ at 12:00| Comment(0) | 機械学習 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は180日以上新しい記事の投稿がないブログに表示されております。