PythonでDBSCANを実装!Scikit-learnで密度ベースクラスタリングを学ぶ

Python

データ分析の手法としてよく知られる「クラスタリング」。その中でも特に有名なk-means法では、綺麗な円形のデータでないとうまくグループ分けできない、という課題がありました。

この課題を解決する強力な手法が、DBSCAN (Density-Based Spatial Clustering of Applications with Noise) です。

この記事では、Pythonの定番ライブラリScikit-learnを使い、DBSCANを実際に手を動かしながら実装する方法を学びます。密度ベースクラスタリングの考え方を理解し、分析のスキルを一段階レベルアップさせましょう。

この記事を通じて学べること

  • 密度ベースクラスタリング(DBSCAN)の基本的な考え方
  • Scikit-learnを使ったDBSCANの実装コード
  • DBSCANを使いこなすための重要パラメータの知識

DBSCANとは? – 密度ベースクラスタリングの直感的な理解

DBSCANは、その名の通りデータの密度に着目してクラスタ(グループ)を見つけ出すアルゴリズムです。点が密集しているエリアを一つのクラスタとみなし、どこにも属さない孤立した点を「ノイズ(外れ値)」として扱えるのが大きな特徴です。

DBSCANがデータをグループ分けする仕組み

DBSCANは、すべてのデータ点を以下の3種類に分類しながらクラスタを形成します。

  1. コア点 (Core Point): ある点から決まった距離(半径eps)の中に、自分を含めて指定された数(min_samples)以上の仲間がいる、にぎやかな場所の中心メンバー。
  2. ボーダー点 (Border Point): 自分は中心メンバーではないものの、どこかの中心メンバーの「ご近所さん」である点。クラスタの端に位置します。
  3. ノイズ点 (Noise Point / Outlier): 上記のどちらでもない、ポツンと孤立した点。どのクラスタにも属さない外れ値として扱われます。

DBSCANは、まず「コア点」を見つけ出し、近くにあるコア点やボーダー点を連結させていくことで、最終的に一つの大きなクラスタを形成します。

k-means法との決定的な違い

DBSCANがk-means法と大きく異なる点は以下の通りです。

  • クラスタ数の事前指定が不要: k-meansでは分析者が「クラスタは3つ」のように数を指定する必要がありますが、DBSCANはデータの分布から自動的にクラスタの数を判断します。
  • 任意の形状のクラスタを検出: DBSCANは密度で繋がっていればグループと見なすため、三日月形やドーナツ形といった、k-meansが苦手とする複雑な形状のクラスタも得意です。
  • 外れ値の検出: どのグループにも属さないデータを「ノイズ」として明確に分離できるため、外れ値検出にも応用できます。

Scikit-learnでDBSCANを実装する基本的な流れ

それでは、Scikit-learnを使ってDBSCANを実装してみましょう。DBSCANの強みが分かりやすいように、三日月形のデータセットを使用します。

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

まず、分析に必要なライブラリをインポートします。

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt

# Scikit-learnのバージョンも確認しておくと、挙動の違いを意識できます
import sklearn
print(f"Scikit-learn version: {sklearn.__version__}")

STEP2: サンプルデータの生成 (make_moons)

次に、動作確認用のサンプルデータを作成します。make_moonsは三日月形のデータセットを簡単に生成できる便利な関数です。

# 三日月形のデータセットを200個生成
X, y = make_moons(n_samples=200, noise=0.05, random_state=0)

# データをプロットして形状を確認
plt.scatter(X[:, 0], X[:, 1])
plt.title("Original Data")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()

STEP3: DBSCANモデルの作成と学習

いよいよDBSCANモデルを作成し、データに適用します。DBSCANクラスのインスタンスを作成し、fit_predictメソッドを呼び出すだけでクラスタリングが実行されます。

ここで鍵となるのがepsmin_samplesという2つのパラメータです。今回はeps=0.3, min_samples=5と設定して試してみます。

# DBSCANモデルを作成・学習
# eps: ある点からの距離の閾値(ご近所さんの範囲)
# min_samples: クラスタを形成するために必要な点の最小数
dbscan = DBSCAN(eps=0.3, min_samples=5)

clusters = dbscan.fit_predict(X)

print("Cluster labels assigned to each data point:")
print(clusters)

fit_predictが返すのは、各データ点がどのクラスタに分類されたかを示すラベル配列です。0, 1などがクラスタのID、そして**-1はノイズ(外れ値)**として分類されたことを意味します。

STEP4: クラスタリング結果の可視化

最後に、クラスタリングの結果がどうなったのかを可視化して確認しましょう。

# クラスタリング結果を色分けしてプロット
unique_labels = set(clusters)
colors = [plt.cm.Spectral(each) for each in np.linspace(0, 1, len(unique_labels))]

for k, col in zip(unique_labels, colors):
    if k == -1:
        # ノイズ点は黒色で表示
        col = [0, 0, 0, 1]

    class_member_mask = (clusters == k)
    
    xy = X[class_member_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=8)

plt.title(f'DBSCAN Clustering Results')
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()

このコードを実行すると、2つの三日月がそれぞれ別の色で、綺麗にクラスタリングされていることが視覚的に確認できます。

DBSCANの最重要パラメータ:epsとmin_samples

DBSCANをうまく使うには、epsmin_samplesの調整が欠かせません。この2つのパラメータが結果を大きく左右します。

eps (epsilon)とは? – “ご近所さん”の範囲を決める半径

epsは、ある点を中心としたときに、どこまでの距離を「近所」と見なすかを決める値です。

  • epsが小さいと: ご近所の範囲が狭まり、より密集した部分しかクラスタと認識されず、ノイズと判断される点が増えます。
  • epsが大きいと: ご近所の範囲が広がり、別々のクラスタが一つにまとまってしまうことがあります。

min_samplesとは? – “密集地”と見なす最小人数

min_samplesは、ある点が「密集地の中心(コア点)」と認定されるために、その近所(半径eps以内)に最低限いなければならない点の数(自分自身を含む)です。

  • min_samplesが小さいと: わずかな集まりでもクラスタと認識しやすくなりますが、ノイズも拾いやすくなります。
  • min_samplesが大きいと: よほど密集していないとクラスタと認識されなくなり、より頑健なクラスタを抽出できます。

これらのパラメータは、データのスケールや密度によって最適な値が変わるため、試行錯誤しながら調整することが重要です。

DBSCANのメリットとデメリット

最後に、DBSCANの長所と短所を整理します。

メリット:任意の形状のクラスタ発見&外れ値の検出

  • クラスタ数を事前に決める必要がない。
  • 複雑な形状のクラスタを発見できる。
  • アルゴリズムの過程で自然に外れ値(ノイズ)を特定できる。

デメリット:密度の異なるデータとパラメータ設定の難しさ

  • クラスタごとに密度が大きく異なるデータセットの扱いは苦手。
  • パラメータepsmin_samplesの調整が結果に大きく影響し、その選択が難しい場合がある。
  • 特徴量の多い高次元データでは性能が低下することがある(次元の呪い)。

まとめ

この記事を通じて、Scikit-learnを使ったDBSCANの実装方法と、その背景にある密度ベースクラスタリングの考え方を学びました。

  • DBSCANはデータの「密度」に基づいてクラスタとノイズを自動的に分離する。
  • k-meansと異なり、クラスタ数指定が不要で、複雑な形状も検出できる。
  • Scikit-learnを使えば、DBSCANクラスで手軽に実装できる。
  • eps(距離)とmin_samples(最小数)のパラメータが結果を左右する鍵となる。

DBSCANは、k-means法だけでは対応しきれない、より現実世界の複雑なデータ分布に対応するための強力な選択肢です。ぜひ、あなたの分析ツールボックスに加えてみてください。

コメント

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