Scikit-learnで学ぶ凝集型クラスタリング(AgglomerativeClustering)の使い方と実践コード

Python

データ分析において、似たもの同士をグループ分けする「クラスタリング」は非常に重要な手法です。中でも、データの階層的な関係性を捉えることができる**凝集型クラスタリング(AgglomerativeClustering)**は、多くの場面で役立ちます。

この記事では、Pythonの定番ライブラリであるScikit-learnを使い、AgglomerativeClusteringの基本的な仕組みから、具体的な実装方法、そして結果を評価するための可視化手法までを、実践的なサンプルコードを交えながら分かりやすく解説します。

この記事を読み終える頃には、AgglomerativeClusteringの使い方をマスターし、ご自身のデータ分析プロジェクトに応用できるようになるでしょう。

はじめに:凝集型クラスタリング(AgglomerativeClustering)とは?

まずは、この手法がどのようなものなのか、基本的な考え方から見ていきましょう。

ボトムアップで階層構造を作る

AgglomerativeClusteringは、階層的クラスタリングと呼ばれるアプローチの一つです。その名の通り、データを階層的なツリー構造(デンドログラム)として捉えます。

「凝集型」という言葉が示すように、この手法はボトムアップで動作します。

  1. 初期状態: 全てのデータ点を、それぞれが独立した一つのクラスタと見なします。
  2. 繰り返し: 最も似ている(距離が近い)クラスタ同士を見つけ、一つにまとめます。
  3. 終了: 最終的に一つの巨大なクラスタになるか、指定されたクラスタ数に達するまで、ステップ2を繰り返します。

個々のデータという小さな単位から始まり、徐々に大きな塊へとまとめていくイメージです。

K-Meansクラスタリングとの違い

もう一つの有名なクラスタリング手法であるK-Meansと比較すると、その特徴がより明確になります。

  • AgglomerativeClustering:
    • 個々のデータから始めて、似ているものを順にまとめていくボトムアップ方式です。
    • 事前にクラスタ数を決めなくても、クラスタが作られていく過程を可視化できます。
    • 球状でない、複雑な形のクラスタも検出できる可能性があります。
  • K-Means:
    • 最初にクラスタの数(K)を指定し、ランダムな中心点から各データを割り当てるトップダウン方式です。
    • アルゴリズムが高速で、大規模なデータセットにも比較的強いです。
    • クラスタの形状が球状であることを仮定しています。

どちらが良いというわけではなく、データの特性や分析の目的に応じて使い分けることが重要です。

Scikit-learnによるAgglomerativeClusteringの実装手順

それでは、実際に手を動かしてAgglomerativeClusteringを実装してみましょう。ここでは、ステップバイステップでコードを解説します。

必要なライブラリのインポート

まず、データ処理や可視化、クラスタリングに必要なライブラリをインポートします。これらがインストールされていない場合は、pip install scikit-learn numpy matplotlibでインストールしてください。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import AgglomerativeClustering

サンプルデータの生成と可視化

今回は、クラスタリングの練習用にScikit-learnが提供するmake_blobs関数で擬似的なデータを生成します。

# サンプルデータを150個、4つの中心で生成
X, _ = make_blobs(n_samples=150, centers=4, cluster_std=0.9, random_state=42)

# どのようなデータが生成されたかを確認
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], s=50, color='gray')
plt.title("Generated Sample Data")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.grid(True)
plt.show()

モデルの構築とクラスタリングの実行

AgglomerativeClusteringクラスを使ってモデルを構築し、生成したデータに適用します。n_clustersパラメータで、最終的にいくつのクラスタに分けたいかを指定します。

# AgglomerativeClusteringのインスタンスを作成
# n_clusters=4 で、4つのクラスタに分けるよう指定
agg_cluster = AgglomerativeClustering(n_clusters=4)

# fit_predictメソッドで学習とクラスタラベルの予測を同時に実行
labels = agg_cluster.fit_predict(X)

# 各データ点がどのクラスタに属するかが出力される
print(labels)
# 出力例: [1 1 2 0 1 ... ]

結果を色分けしてプロットする

fit_predictで得られたlabelsを元に、どのデータがどのクラスタに分類されたのかを色分けして可視化します。

# クラスタリング結果を可視化
plt.figure(figsize=(8, 6))
# c=labels とすることで、クラスタごとに色を自動で変えてくれる
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')

plt.title("Agglomerative Clustering Result")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.grid(True)
plt.show()

このコードを実行すれば、元々は灰色の点の集まりだったデータが、4つのグループに見事に色分けされた散布図が表示されます。

覚えておきたい主要パラメータ

AgglomerativeClusteringの結果は、いくつかのパラメータによって大きく変化します。特に重要な3つを覚えておきましょう。

n_clusters: いくつのクラスタに分けるか

最終的にデータをいくつのクラスタに分割するかを指定します。分析の目的に応じて設定しますが、最適な数が不明な場合は、後述するデンドログラムが判断の助けになります。

linkage: クラスタ間の距離をどう測るか(最重要)

どのクラスタ同士を結合するかを決めるための、「クラスタ間の距離」の計算方法を指定します。これは結果に最も大きな影響を与えるパラメータの一つです。

  • 'ward': デフォルト値。全てのクラスタ内の分散(ばらつき)の合計が最も小さくなるように結合します。多くの場合でバランスの良い結果が得られます。(affinity'euclidean'の場合のみ使用可能)
  • 'complete': 2つのクラスタ間で、最も遠い点同士の距離をクラスタ間の距離とします。
  • 'average': 2つのクラスタに属する全ての点のペアの距離の平均値をクラスタ間の距離とします。

affinity: データ点間の距離計算方法

個々のデータ点同士の距離をどのように計算するかを指定します。デフォルトは'euclidean'(ユークリッド距離)で、ほとんどの場合はこれで十分です。

デンドログラムでクラスタの併合過程を可視化する

AgglomerativeClusteringの強力な特徴は、クラスタが結合していく過程をデンドログラムとして可視化できる点です。

なぜデンドログラムが便利なのか?

デンドログラムを見ると、どのクラスタがどの段階(距離)で結合したかが一目瞭然になります。これにより、データの階層構造を直感的に理解できるだけでなく、「どこで分割すれば自然なクラスタリングになるか」という、最適なクラスタ数を決定するための重要な手がかりを得ることができます。

SciPyと連携した描画コード

Scikit-learnには直接デンドログラムを描画する機能はありませんが、科学技術計算ライブラリのSciPyと組み合わせることで簡単に作成できます。

from scipy.cluster.hierarchy import dendrogram, linkage

# linkage関数にデータとlinkage手法を渡す
linked = linkage(X, method='ward')

# デンドログラムの描画
plt.figure(figsize=(12, 8))
dendrogram(linked,
           orientation='top',
           distance_sort='descending',
           show_leaf_counts=True)

plt.title("Dendrogram")
plt.xlabel("Data Points Index")
plt.ylabel("Distance")
plt.grid(axis='y')
plt.show()

この樹形図の縦軸はクラスタ間の距離を表します。他の結合箇所と比べて、縦に長く伸びている(=距離が一気に離れている)箇所を見つけ、その下で水平に線を引くことで、適切なクラスタ数を視覚的に判断することができます。

まとめ

本記事では、Scikit-learnを用いた凝集型クラスタリング(AgglomerativeClustering)の使い方を、実践的なコードを交えて解説しました。

  • AgglomerativeClusteringは、似たデータから順にまとめていくボトムアップな手法。
  • Scikit-learnを使えば、AgglomerativeClusteringクラスで簡単に実装可能。
  • linkageパラメータはクラスタの形状を決定する重要な要素。
  • SciPyと連携してデンドログラムを描画することで、データの階層構造を深く理解できる。

K-Meansと並んで非常に使いやすく強力なクラスタリング手法です。ぜひこの機会に使い方をマスターし、データ分析の引き出しを一つ増やしてみてください。

コメント

タイトルとURLをコピーしました