はじめに
データ分析の世界で広く使われるクラスタリング。その代表的な手法として「K-means」が非常に有名です。しかし、K-meansは「あるデータは、必ずどこか1つのクラスタに100%所属する」という、いわば”白黒はっきりさせる”アプローチ(ハードクラスタリング)を取ります。
現実の世界は、もっと曖昧ではないでしょうか?
例えば、顧客をセグメンテーションする際に、「ヘビーユーザー」と「ライトユーザー」の中間に位置するような、どちらの性質も併せ持つ顧客層が存在します。このようなデータを無理やりどちらか一方に分類してしまうと、重要な情報を見失いかねません。
そこで登場するのが、今回ご紹介するGaussian Mixture Model (GMM) と、それを用いた「確率的クラスタリング(ソフトクラスタリング)」です。GMMは、「このデータはクラスタAに80%、クラスタBに20%の確率で所属する」というように、物事の曖昧さを許容した、より現実に即した分析を可能にします。
この記事は、PythonのScikit-learnライブラリを使い、Gaussian Mixture Modelの理論から実践的な使い方、そしてその真価である「所属確率」の活用法までを網羅した、まさに「実践ガイド」です。
この記事を読み終える頃には、あなたは以下のスキルを身につけているでしょう。
- GMMと確率的クラスタリングの基本概念を説明できる
Scikit-learnを使ってGMMを実装し、データをクラスタリングできる- GMMの強みである「所属確率」を解釈し、分析に活かす方法がわかる
- BICという客観的な指標を用いて、最適なクラスタ数を科学的に決定できる
それでは、K-meansの一歩先を行く、柔軟で強力なクラスタリングの世界へ進んでいきましょう。
1. 確率的クラスタリングとGaussian Mixture Model (GMM) の基本
まずは、GMMの背景にある「確率的クラスタリング」という考え方と、その仕組みを理解することから始めましょう。
1-1. 「所属確率」で考えるソフトクラスタリングのメリット
ソフトクラスタリングとは、各データが複数のクラスタにまたがって所属することを「確率」で表現する手法です。これにより、ハードクラスタリングにはない、以下のような大きなメリットが生まれます。
- 曖昧さの表現: クラスタの境界線付近にあるデータに対し、「どちらのクラスタにも属しうる」という曖昧な状態を数値(確率)で表現できます。これは、より現実のデータ構造に即した見方です。
- 豊富な情報量: 単なる分類ラベルだけでなく、0から1までの確率値が得られるため、分析から得られる情報が格段に増えます。例えば、所属確率が低いデータは「どのクラスタにもあまり似ていない外れ値」である可能性を示唆します。
- 柔軟な意思決定: 例えば顧客セグメンテーションで、ある顧客が「高収益セグメントに60%」「離反予備軍セグメントに40%」と分析された場合、単純に高収益顧客として扱うだけでなく、離反防止の施策も検討するという、より nuanced(ニュアンスのある)な意思決定に繋がります。
このように、所属確率を考慮することで、より深く、より柔軟なデータ分析が可能になるのです。
1-2. GMMの仕組み:データは複数の正規分布(ガウス分布)から生まれる
では、GMMはどのようにしてこの「所属確率」を計算するのでしょうか。その核心的なアイデアは、「観測されているデータセット全体は、目には見えない複数の正規分布(ガウス分布)が混ざり合って生成されたものである」と仮定することにあります。
正規分布は、平均(分布の中心)と分散(分布の広がり)で特徴づけられる、釣鐘型の確率分布です。GMMでは、各クラスタがそれぞれ異なる平均と分散を持つ一つの正規分布に対応すると考えます。
GMMの学習プロセス(内部ではEMアルゴリズムという手法が使われます)は、以下の作業を自動的に行います。
- データセットに最もフィットするように、複数の正規分布の形(平均、分散)や位置、そしてそれぞれの分布がデータ全体に占める割合(混合係数)を推定する。
- 推定された複数の正規分布を元に、個々のデータ点が「どの分布から生成された可能性が最も高いか」を確率として計算する。
これにより、データは円形だけでなく、各正規分布の形状に応じた楕円形や大きさの異なるクラスタとして捉えることができるのです。
1-3. ハードクラスタリング(K-means)とのアプローチの違い
GMMとK-meansの違いをまとめると、以下のようになります。この違いを理解することが、適切な手法選択の鍵となります。
| 特徴 | Gaussian Mixture Model (GMM) | K-means |
| 所属の考え方 | ソフトクラスタリング(確率で所属) | ハードクラスタリング(1つのクラスタに所属) |
| クラスタの形状 | 楕円形(分散共分散を考慮) | 円形(超球)(中心からの距離のみ考慮) |
| 得意なデータ | 複雑な形状、大きさの異なるクラスタ | 各クラスタが同じような大きさで円形のデータ |
| 計算コスト | 比較的高め | 比較的低め |
| 得られる情報 | 所属ラベル、所属確率 | 所属ラベルのみ |
K-meansは、GMMにおいて各クラスタの分散が全方向で等しい(つまり、形状が真円である)と仮定した、よりシンプルな特別ケースと考えることもできます。
2. Scikit-learnによるGaussianMixtureの実践ステップ
理論を学んだところで、いよいよScikit-learnを使ってGMMを実装してみましょう。コードを動かしながら、その挙動を体感するのが理解への一番の近道です。
2-1. 必要なライブラリの準備
まず、分析に必要なPythonライブラリをインポートします。scikit-learn、numpy、matplotlibがインストールされていない場合は、pipコマンドでインストールしておきましょう。
pip install scikit-learn numpy matplotlib# ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from sklearn.datasets import make_blobs
# グラフのスタイル設定 (任意)
plt.style.use('seaborn-v0_8-whitegrid')
print(f"Scikit-learn version: {sklearn.__version__}") # バージョン確認この記事のコードは、scikit-learnのバージョン1.0以降で動作確認しています。
2-2. 実践用のサンプルデータを作成する
GMMの性能を確かめるために、K-meansが苦手とするような、少し意地悪なデータセットをmake_blobs関数を使って人工的に生成します。具体的には、楕円形に引き伸ばされた(非等方性の)データを作成します。
# サンプルデータの生成
n_samples = 600
random_state = 42
# まずは通常の塊データを生成
X, y = make_blobs(n_samples=n_samples, centers=3, cluster_std=0.8, random_state=random_state)
# データを意図的に引き伸ばして、楕円形のクラスタを作成
transformation = [[0.6, -0.6], [-0.4, 0.8]]
X_aniso = np.dot(X, transformation)
# 生成したデータをプロットして確認
plt.figure(figsize=(8, 8))
plt.scatter(X_aniso[:, 0], X_aniso[:, 1], s=15, c='gray')
plt.title('Generated Anisotropic Blobs Data')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()生成されたデータを見ると、3つの塊がありますが、それぞれが真円ではなく、斜めに伸びた楕円形をしていることがわかります。
2-3. GMMモデルの学習とクラスタ割り当て (fitとpredict)
Scikit-learnのAPIは統一されており、GMMの使い方もKMeansと非常によく似ています。GaussianMixtureクラスのインスタンスを作成し、fitメソッドで学習、predictメソッドで予測を行います。
n_componentsは、混合させるガウス分布の数、つまりクラスタ数を指定する最も重要なパラメータです。
# GaussianMixtureモデルのインスタンス化
# n_componentsにクラスタ数を指定
gmm = GaussianMixture(n_components=3, random_state=random_state)
# モデルの学習
gmm.fit(X_aniso)
# 各データ点がどのクラスタに属するかを予測
labels = gmm.predict(X_aniso)
# 最初の10個のデータの予測結果を表示
print(labels[:10])
# 出力例: [1 2 2 0 1 0 0 1 0 2]たったこれだけで、モデルの学習と各データのクラスタリングが完了しました。
2-4. クラスタリング結果を可視化して確認する
予測したlabelsを使って、結果を色分けしてプロットし、正しくクラスタリングできているかを確認しましょう。
# クラスタリング結果の可視化
plt.figure(figsize=(8, 8))
scatter = plt.scatter(X_aniso[:, 0], X_aniso[:, 1], c=labels, s=15, cmap='viridis')
plt.title('GaussianMixture Clustering Result')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend(handles=scatter.legend_elements()[0], labels=['Cluster 0', 'Cluster 1', 'Cluster 2'])
plt.show()結果を見ると、楕円形のクラスタが見事にその形状に沿って分割されていることがわかります。これは、各クラスタを中心からの距離だけで判断するK-meansでは困難なタスクです。GMMがデータの分散構造を正しく捉えられた証拠です。
3. GMMの真価:所属確率を読み解き、活用する
基本的な使い方がわかったところで、いよいよGMMの真骨頂である「所属確率」に迫ります。この確率をどう計算し、どう解釈し、どうビジネスに活かすのかを見ていきましょう。
3-1. predict_probaメソッドで所属確率を計算する方法
所属確率の計算は非常に簡単です。学習済みのGMMモデルに対し、predict_probaメソッドを呼び出すだけです。
# 各データが各クラスタに所属する確率を計算
probs = gmm.predict_proba(X_aniso)
# 最初の5データ点の所属確率を表示
# .round(3)で小数点以下3桁に丸めている
print("Shape of probs:", probs.shape)
print("Probabilities for the first 5 data points:")
print(probs[:5].round(3))出力結果は以下のようになります。
Shape of probs: (600, 3)
Probabilities for the first 5 data points:
[[0. 1. 0. ]
[0. 0. 1. ]
[0. 0. 1. ]
[1. 0. 0. ]
[0. 1. 0. ]]出力は (データ点数, クラスタ数) の形状を持つNumPy配列です。各行がデータ点、各列がクラスタに対応し、その値が「そのデータがそのクラスタに所属する確率」を示しています。例えば、1行目は「クラスタ0に0%、クラスタ1に100%、クラスタ2に0%」の確率で所属することを示しており、これはクラスタ1のど真ん中あたりにあるデータ点だと推測できます。
3-2. 所属確率の具体的な解釈とビジネスへの応用
この確率情報は、ビジネスの現場で非常に価値のある洞察をもたらします。
- 顧客セグメンテーションでの応用: ECサイトの顧客を購買データからクラスタリングしたとします。「優良顧客」クラスタへの所属確率が95%の顧客は、安心してVIP向けの施策対象とできます。一方、所属確率が60%の顧客は、「優良顧客になりつつあるが、まだ他の特徴も持つ」と解釈でき、より育成を目的としたアプローチが有効かもしれません。
- 異常検知への応用: 全てのクラスタに対する所属確率が軒並み低いデータ点(例:
[0.01, 0.02, 0.005])は、どのクラスタの特徴にも当てはまらない、学習データには無かったパターンの可能性があります。これは、工場の製品検査における「不良品」や、クレジットカードの不正利用検知における「不正取引」など、「異常検知」の強力なシグナルとなります。
3-3. 確率を使ってクラスタリングの曖昧さ・信頼度を評価する
所属確率は、個々のデータだけでなく、クラスタリング全体の「質」を評価するのにも役立ちます。各データについて、最も高い所属確率(そのデータが分類されたクラスタへの確信度)を抽出し、その分布を見てみましょう。
# 各データの最大所属確率(確信度)を取得
confidence_scores = np.max(probs, axis=1)
# 確信度の分布をヒストグラムで可視化
plt.figure(figsize=(10, 6))
plt.hist(confidence_scores, bins=50, density=True, alpha=0.7, color='steelblue')
plt.title('Distribution of Confidence Scores')
plt.xlabel('Highest Probability (Confidence)')
plt.ylabel('Density')
plt.show()もし、このヒストグラムが1.0に近い右側に大きく偏っていれば、ほとんどのデータが明確にいずれかのクラスタに分類できていることを意味し、クラスタリングの信頼度が高いと言えます。逆に、0.5〜0.8あたりに多くのデータが分布している場合、クラスタの境界が曖昧で、多くのデータが複数のクラスタの中間的な性質を持つことを示唆しています。
4. 最適なクラスタ数を科学的に見つける方法
これまでの分析では、最初からクラスタ数を「3」と決めていました。しかし、実世界のデータでは、最適なクラスタ数は未知です。ここでは、その数を科学的に決定するためのアプローチを紹介します。
4-1. なぜクラスタ数の決定が重要なのか
クラスタ数(n_components)の決定は、クラスタリング分析の成否を分ける重要なプロセスです。
- 少なすぎる場合: 本来は異なる性質を持つグループを一つにまとめてしまい、データの構造を見落とす「過小評価」に繋がります。
- 多すぎる場合: 細かすぎるノイズまでを別のクラスタとして捉えてしまい、解釈が困難で汎用性のないモデルができる「過学習」に繋がります。
勘や経験で決めるのではなく、客観的な指標に基づいて判断することが求められます。
4-2. ベイズ情報量規準(BIC)を用いたモデル選択
GMMの最適なクラスタ数を決定するためによく用いられるのが**ベイズ情報量規準(BIC: Bayesian Information Criterion)**です。
BICは、以下の2つのバランスを取るための指標です。
- モデルの当てはまりの良さ(対数尤度): モデルがデータをどれだけうまく説明できているか。値が大きいほど良い。
- モデルの複雑さ(パラメータ数)に対するペナルティ: クラスタ数を増やすほどモデルは複雑になり、過学習しやすくなる。その複雑さに対して罰を与える。
BICスコアが最も低くなるモデルが、最も良いモデルであると判断します。つまり、私たちは様々なクラスタ数でGMMを試し、BICが最小値を取るクラスタ数を探せばよいのです。(類似の指標にAICがありますが、BICの方がよりシンプルなモデルを選択する傾向があります。)
4-3. 実践コード:BICスコアをプロットして最適値を探る
Scikit-learnのGaussianMixtureは、学習後に.bic()メソッドを呼び出すだけで簡単にBICスコアを計算できます。クラスタ数を変化させながらBICを計算し、グラフにプロットしてみましょう。
# クラスタ数を1から10まで変化させて、それぞれのBICスコアを計算
n_components_range = range(1, 11)
bic_scores = []
for n_components in n_components_range:
gmm = GaussianMixture(n_components=n_components, random_state=random_state)
gmm.fit(X_aniso)
bic_scores.append(gmm.bic(X_aniso))
# BICスコアをプロット
plt.figure(figsize=(10, 6))
plt.plot(n_components_range, bic_scores, marker='o')
plt.title('BIC Score per Number of Components')
plt.xlabel('Number of components (k)')
plt.ylabel('Bayesian Information Criterion (BIC)')
plt.xticks(n_components_range)
plt.grid(True)
plt.show()このグラフを見ると、Number of componentsが3のときにBICスコアがガクッと下がり、最小値を取っていることが一目瞭然です。この結果から、私たちのサンプルデータにとって最適なクラスタ数は「3」であると、客観的かつ自信を持って結論づけることができます。
5. まとめ:GaussianMixtureで一歩進んだクラスタリングへ
本記事では、Gaussian Mixture Model(GMM)を用いた確率的クラスタリングについて、その理論的背景からScikit-learnによる実践的な実装、そして応用的な活用法までを詳細に解説しました。
最後に、重要なポイントを振り返りましょう。
- GMMは確率的クラスタリング: データを「100%どれかに所属」させるのではなく、「各クラスタへの所属確率」で表現することで、曖昧で複雑なデータ構造を柔軟に捉えます。
- K-meansを超える柔軟性: 楕円形や大きさの異なるクラスタも認識できるため、K-meansではうまくいかない多くのケースで有効です。
predict_probaが鍵: GMMの真価は所属確率にあります。この情報を活用することで、より深い洞察や、異常検知などの高度な分析が可能になります。- 最適なクラスタ数はBICで判断: 客観的な指標であるBICスコアを比較することで、勘に頼らず科学的に最適なクラスタ数を決定できます。
GMMは、単なるデータ分類ツールではありません。データの背後にある生成過程を確率分布で推定し、その不確実性までをも情報として提供してくれる、非常に強力な分析モデルです。
ぜひ、あなたの手元にあるデータでGaussianMixtureを試し、K-meansだけでは見えてこなかった、新しいデータの側面を発見してみてください。


コメント